From c62f1818c7494040754e80d17c9adcbad8e325e5 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 24 Oct 2025 12:51:47 +0200 Subject: [PATCH 01/21] =?UTF-8?q?-=20in=20BLADETOWASTE=20e=20DiceCut=20eli?= =?UTF-8?q?minati=20tutti=20i=20riferimenti=20al=20DownUp:=20il=20tipo=20d?= =?UTF-8?q?i=20lavorazione=20si=20verificher=C3=A0=20direttamente=20in=20F?= =?UTF-8?q?aceByBlade=20o=20FindBlade=20-=20in=20FaceData.GetFacesInfo=20s?= =?UTF-8?q?i=20salva=20l'id=20della=20trimesh=20nella=20faccia=20-=20in=20?= =?UTF-8?q?HEADCUT=20il=20box=20per=20i=20cubetti=20viene=20copiato=20non?= =?UTF-8?q?=20per=20riferimento?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/DiceCut.lua | 18 +- LuaLibs/FaceData.lua | 5 +- Strategies/Standard/HEADCUT/HEADCUT.lua | 3 +- StrategyLibs/BLADETOWASTE.lua | 216 +++++++++--------------- StrategyLibs/FACEBYBLADE.lua | 12 ++ 5 files changed, 106 insertions(+), 148 deletions(-) diff --git a/LuaLibs/DiceCut.lua b/LuaLibs/DiceCut.lua index 137fe07..0211b3e 100644 --- a/LuaLibs/DiceCut.lua +++ b/LuaLibs/DiceCut.lua @@ -134,7 +134,7 @@ end -- vtO: il versore dei piani ortogonali -- dOffsetEff: offset della distanza dal punto centrale -- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset -local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownUp) +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT)) EgtSetGridFrame(FrameLocal) local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal) @@ -156,7 +156,7 @@ local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dMinNzDownU -- TODO si può eliminare questo test dato che vengono verificate già volume e dimensione del cubetto?? local dMaxLen = BeamData.MAX_LEN_DICE or 600 if dLen < dMaxLen and dWidth < dMaxLen and - ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dMinNzDownUp then + ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) then return nil, nil, nil end @@ -261,7 +261,7 @@ end -- dOffsetParallel: offset della distanza dal punto centrale -- b3BoxDicing: il grezzo della barra -- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua -local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMinNzDownUp) +local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing) if not CutTable[1] or not CutTable[2] then return end @@ -294,7 +294,7 @@ local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing, dMin -- lunghezza totale faccia local dLongSize = x1 + x2 -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti - if dLongSize <= dOffsetParallel + 1.0 and vtN1:getZ() > dMinNzDownUp then + if dLongSize <= dOffsetParallel + 1.0 then local nAddGrpId = EgtGetParent( Cut1Id) local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id}) --EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) @@ -430,8 +430,6 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) local nStepOrthogonal = OptionalParameters.nStepOrthogonal or 100 -- distanza tra piani paralleli e piani di taglio (era sempre 0, serve???) local dTolerance = OptionalParameters.dTolerance or 0 - -- inclinazione limite per taglio da sotto - local dMinNzDownUp = OptionalParameters.dMinNzDownUp or -2 --Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo local TBoxPoint = CalcolaPuntiEstremiBox( b3BoxDicing) @@ -508,10 +506,10 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) end -- calcolo la direzione dei piani ortogonali local vtO = VectorFromUprightOrtho( vtNInner) - if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dMinNzDownUp or abs( vtNInner:getY()) > 0.8 then + if vtNInner:getZ() > -0.0175 or abs( vtNInner:getY()) > 0.8 then vtO:rotate( vtNInner, 90) -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente - if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) and vtNInner:getZ() > dMinNzDownUp then + if ( abs( vtO:getY()) > 4 * abs( vtO:getX()) or b3BoxDicing:getDimZ() > 620) then vtO:rotate( vtNInner, 90) -- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra if vtNInner:getZ() < -0.05 then @@ -533,7 +531,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero - local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal, dMinNzDownUp) + local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, dOffsetOrthogonal) if OffsetRel and CopyPlane and dCenOffs then ptCInner = ptCInner + dCenOffs * vtO @@ -582,7 +580,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato if not bGetOrtoPlanes then - VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing, dMinNzDownUp) + VerifyFirstOrthoCut( UltimateTable, dOffsetParallelOriginal, b3BoxDicing) -- se rimangono due sole facce, devono coincidere con le originali e quindi sono superflue if #UltimateTable == 2 and #UltimateTable[1] == 1 and #UltimateTable[2] == 1 then EgtErase( UltimateTable[1][1]) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 3476b4e..679b7e1 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -175,6 +175,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) for i = 1, Proc.nFct do Faces[i] = {} Faces[i].id = i - 1 + Faces[i].idTrimesh = Proc.id Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT) if Proc.nFct < 6 or FaceIsToGet( i) then -- frame OCS faccia @@ -215,6 +216,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) end ------------------------------------------------------------------------------------------------------------- +-- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart; passare Face invece dell'id? function FaceData.IsFaceRectangular( Proc, idFace) local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId) @@ -233,11 +235,12 @@ function FaceData.IsFaceRectangular( Proc, idFace) end ------------------------------------------------------------------------------------------------------------- +-- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart; passare Face invece dell'id? function FaceData.IsFaceRhomboid( Proc, idFace) local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId) if nContourCnt > 1 then - error( 'IsFaceRectangular : too many loops') + error( 'IsFaceRhomboid : too many loops') end local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId) diff --git a/Strategies/Standard/HEADCUT/HEADCUT.lua b/Strategies/Standard/HEADCUT/HEADCUT.lua index ef3f568..216cdb9 100644 --- a/Strategies/Standard/HEADCUT/HEADCUT.lua +++ b/Strategies/Standard/HEADCUT/HEADCUT.lua @@ -86,8 +86,7 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) if not bExecutePrecutOnly then local OptionalParameters = {} -- si parte dal box della feature e si aggiunge il punto estremo del grezzo - -- ATTENZIONE : Proc.b3Box viene modificata dato che il tipo Box è come se fosse una tabella, ma da qui passa solo 1 volta per pezzo quindi non dovrebbero esserci problemi - local b3BoxDicing = Proc.b3Box + local b3BoxDicing = BBox3d( Proc.b3Box) b3BoxDicing:Add( Part.b3Raw:getMax()) b3BoxDicing:expand( 1000 * GEO.EPS_SMALL) OptionalParameters.b3BoxDicing = b3BoxDicing diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 7818ef4..ae36c09 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -204,7 +204,7 @@ local function CompareEdgesNoPreference( EdgeA, EdgeB) end -local function GetEdgeToMachine( Edges, vtNFace, sBladeType, bAllowFastCuts) +local function GetEdgeToMachine( Edges, sBladeType, bAllowFastCuts) local EdgeToMachine = {} local EdgesSorted = {} @@ -222,14 +222,6 @@ local function GetEdgeToMachine( Edges, vtNFace, sBladeType, bAllowFastCuts) elseif sBladeType == 'Bottom' then table.sort( EdgesSorted, CompareEdgesBottomHead) EdgeToMachine = EdgesSorted[1] - elseif sBladeType == 'TopDownUp' then - local vtEdgeDirection - if vtNFace:getY() > -0.02 then - vtEdgeDirection = -Y_AX() - else - vtEdgeDirection = Y_AX() - end - EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtEdgeDirection) elseif sBladeType == 'TopGuillotine' then table.sort( EdgesSorted, CompareEdgesTopHeadGuillotine) EdgeToMachine = EdgesSorted[1] @@ -262,9 +254,10 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) local dMinNzTopBladeIfEqual = OptionalParameters.dMinNzTopBlade or sin(-5) local dMaxNyTopBlade = OptionalParameters.dMaxNyTopBlade or sin(1) local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART - local dElevationTop = OptionalParameters.dElevationTop - local dElevationBottom = OptionalParameters.dElevationBottom - local dElevationTopDownUp = OptionalParameters.dElevationTopDownUp or 0 + local EdgeToMachineTop = OptionalParameters.EdgeToMachineTop + local EdgeToMachineBottom = OptionalParameters.EdgeToMachineBottom + local dElevationTop = EdgeToMachineTop and EdgeToMachineTop.dElevation + BeamData.CUT_EXTRA or nil + local dElevationBottom = EdgeToMachineBottom and EdgeToMachineBottom.dElevation + BeamData.CUT_EXTRA or nil -- se ho già l'utensile, devo solo discriminare se è lama sopra o sotto e verificare se ci arriva if OptionalParameters.nToolIndex then @@ -282,20 +275,24 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) local ToolInfo -- ricerca lama testa sopra ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = Face.vtN, bAllowTopHead = true, bAllowBottomHead = false, - dElevation = dElevationTop + dElevation = dElevationTop, + vtN = Face.vtN, + vtToolDirection = EdgeToMachineTop.vtN, + b3Raw = Part.b3Raw }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexTop = ToolInfo.nToolIndex end -- ricerca lama testa sotto ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = Face.vtN, bAllowTopHead = false, bAllowBottomHead = true, - dElevation = dElevationBottom + dElevation = dElevationBottom, + vtN = Face.vtN, + vtToolDirection = EdgeToMachineBottom.vtN, + b3Raw = Part.b3Raw }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexBottom = ToolInfo.nToolIndex @@ -337,19 +334,8 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) -- assegnazione tipo lama if nChosenToolIndex == nToolIndexBottom then sChosenBladeType = 'Bottom' - -- se lama sopra va verificato se va usata in DownUp elseif nChosenToolIndex == nToolIndexTop then - local dMinNzDownUp = TOOLS[nToolIndexTop].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face.vtN, nil, TOOLS[nToolIndexTop]) - local dCurrentResidualDepth = dElevationTopDownUp - TOOLS[nToolIndexTop].dMaxDepth - if Face.vtN:getZ() < dMinNzDownUp then - if ( dCurrentResidualDepth > 10 * GEO.EPS_SMALL) then - -- TODO serve messaggio per motivare il non applicabile?? - nChosenToolIndex = nil - end - sChosenBladeType = 'TopDownUp' - else - sChosenBladeType = 'Top' - end + sChosenBladeType = 'Top' end -- se non trovata alcuna lama ritorna nil @@ -379,19 +365,17 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) -- se non arrivano dall'esterno si cercano i migliori disponibili local EdgeToMachineList = OptionalParameters.EdgeToMachineList or { - Top = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Top', bAllowFastCuts), - Bottom = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Bottom', bAllowFastCuts), - TopDownUp = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopDownUp', bAllowFastCuts), - TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopGuillotine', bAllowFastCuts) + Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', bAllowFastCuts), + Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', bAllowFastCuts), + TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, 'TopGuillotine', bAllowFastCuts) } local sChosenBladeType -- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato local OptionalParametersGetBestBlade = { - dElevationTop = EdgeToMachineList.Top.dElevation + BeamData.CUT_EXTRA, - dElevationBottom = EdgeToMachineList.Bottom.dElevation + BeamData.CUT_EXTRA, - dElevationTopDownUp = EdgeToMachineList.TopDownUp.dElevation + BeamData.CUT_EXTRA, + EdgeToMachineTop = EdgeToMachineList.Top, + EdgeToMachineBottom = EdgeToMachineList.Bottom, nToolIndex = nToolIndex } nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) @@ -402,26 +386,14 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) -- ricerca lama migliore testa sopra local ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = true, - bAllowBottomHead = false + bAllowBottomHead = false, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachineList.Top.vtN, + b3Raw = Part.b3Raw }) nToolIndexGuillotine = ToolInfo.nToolIndex - -- se non trovato utensile, si prova in DownUp - if not nToolIndexGuillotine then - ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = -FaceToMachine.vtN, - bAllowTopHead = true, - bAllowBottomHead = false}) - if ToolInfo.nToolIndex then - local dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, EdgeToMachineList.TopGuillotine.vtN, TOOLS[ToolInfo.nToolIndex]) - if FaceToMachine.vtN:getZ() < dMinNzDownUp then - nToolIndexGuillotine = ToolInfo.nToolIndex - end - end - end - -- test fattibilità taglio a ghigliottina if nToolIndexGuillotine then local dRadialOffset = FaceByBlade.GetRadialOffsetForGuillotine( nToolIndexGuillotine, EdgeToMachineList.TopGuillotine.dLength) @@ -437,7 +409,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) end -local function GetDualSideCutStrategy( Proc, OptionalParameters) +local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) -- parametri opzionali OptionalParameters = OptionalParameters or {} @@ -458,17 +430,21 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters) -- ricerca lama testa sopra local ToolInfoTopBlade = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = true, bAllowBottomHead = false, - dElevation = dDepthToMachineTop + dElevation = dDepthToMachineTop, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachine.vtN, + b3Raw = Part.b3Raw }) -- ricerca lama testa sotto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = false, bAllowBottomHead = true, - dElevation = dDepthToMachineBottom + dElevation = dDepthToMachineBottom, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachine.vtN, + b3Raw = Part.b3Raw }) local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -481,10 +457,12 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters) dDepthToMachineBottom = EdgeToMachine.dElevation - dDepthToMachineTop + BeamData.CUT_EXTRA_MIN -- ricerca lama sotto con la nuova depth ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = false, bAllowBottomHead = true, - dElevation = dDepthToMachineBottom + dElevation = dDepthToMachineBottom, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachine.vtN, + b3Raw = Part.b3Raw }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -495,10 +473,12 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters) dDepthToMachineTop = EdgeToMachine.dElevation - dDepthToMachineBottom + BeamData.CUT_EXTRA_MIN -- ricerca lama sopra con la nuova depth ToolInfoTopBlade = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = true, bAllowBottomHead = false, - dElevation = dDepthToMachineTop + dElevation = dDepthToMachineTop, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachine.vtN, + b3Raw = Part.b3Raw }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL end @@ -526,10 +506,12 @@ local function GetDualSideCutStrategy( Proc, OptionalParameters) -- ricerca lama testa sopra local ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = FaceToMachine.vtN, bAllowTopHead = true, bAllowBottomHead = false, - dElevation = dDepthToMachine + dElevation = dDepthToMachine, + vtN = FaceToMachine.vtN, + vtToolDirection = EdgeToMachine.vtN, + b3Raw = Part.b3Raw }) -- se lama ci arriva si assegnano utensili e profondità da ritornare @@ -607,7 +589,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) elseif FaceData.IsFaceRhomboid( Proc, Proc.Faces[1].id) then local CuttingParametersList - CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, OptionalParameters) + CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters) if CuttingParametersList then local OptionalParametersFaceByBlade = { @@ -704,9 +686,6 @@ local function CutWithDicing( Proc, Part, OptionalParameters) return Machinings, Result end - -- limite per taglio DownUp - local dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face1.vtN, nil, TOOLS[nToolIndex]) - -- 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 @@ -719,7 +698,6 @@ local function CutWithDicing( Proc, Part, OptionalParameters) OptionalParametersDiceCut.dOffsetParallel = dDiceDimension OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced - OptionalParametersDiceCut.dMinNzDownUp = dMinNzDownUp OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) @@ -818,77 +796,45 @@ local function CutWithDicing( Proc, Part, OptionalParameters) local Cutting = {} local vtNCurrentFace = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) local FaceToMachine = { id = 0, vtN = vtNCurrentFace} - -- se taglio DownUp e strato pari composto da 1 o 2 elementi (tutti gli altri casi vengono saltati) - if ( vtNCurrentFace:getZ() < dMinNzDownUp) and ( ( i % 2) == 0) and ( #vCuts[i] <= 2) then - -- il primo elemento prende la direzione prevista, il secondo quella opposta - local vtToolDirectionNew = Vector3d( vtToolDirection) - if j ~= 1 then - vtToolDirectionNew = -vtToolDirection - end - -- lavorazione - local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part) - local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0) - local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirectionNew) - local dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA - local OptionalParametersFaceByBlade = { - dDepthToMachine = dDepthToMachine, - nToolIndex = nToolIndex, - dRadialStepSpan = 0, - dExtendAfterTail = dExtendAfterTail - } - Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) - Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) - - if Cutting.bIsApplicable then - table.insert( Machinings, Cutting) - else - bIsDicingOk = false - end - if Cutting.sStage == 'AfterTail' then - bMoveAfterSplit = true - end - -- caso generale - else - -- in generale sta sollevato di pochissimo - local dExtraCut = -0.1 - -- se tagli paralleli - if ( i % 2) == 0 then - -- se non ci sono tagli ortogonali devo affondare - if bNoPerpCuts then + -- in generale sta sollevato di pochissimo + local dExtraCut = -0.1 + -- se tagli paralleli + if ( i % 2) == 0 then + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts then + dExtraCut = BeamData.CUT_EXTRA + -- se è faccia singola si affonda + elseif Proc.nFct < 2 then + -- se tagli ortogonali invertiti, devo approfondire dello spessore lama + if bAreOrthogonalCutsInverted then + dExtraCut = TOOLS[nToolIndex].dThickness + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i] then dExtraCut = BeamData.CUT_EXTRA - -- se è faccia singola si affonda - elseif Proc.nFct < 2 then - -- se tagli ortogonali invertiti, devo approfondire dello spessore lama - if bAreOrthogonalCutsInverted then - dExtraCut = TOOLS[nToolIndex].dThickness - -- se ultimo taglio, devo affondare - elseif j == #vCuts[i] then - dExtraCut = BeamData.CUT_EXTRA - end end end - local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part) - local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0) - local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirection) - local dDepthToMachine = EdgeToMachine.dElevation + dExtraCut - local OptionalParametersFaceByBlade = { - dDepthToMachine = dDepthToMachine, - nToolIndex = nToolIndex, - dRadialStepSpan = 0, - dExtendAfterTail = dExtendAfterTail - } - Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) - Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) + end + local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part) + local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0) + local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirection) + local dDepthToMachine = EdgeToMachine.dElevation + dExtraCut + local OptionalParametersFaceByBlade = { + dDepthToMachine = dDepthToMachine, + nToolIndex = nToolIndex, + dRadialStepSpan = 0, + dExtendAfterTail = dExtendAfterTail + } + Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) + Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) - if Cutting.bIsApplicable then - table.insert( Machinings, Cutting) - bIsDicingOk = true - else - bIsDicingOk = false - end - if Cutting.sStage == 'AfterTail' then - bMoveAfterSplit = true - end + if Cutting.bIsApplicable then + table.insert( Machinings, Cutting) + bIsDicingOk = true + else + bIsDicingOk = false + end + if Cutting.sStage == 'AfterTail' then + bMoveAfterSplit = true end end end @@ -1096,7 +1042,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local OptionalParametersGetSingleCutStrategy = { bReduceBladePath = false, nFaceToMachineIndex = i, - EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine, TopDownUp = EdgeToMachine} + EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine} } nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) end diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index fb791e6..00cfb3f 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -187,6 +187,18 @@ local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) end +function FACEBYBLADE.GetCuttingType( FaceToMachine, EdgeToMachine) +local SCuttingType + + + + + + + return SCuttingType +end + + -- dato un certo offset radiale (uscente) e la distanza da mantenere dallo spigolo, calcola di quanto la lama deve arretrare lateralmente rispetto al centro per lavorare il lato function FACEBYBLADE.GetPathReductionLength( nToolIndex, dRadialOffset, OptionalParameters) local Tool = TOOLS[nToolIndex] From 070ad50d73ecd7ce51f0166fde0b8cacde7d7ec2 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 24 Oct 2025 18:38:25 +0200 Subject: [PATCH 02/21] - in FaceData IsFaceRectangular e IsFaceRhomboid si passa Face invece che idFace - in FaceByBlade introdotta funzione GetBladeEngagement che sostituisce GetMinNzDownUp --- LuaLibs/FaceData.lua | 16 ++++++++-------- StrategyLibs/BLADETOWASTE.lua | 2 +- StrategyLibs/FACEBYBLADE.lua | 24 ++++++++++++------------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 2f91b31..865bf2f 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -216,10 +216,10 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) end ------------------------------------------------------------------------------------------------------------- --- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart; passare Face invece dell'id? -function FaceData.IsFaceRectangular( Proc, idFace) +-- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart +function FaceData.IsFaceRectangular( Proc, Face) local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) - local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId) + local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, Face.id, nAddGrpId) if nContourCnt > 1 then error( 'IsFaceRectangular : too many loops') end @@ -235,10 +235,10 @@ function FaceData.IsFaceRectangular( Proc, idFace) end ------------------------------------------------------------------------------------------------------------- --- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart; passare Face invece dell'id? -function FaceData.IsFaceRhomboid( Proc, idFace) +-- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart +function FaceData.IsFaceRhomboid( Proc, Face) local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) - local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId) + local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, Face.id, nAddGrpId) if nContourCnt > 1 then error( 'IsFaceRhomboid : too many loops') end @@ -247,8 +247,8 @@ function FaceData.IsFaceRhomboid( Proc, idFace) local bIsRhomboid = false -- un parallelogramma è un trapezoide con i lati paralleli a due a due if bIsTrapezoid - and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[1].vtN, Proc.Faces[idFace + 1].Edges[3].vtN) - and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[2].vtN, Proc.Faces[idFace + 1].Edges[4].vtN) then + and AreOppositeVectorApprox( Face.Edges[1].vtN, Face.Edges[3].vtN) + and AreOppositeVectorApprox( Face.Edges[2].vtN, Face.Edges[4].vtN) then bIsRhomboid = true end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index ae36c09..f72d838 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -586,7 +586,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- se taglio da un lato non ce la fa, si prova da due lati -- TODO valutare se estendere ai non parallelogrammi - elseif FaceData.IsFaceRhomboid( Proc, Proc.Faces[1].id) then + elseif FaceData.IsFaceRhomboid( Proc, Proc.Faces[1]) then local CuttingParametersList CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 00cfb3f..13d73c0 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -16,8 +16,8 @@ local function GetLeadInOutType( Machining) local sLeadInOutType = '' if Machining.bIsStartClosed or Machining.bIsEndClosed - or Machining.sCutType == 'Guillotine' - or Machining.sCutType == 'Reduced' then + or Machining.sEdgeUsage == 'Guillotine' + or Machining.sEdgeUsage == 'Reduced' then sLeadInOutType = 'Perpendicular' else @@ -68,10 +68,10 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) local dToolMarkLength = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine) -- allungamento per faccia singola (aperta in tutte le direzioni) local dAddedLengthOpenFace = BeamData.CUT_EXTRA - if Machining.sCutType == 'Guillotine' then + if Machining.sEdgeUsage == 'Guillotine' then local dGuillotineLengthToMachine = 1 dAddedLengthOpenFace = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2 - elseif Machining.sCutType == 'Reduced' then + elseif Machining.sEdgeUsage == 'Reduced' then dAddedLengthOpenFace = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset) end @@ -187,15 +187,15 @@ local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) end -function FACEBYBLADE.GetCuttingType( FaceToMachine, EdgeToMachine) -local SCuttingType +function FACEBYBLADE.GetBladeEngagement( Face, vtToolDirection, b3Raw, Tool) +local sBladeEngagement - return SCuttingType + return sBladeEngagement end @@ -271,7 +271,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar dLongitudinalOffset = 0 end local dRadialStepSpan = OptionalParameters.dRadialStepSpan - local dMinNzDownUp = OptionalParameters.dMinNzDownUp local sUserNotes = OptionalParameters.sUserNotes or '' -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato @@ -299,6 +298,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- ricerca utensile if nToolIndex then Cutting.nToolIndex = nToolIndex + Cutting.sBladeEngagement = FACEBYBLADE.GetBladeEngagement( FaceToMachine, Cutting.vtToolDirection, Part.b3Raw, TOOLS[nToolIndex]) else local ToolSearchParameters = {} ToolSearchParameters.dElevation = dDepthToMachine @@ -361,7 +361,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.bInvert = false end -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità) - if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( Proc, FaceToMachine.id)) then + if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( Proc, FaceToMachine)) then OppositeToolDirectionMode = 'Disabled' -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza. if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) @@ -414,7 +414,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar else Cutting.dDepthToMachine = dDepthToMachine Cutting.dResidualDepth = 0 - Cutting.sCutType = 'Standard' + Cutting.sEdgeUsage = 'Standard' if bReduceBladePath and ( Proc.nFct == 1) and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then @@ -426,11 +426,11 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- taglio a ghigliottina if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine < Cutting.dMaxRadialOffset - 10 * GEO.EPS_SMALL) then dDepthToMachine = Cutting.dDepthToMachine + Cutting.dRadialOffsetGuillotine - Cutting.sCutType = 'Guillotine' + Cutting.sEdgeUsage = 'Guillotine' -- taglio ridotto else dDepthToMachine = Cutting.dDepthToMachine + Cutting.dMaxRadialOffset - Cutting.sCutType = 'Reduced' + Cutting.sEdgeUsage = 'Reduced' end end end From 0afcd786d17aacb43e836041ed93abc9da24cb72 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 24 Oct 2025 18:54:49 +0200 Subject: [PATCH 03/21] - in FaceData, IsFaceRectangular e IsFaceRhomboid ricevono solamente il parametro Face; utilizzano il gruppo per geometrie temporanee invece di AddGroup --- LuaLibs/BeamLib.lua | 15 +++++++++++++ LuaLibs/FaceData.lua | 40 +++++++++++++++++++++++------------ StrategyLibs/BLADETOWASTE.lua | 4 ++-- StrategyLibs/FACEBYBLADE.lua | 4 ++-- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index d6a312d..49aba8c 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -292,6 +292,21 @@ function BeamLib.CreateOrEmptyAddGroup( PartId) return true end +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateTempGroup() + local idTempGroup = EgtGroup( GDB_ID.ROOT) + EgtSetName( idTempGroup, "#TEMP_GROUP#") + + return idTempGroup +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetTempGroup() + local idTempGroup = EgtGetFirstNameInGroup( GDB_ID.ROOT, "#TEMP_GROUP#") or nil + + return idTempGroup +end + ------------------------------------------------------------------------------------------------------------- function BeamLib.GetAddGroup( PartId) -- recupero il nome del gruppo di lavoro corrente diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 865bf2f..ec7ab22 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -216,29 +216,41 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) end ------------------------------------------------------------------------------------------------------------- --- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart -function FaceData.IsFaceRectangular( Proc, Face) - local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) - local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, Face.id, nAddGrpId) +function FaceData.IsFaceRectangular( Face) + -- recupero gruppo per geometrie temporanee + local bIsTempGroupToDelete = false + local idTempGroup = BeamLib.GetTempGroup() + if not idTempGroup then + idTempGroup = BeamLib.CreateTempGroup() + bIsTempGroupToDelete = true + end + + local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then error( 'IsFaceRectangular : too many loops') end local bIsRectangular = EgtCurveIsARectangle( nContourId) - -- elimino curve create - for i = 1, nContourCnt do - EgtErase( nContourId + i - 1) + -- se necessario, elimino il gruppo temporaneo + if bIsTempGroupToDelete then + EgtErase( idTempGroup) end return bIsRectangular end ------------------------------------------------------------------------------------------------------------- --- TODO valutare se scrivere in gruppo temporaneo che non richiede di passare ogni volta idPart -function FaceData.IsFaceRhomboid( Proc, Face) - local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) - local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, Face.id, nAddGrpId) +function FaceData.IsFaceRhomboid( Face) + -- recupero gruppo per geometrie temporanee + local bIsTempGroupToDelete = false + local idTempGroup = BeamLib.GetTempGroup() + if not idTempGroup then + idTempGroup = BeamLib.CreateTempGroup() + bIsTempGroupToDelete = true + end + + local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then error( 'IsFaceRhomboid : too many loops') end @@ -253,9 +265,9 @@ function FaceData.IsFaceRhomboid( Proc, Face) bIsRhomboid = true end - -- elimino curve create - for i = 1, nContourCnt do - EgtErase( nContourId + i - 1) + -- se necessario, elimino il gruppo temporaneo + if bIsTempGroupToDelete then + EgtErase( idTempGroup) end return bIsRhomboid diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index f72d838..3293560 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -381,7 +381,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. - if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then + if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangular( FaceToMachine) then local nToolIndexGuillotine -- ricerca lama migliore testa sopra @@ -586,7 +586,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- se taglio da un lato non ce la fa, si prova da due lati -- TODO valutare se estendere ai non parallelogrammi - elseif FaceData.IsFaceRhomboid( Proc, Proc.Faces[1]) then + elseif FaceData.IsFaceRhomboid( Proc.Faces[1]) then local CuttingParametersList CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 13d73c0..c60abfc 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -361,7 +361,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.bInvert = false end -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità) - if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( Proc, FaceToMachine)) then + if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( FaceToMachine)) then OppositeToolDirectionMode = 'Disabled' -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza. if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) @@ -417,7 +417,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sEdgeUsage = 'Standard' if bReduceBladePath and ( Proc.nFct == 1) - and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then + and FaceData.IsFaceRectangular( FaceToMachine) then local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC From b8b71ff73a36b6d3910505b424ae4b4a807b5613 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 27 Oct 2025 10:09:18 +0100 Subject: [PATCH 04/21] - in BLADETOWASTE chiamate a FindBlade aggiornate --- StrategyLibs/BLADETOWASTE.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 3293560..c6477c7 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -278,7 +278,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, dElevation = dElevationTop, - vtN = Face.vtN, + FaceToMachine = Face, vtToolDirection = EdgeToMachineTop.vtN, b3Raw = Part.b3Raw }) @@ -290,7 +290,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) bAllowTopHead = false, bAllowBottomHead = true, dElevation = dElevationBottom, - vtN = Face.vtN, + FaceToMachine = Face, vtToolDirection = EdgeToMachineBottom.vtN, b3Raw = Part.b3Raw }) @@ -388,7 +388,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) local ToolInfo = MachiningLib.FindBlade( Proc, { bAllowTopHead = true, bAllowBottomHead = false, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachineList.Top.vtN, b3Raw = Part.b3Raw }) @@ -433,7 +433,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, dElevation = dDepthToMachineTop, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachine.vtN, b3Raw = Part.b3Raw }) @@ -442,7 +442,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = false, bAllowBottomHead = true, dElevation = dDepthToMachineBottom, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachine.vtN, b3Raw = Part.b3Raw }) @@ -460,7 +460,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = false, bAllowBottomHead = true, dElevation = dDepthToMachineBottom, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachine.vtN, b3Raw = Part.b3Raw }) @@ -476,7 +476,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, dElevation = dDepthToMachineTop, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachine.vtN, b3Raw = Part.b3Raw }) @@ -509,7 +509,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, dElevation = dDepthToMachine, - vtN = FaceToMachine.vtN, + FaceToMachine = FaceToMachine, vtToolDirection = EdgeToMachine.vtN, b3Raw = Part.b3Raw }) From 21bb95c0e987c0627c1bfc9b17eb822d4e13ce4f Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 28 Oct 2025 18:22:36 +0100 Subject: [PATCH 05/21] =?UTF-8?q?-=20in=20BeamLib=20aggiunta=20funzione=20?= =?UTF-8?q?GetPlaneOrientation=20per=20avere=20il=20modulo=20di=20un=20vet?= =?UTF-8?q?tore=20nelle=203=20direzioni=20e=20l'incidenza=20relativa=20di?= =?UTF-8?q?=20ogni=20componente=20sul=20totale=20-=20in=20BLADETOWASTE,=20?= =?UTF-8?q?chiamate=20a=20FindBlade=20aggiornate=20-=20in=20FACEBYBLADE=20?= =?UTF-8?q?numerose=20modifiche,=20da=20terminare,=20per=20determinare=20s?= =?UTF-8?q?e=20la=20lavorazione=20=C3=A8=20fattibile=20e=20se=20in=20DownU?= =?UTF-8?q?p=20(GetBladeEngagement)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/BeamLib.lua | 33 ++++++ StrategyLibs/BLADETOWASTE.lua | 16 +-- StrategyLibs/FACEBYBLADE.lua | 188 +++++++++++++++++++++++++++++++++- 3 files changed, 226 insertions(+), 11 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 49aba8c..25ca3cb 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -782,6 +782,39 @@ function BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtDirection) return BestEdge end +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPlaneOrientation( vtN) + local x = vtN:getX() + local y = vtN:getY() + local z = vtN:getZ() + + -- modulo della proiezione in ogni piano + local Orientation = { + { sPlane = "XY", dMagnitude = sqrt( x^2 + y^2)}, + { sPlane = "XZ", dMagnitude = sqrt( x^2 + z^2)}, + { sPlane = "YZ", dMagnitude = sqrt( y^2 + z^2)} + } + + -- modulo totale in 3d + local dTotalMagnitude = sqrt( x^2 + y^2 + z^2) + + -- incidenza del modulo in ogni piano + for i = 1, #Orientation do + -- se il modulo è nullo, si restituisce 0 in tutti i piani + if dTotalMagnitude == 0 then + Orientation[i].dRelativeMagnitude = 0 + -- altrimenti, si calcola l'incidenza relativa + else + Orientation[i].dRelativeMagnitude = Orientation[i].dMagnitude / dTotalMagnitude + end + end + + -- si ordina per incidenza in ogni piano + table.sort( Orientation, function (a, b) return a.dRatio > b.dRatio end) + + return Orientation +end + ------------------------------------------------------------------------------------------------------------- -- nNearSide : 3=Z+, -3=Z- function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, dMaxDist, nNearSide) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index c6477c7..ce49c81 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -279,7 +279,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) bAllowBottomHead = false, dElevation = dElevationTop, FaceToMachine = Face, - vtToolDirection = EdgeToMachineTop.vtN, + EdgeToMachine = EdgeToMachineTop, b3Raw = Part.b3Raw }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then @@ -291,7 +291,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) bAllowBottomHead = true, dElevation = dElevationBottom, FaceToMachine = Face, - vtToolDirection = EdgeToMachineBottom.vtN, + EdgeToMachine = EdgeToMachineBottom, b3Raw = Part.b3Raw }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then @@ -389,7 +389,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachineList.Top.vtN, + EdgeToMachine = EdgeToMachineList.Top, b3Raw = Part.b3Raw }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -434,7 +434,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachine.vtN, + EdgeToMachine = EdgeToMachine, b3Raw = Part.b3Raw }) -- ricerca lama testa sotto @@ -443,7 +443,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = true, dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachine.vtN, + EdgeToMachine = EdgeToMachine, b3Raw = Part.b3Raw }) @@ -461,7 +461,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = true, dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachine.vtN, + EdgeToMachine = EdgeToMachine, b3Raw = Part.b3Raw }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -477,7 +477,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachine.vtN, + EdgeToMachine = EdgeToMachine, b3Raw = Part.b3Raw }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -510,7 +510,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, dElevation = dDepthToMachine, FaceToMachine = FaceToMachine, - vtToolDirection = EdgeToMachine.vtN, + EdgeToMachine = EdgeToMachine, b3Raw = Part.b3Raw }) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index c60abfc..9e13054 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -187,15 +187,195 @@ local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) end -function FACEBYBLADE.GetBladeEngagement( Face, vtToolDirection, b3Raw, Tool) -local sBladeEngagement +-- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per il taglio scelto (Standard o DownUp) +local function IsFaceZOutOfRange ( vtNFace, Tool) + + -- lama sotto: angolo negativo troppo basso + if Tool.SetupInfo.HeadType.Top and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then + return true + end + -- lama sopra: angolo positivo troppo elevato + if Tool.SetupInfo.HeadType.Bottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then + return true + end + + return false +end +local function GetCorrectedElevationDownUp( ) + +end +local function IsOrientationOkForDownUp( Face, Edge, b3Raw) + -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp + if AreSameVectorApprox( Face.vtN, Edge) then + + return true + end + + -- orientamento 3d della faccia: non lavorabile in DownUp + -- TODO implementare gestione DownUp in 3d + local FaceOrientation = BeamLib.GetPlaneOrientation( Face.vtN) + if FaceOrientation[1].dRelativeMagnitude < 1 - 10 * GEO.EPS_SMALL then + + return false + end + + -- orientamento 2d: si determinano il piano della faccia e la direzione perpendicolare + local vtPerpendicularToPlane + if FaceOrientation[1].sPlane == 'XY' then + vtPerpendicularToPlane = Z_AX() + elseif FaceOrientation[1].sPlane == 'XZ' then + vtPerpendicularToPlane = Y_AX() + elseif FaceOrientation[1].sPlane == 'YZ' then + vtPerpendicularToPlane = X_AX() + end + + -- se l'utensile è in direzione perpendicolare al piano, l'orientamento è sempre valido per DownUp + if AreSameOrOppositeVectorApprox( Edge.vtN, vtPerpendicularToPlane) then + + return true + end + + -- orientamento composito faccia / direzione utensile + -- TODO migliorare!! + local bIsOrientationOkForDownUp = false + local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + + if FaceOrientation[1].sPlane == 'XY' then + + -- X discorde + if Face.vtN:getX() * Edge.vtN:getX() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getX() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getX() > b3Raw:getMax():getX() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getX() < b3Raw:getMax():getX() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + + -- Y discorde + elseif Face.vtN:getY() * Edge.vtN:getY() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getY() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getY() > b3Raw:getMax():getY() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getY() < b3Raw:getMax():getY() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + end + + elseif FaceOrientation[1].sPlane == 'XZ' then + + -- X discorde + if Face.vtN:getX() * Edge.vtN:getX() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getX() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getX() > b3Raw:getMax():getX() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getX() < b3Raw:getMax():getX() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + + -- Z discorde + elseif Face.vtN:getZ() * Edge.vtN:getZ() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getZ() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getZ() > b3Raw:getMax():getZ() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getZ() < b3Raw:getMax():getZ() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + end + + elseif FaceOrientation[1].sPlane == 'YZ' then + + -- Y discorde + if Face.vtN:getY() * Edge.vtN:getY() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getY() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getY() > b3Raw:getMax():getY() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getY() < b3Raw:getMax():getY() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + + -- Z discorde + elseif Face.vtN:getZ() * Edge.vtN:getZ() < 10 * GEO.EPS_SMALL then + + local bIsPointOnBox = false + if Edge.vtN:getZ() > GEO.EPS_SMALL then + bIsPointOnBox = ptOnBox:getZ() > b3Raw:getMax():getZ() - 500 * GEO.EPS_SMALL + else + bIsPointOnBox = ptOnBox:getZ() < b3Raw:getMax():getZ() + 500 * GEO.EPS_SMALL + end + + if bIsPointOnBox then + bIsOrientationOkForDownUp = true + end + end + end +end - return sBladeEngagement +-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) +function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) + local sBladeEngagement = 'Standard' + local dCorrectedElevation = Edge.dElevation + + -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio + if not IsFaceZOutOfRange( Face.vtN, Tool) then + + -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? + + return true, sBladeEngagement, dCorrectedElevation + end + + -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile + -- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta) + if IsFaceZOutOfRange( -Face.vtN, Tool) then + + return false + end + + -- faccia non rettangolare: non lavorabile in DownUp + if not FaceData.IsFaceRectangular( Face) then + + return false + end + + -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna + if IsOrientationOkForDownUp( Face, Edge, b3Raw) then + + sBladeEngagement = 'DownUp' + dCorrectedElevation = GetCorrectedElevationDownUp() + + return true, sBladeEngagement, dCorrectedElevation + end + + return false end @@ -298,6 +478,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- ricerca utensile if nToolIndex then Cutting.nToolIndex = nToolIndex + -- TODO qui ricevere anche la dMaxElevation o simile? decidere cosa fare se non arriva: si dovrà modificare la dResidualDepth Cutting.sBladeEngagement = FACEBYBLADE.GetBladeEngagement( FaceToMachine, Cutting.vtToolDirection, Part.b3Raw, TOOLS[nToolIndex]) else local ToolSearchParameters = {} @@ -311,6 +492,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- TODO bisognerà implementare anche la lama da sotto ToolSearchParameters.bAllowBottomHead = false ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade + -- TODO ToolSearchParameters da rivedere per il passaggio di FaceToMachine e EdgeToMachine local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) -- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire if ToolInfo.nToolIndex and not dMinNzDownUp then From 9468e3d0134cb2cfa83e78257b8195b09352451c Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 29 Oct 2025 15:29:40 +0100 Subject: [PATCH 06/21] - in FACEBYBLADE completata IsOrientationOkForDownUp; rimane da fare GetCorrectedElevationDownUp --- StrategyLibs/FACEBYBLADE.lua | 141 +++++++++++------------------------ 1 file changed, 45 insertions(+), 96 deletions(-) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 9e13054..1e98c73 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -203,12 +203,14 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end -local function GetCorrectedElevationDownUp( ) - +-- TODO da fare +local function GetCorrectedElevationDownUp( Face, Edge, b3Raw ) + end local function IsOrientationOkForDownUp( Face, Edge, b3Raw) + -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp if AreSameVectorApprox( Face.vtN, Edge) then @@ -224,12 +226,13 @@ local function IsOrientationOkForDownUp( Face, Edge, b3Raw) end -- orientamento 2d: si determinano il piano della faccia e la direzione perpendicolare + local sPlane = FaceOrientation[1].sPlane local vtPerpendicularToPlane - if FaceOrientation[1].sPlane == 'XY' then + if sPlane == 'XY' then vtPerpendicularToPlane = Z_AX() - elseif FaceOrientation[1].sPlane == 'XZ' then + elseif sPlane == 'XZ' then vtPerpendicularToPlane = Y_AX() - elseif FaceOrientation[1].sPlane == 'YZ' then + elseif sPlane == 'YZ' then vtPerpendicularToPlane = X_AX() end @@ -239,104 +242,50 @@ local function IsOrientationOkForDownUp( Face, Edge, b3Raw) return true end - -- orientamento composito faccia / direzione utensile - -- TODO migliorare!! - local bIsOrientationOkForDownUp = false - local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + -- se tutte le condizioni precedenti sono soddisfatte, il DownUp si può fare se lungo l'asse in cui Face.vtN e Edge.vtN sono discordi il punto iniziale del lato è sul box + -- in pratica, ciò significa che il braccio non entrerà in collisione con la trave + -- TODO in realtà così si escludono dei casi di faccia non troncante in cui aumenterebbe l'elevation ma si potrebbe comunque lavorare + local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + -- Helper function: verifica se i vettori sono discordi lungo l'asse indicato e, se sì, se il punto iniziale della lavorazione è sul box oppure no, nella direzione dell'utensile + local function IsDiscordantAndOnBox( sAxis) + -- si compongono i metodi getX, getY, getZ in base all'asse in arrivo (Face.vtN[getX] equivale a Face.vtN:getX()) + local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) + local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) + local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) + local dMaxb3rawComponent = b3Raw:getMax()["get" .. sAxis](b3Raw:getMax()) + local dMinb3rawComponent = b3Raw:getMin()["get" .. sAxis](b3Raw:getMin()) - if FaceOrientation[1].sPlane == 'XY' then - - -- X discorde - if Face.vtN:getX() * Edge.vtN:getX() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getX() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getX() > b3Raw:getMax():getX() - 500 * GEO.EPS_SMALL + if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then + if dEdgeComponent > GEO.EPS_SMALL then + return dPtonboxComponent > dMaxb3rawComponent - 500 * GEO.EPS_SMALL else - bIsPointOnBox = ptOnBox:getX() < b3Raw:getMax():getX() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true - end - - -- Y discorde - elseif Face.vtN:getY() * Edge.vtN:getY() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getY() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getY() > b3Raw:getMax():getY() - 500 * GEO.EPS_SMALL - else - bIsPointOnBox = ptOnBox:getY() < b3Raw:getMax():getY() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true + return dPtonboxComponent < dMinb3rawComponent + 500 * GEO.EPS_SMALL end end - - elseif FaceOrientation[1].sPlane == 'XZ' then - - -- X discorde - if Face.vtN:getX() * Edge.vtN:getX() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getX() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getX() > b3Raw:getMax():getX() - 500 * GEO.EPS_SMALL - else - bIsPointOnBox = ptOnBox:getX() < b3Raw:getMax():getX() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true - end - - -- Z discorde - elseif Face.vtN:getZ() * Edge.vtN:getZ() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getZ() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getZ() > b3Raw:getMax():getZ() - 500 * GEO.EPS_SMALL - else - bIsPointOnBox = ptOnBox:getZ() < b3Raw:getMax():getZ() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true - end + return false + end + -- in base all'orientamento, si verifica se il DownUp è fattibile + if sPlane == 'XY' then + if IsDiscordantAndOnBox( "X") then + return true + elseif IsDiscordantAndOnBox( "Y") then + return true end - - elseif FaceOrientation[1].sPlane == 'YZ' then - - -- Y discorde - if Face.vtN:getY() * Edge.vtN:getY() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getY() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getY() > b3Raw:getMax():getY() - 500 * GEO.EPS_SMALL - else - bIsPointOnBox = ptOnBox:getY() < b3Raw:getMax():getY() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true - end - - -- Z discorde - elseif Face.vtN:getZ() * Edge.vtN:getZ() < 10 * GEO.EPS_SMALL then - - local bIsPointOnBox = false - if Edge.vtN:getZ() > GEO.EPS_SMALL then - bIsPointOnBox = ptOnBox:getZ() > b3Raw:getMax():getZ() - 500 * GEO.EPS_SMALL - else - bIsPointOnBox = ptOnBox:getZ() < b3Raw:getMax():getZ() + 500 * GEO.EPS_SMALL - end - - if bIsPointOnBox then - bIsOrientationOkForDownUp = true - end + elseif sPlane == 'XZ' then + if IsDiscordantAndOnBox( "X") then + return true + elseif IsDiscordantAndOnBox( "Z") then + return true + end + elseif sPlane == 'YZ' then + if IsDiscordantAndOnBox( "Y") then + return true + elseif IsDiscordantAndOnBox( "Z") then + return true end end + + return false end From ecd2147e83c0ce2de3ab2801d5dda0b295ac4bfd Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 30 Oct 2025 13:20:15 +0100 Subject: [PATCH 07/21] - in FACEBYBLADE modifiche e refactoring per contemplare nuova gestione DownUp --- LuaLibs/FaceData.lua | 41 +++++---- Strategies/Standard/STR0003/STR0003.lua | 4 +- StrategyLibs/FACEBYBLADE.lua | 117 ++++++++++++++---------- 3 files changed, 90 insertions(+), 72 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index ec7ab22..8c8a120 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -218,12 +218,7 @@ end ------------------------------------------------------------------------------------------------------------- function FaceData.IsFaceRectangular( Face) -- recupero gruppo per geometrie temporanee - local bIsTempGroupToDelete = false local idTempGroup = BeamLib.GetTempGroup() - if not idTempGroup then - idTempGroup = BeamLib.CreateTempGroup() - bIsTempGroupToDelete = true - end local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then @@ -232,23 +227,13 @@ function FaceData.IsFaceRectangular( Face) local bIsRectangular = EgtCurveIsARectangle( nContourId) - -- se necessario, elimino il gruppo temporaneo - if bIsTempGroupToDelete then - EgtErase( idTempGroup) - end - return bIsRectangular end ------------------------------------------------------------------------------------------------------------- function FaceData.IsFaceRhomboid( Face) -- recupero gruppo per geometrie temporanee - local bIsTempGroupToDelete = false local idTempGroup = BeamLib.GetTempGroup() - if not idTempGroup then - idTempGroup = BeamLib.CreateTempGroup() - bIsTempGroupToDelete = true - end local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then @@ -265,14 +250,30 @@ function FaceData.IsFaceRhomboid( Face) bIsRhomboid = true end - -- se necessario, elimino il gruppo temporaneo - if bIsTempGroupToDelete then - EgtErase( idTempGroup) - end - return bIsRhomboid end +------------------------------------------------------------------------------------------------------------- +-- calcola l'elevazione di un lato rispetto al box passato +function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) + -- recupero gruppo per geometrie temporanee + local idTempGroup = BeamLib.GetTempGroup() + + -- costruzione trimesh rettangolare centrata sul lato + -- TODO sostituire EgtSurfTmFacetOppositeSide con punti direttamente in Edge + local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + local vtEdge = ptEdge2 - ptEdge1 + local vtMove = ( Edge.vtN ^ vtEdge) + local ptRectangleVertex1 = ptEdge1 + vtMove * 100 * GEO.EPS_SMALL + local ptRectangleVertex2 = ptEdge2 + vtMove * 100 * GEO.EPS_SMALL + local ptRectangleVertex3 = ptEdge1 - vtMove * 100 * GEO.EPS_SMALL + local idEdgeTrimesh = EgtSurfTmRectangle( idTempGroup, ptRectangleVertex1, ptRectangleVertex2, ptRectangleVertex3, GDB_RT.GLOB) + + local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Raw, true, GDB_ID.ROOT) + + return dElevation +end + ------------------------------------------------------------------------------------------------------------- local function CompareEdgesBottomFace( EdgeA, EdgeB) -- prima i lati con facce adiacenti diff --git a/Strategies/Standard/STR0003/STR0003.lua b/Strategies/Standard/STR0003/STR0003.lua index 7a6afd9..95058d0 100644 --- a/Strategies/Standard/STR0003/STR0003.lua +++ b/Strategies/Standard/STR0003/STR0003.lua @@ -236,6 +236,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) local BottomEdge = LongFace.MainEdges.BottomEdge -- TODO funzione separata + -- TODO è meglio cercare la lama qui e passarla alla FACEBYBLADE, la scelta è più precisa -- lama - calcolo lavorazioni local Cutting = {} -- parametri comuni a tutte le lavorazioni cutting @@ -243,8 +244,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, - bIsSplitFeature = bIsSplitFeature, - dMinNzDownUp = 0 + bIsSplitFeature = bIsSplitFeature } -- primo lato del tunnel o lato di fondo diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 1e98c73..1fefe73 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -203,12 +203,6 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end --- TODO da fare -local function GetCorrectedElevationDownUp( Face, Edge, b3Raw ) - -end - - local function IsOrientationOkForDownUp( Face, Edge, b3Raw) -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp @@ -292,14 +286,14 @@ end -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) local sBladeEngagement = 'Standard' - local dCorrectedElevation = Edge.dElevation + local dDownUpElevation = Edge.dElevation -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - return true, sBladeEngagement, dCorrectedElevation + return true, sBladeEngagement end -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile @@ -319,9 +313,9 @@ function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) if IsOrientationOkForDownUp( Face, Edge, b3Raw) then sBladeEngagement = 'DownUp' - dCorrectedElevation = GetCorrectedElevationDownUp() + dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) - return true, sBladeEngagement, dCorrectedElevation + return true, sBladeEngagement, dDownUpElevation end return false @@ -412,47 +406,40 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN -- TODO conviene spostare questi calcoli nel FaceData? Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) - -- TODO gestire lama da sotto - -- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert) - -- TODO esiste un limite downUp massimo per la lama da sopra?? - if nToolIndex and not dMinNzDownUp then - dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[nToolIndex]) - end - if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then - Cutting.bToolInvert = true - else - Cutting.bToolInvert = false - end -- ricerca utensile if nToolIndex then Cutting.nToolIndex = nToolIndex - -- TODO qui ricevere anche la dMaxElevation o simile? decidere cosa fare se non arriva: si dovrà modificare la dResidualDepth - Cutting.sBladeEngagement = FACEBYBLADE.GetBladeEngagement( FaceToMachine, Cutting.vtToolDirection, Part.b3Raw, TOOLS[nToolIndex]) + local dDownUpElevation = dDepthToMachine + + -- si determina se il taglio è fattibile e il modo di lavorare della lama + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) + + -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile + if not Cutting.bIsApplicable + or ( Cutting.sBladeEngagement == 'DownUp' + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then + + Cutting.sMessage = 'Orientation not reachable' + EgtOutLog( Cutting.sMessage) + return Cutting, EdgeToMachine.dElevation + end + + -- si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else local ToolSearchParameters = {} ToolSearchParameters.dElevation = dDepthToMachine - if Cutting.bToolInvert then - ToolSearchParameters.vtN = -FaceToMachine.vtN - else - ToolSearchParameters.vtN = FaceToMachine.vtN - end ToolSearchParameters.bAllowTopHead = true - -- TODO bisognerà implementare anche la lama da sotto - ToolSearchParameters.bAllowBottomHead = false + ToolSearchParameters.bAllowBottomHead = true ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade - -- TODO ToolSearchParameters da rivedere per il passaggio di FaceToMachine e EdgeToMachine + ToolSearchParameters.FaceToMachine = FaceToMachine + ToolSearchParameters.EdgeToMachine = EdgeToMachine + local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) - -- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire - if ToolInfo.nToolIndex and not dMinNzDownUp then - dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[ToolInfo.nToolIndex]) - if FaceToMachine.vtN:getZ() < dMinNzDownUp then - Cutting.bToolInvert = true - end - end Cutting.nToolIndex = ToolInfo.nToolIndex + Cutting.sBladeEngagement = ToolInfo.sBladeEngagement end - if not TOOLS[Cutting.nToolIndex] or not TOOLS[Cutting.nToolIndex].sName then + if not TOOLS[Cutting.nToolIndex] then Cutting.sMessage = 'Blade not found' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) @@ -478,11 +465,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- parametri della lavorazione + -- profondità (parametro DEPTH) Cutting.sDepth = sDepth + -- inizio e fine aperti o chiusi Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen + -- lato di lavoro e inversione per avere taglio concorde if TOOLS[Cutting.nToolIndex].bIsCCW then Cutting.nWorkside = MCH_MILL_WS.RIGHT @@ -491,21 +481,33 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.nWorkside = MCH_MILL_WS.LEFT Cutting.bInvert = false end - -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità) + + -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità) if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( FaceToMachine)) then + OppositeToolDirectionMode = 'Disabled' - -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza. + + -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then - -- si attiva OppositeToolDirection solo se non cambiano le condizioni di taglio downUp - local dNewMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, -Cutting.vtToolDirection, TOOLS[nToolIndex]) - if ( FaceToMachine.vtN:getZ() < dMinNzDownUp) == ( FaceToMachine.vtN:getZ() < dNewMinNzDownUp) then - OppositeToolDirectionMode = 'Enabled' - Cutting.vtToolDirection = -EdgeToMachine.vtN - Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) - Cutting.bInvert = not Cutting.bInvert - -- se le condizioni downUp cambiano, si setta per tagliare verso l'alto + -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) + + if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then + + if sBladeEngagementOpposite ~= 'DownUp' + or ( ( dDownUpElevationOpposite - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then + + OppositeToolDirectionMode = 'Enabled' + Cutting.sBladeEngagement = sBladeEngagementOpposite + Cutting.vtToolDirection = -EdgeToMachine.vtN + Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) + Cutting.bInvert = not Cutting.bInvert + end + + -- se non possibile taglio opposto, si setta per tagliare verso l'alto else if Cutting.nWorkside == MCH_MILL_WS.RIGHT then Cutting.nWorkside = MCH_MILL_WS.LEFT @@ -516,12 +518,17 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end end + elseif OppositeToolDirectionMode == 'Enabled' then Cutting.bInvert = not Cutting.bInvert end - if Cutting.bToolInvert then + + -- ToolInvert + if Cutting.sBladeEngagement == 'DownUp' then + Cutting.bToolInvert = true Cutting.bInvert = not Cutting.bInvert end + -- profondità da lavorare e offset radiale if OptionalParameters.dPocketHeight then if TOOLS[Cutting.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then @@ -571,8 +578,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine end end + -- completamento Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100 + -- step verticale e offset longitudinale Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness) Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY @@ -586,10 +595,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar else Cutting.dLongitudinalOffset = dLongitudinalOffset end + -- distanza di sicurezza Cutting.dStartSafetyLength = BeamData.CUT_SIC + -- overlap Cutting.dOverlap = 0 + -- EdgeUse e frame lavorazione if OppositeToolDirectionMode == 'Enabled' then Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection) @@ -600,10 +612,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar --Cutting.vtFaceUse = Cutting.vtToolDirection Cutting.nEdgesFaceUse = EdgeToMachine.id end + -- SCC Cutting.nSCC = GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN) + -- asse bloccato Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX())) + -- eventuale step orizzontale Cutting.CloneStepsRadial = {} if not dRadialStepSpan then @@ -615,8 +630,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.CloneStepsRadial.nCount = 1 Cutting.CloneStepsRadial.dStep = Cutting.dDepthToMachine end + -- approccio e retrazione Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine, bIsSplitFeature) + -- lunghezza lavorata -- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso Cutting.dLengthToMachine = EdgeToMachine.dLength + Cutting.LeadIn.dStartAddLength + Cutting.LeadOut.dEndAddLength From 25dbaed63b3dab6ee2d804938fe0369f3e70b542 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 30 Oct 2025 16:49:49 +0100 Subject: [PATCH 08/21] - funzioni IsFaceZOutOfRange, IsBladeOrientationOkForDownUp e GetBladeEngagement spostate in MachiningLib (da FACEBYBLADE) --- LuaLibs/MachiningLib.lua | 182 ++++++++++++++++++++++++++++++++--- StrategyLibs/FACEBYBLADE.lua | 140 +-------------------------- 2 files changed, 170 insertions(+), 152 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 514b9dc..01ff1a1 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -267,6 +267,141 @@ local function IsToolInAvailableToolList( AvailableToolList, sTool) return bToolFound end +------------------------------------------------------------------------------------------------------------- +-- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per la lavorazione scelta (per DownUp passare vtNFace opposta) +local function IsFaceZOutOfRange ( vtNFace, Tool) + + -- lama sotto: angolo negativo troppo basso + if Tool.SetupInfo.HeadType.Top and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then + return true + end + -- lama sopra: angolo positivo troppo elevato + if Tool.SetupInfo.HeadType.Bottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then + return true + end + + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) + + -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp + if AreSameVectorApprox( Face.vtN, Edge) then + + return true + end + + -- orientamento 3d della faccia: non lavorabile in DownUp + -- TODO implementare gestione DownUp in 3d + local FaceOrientation = BeamLib.GetPlaneOrientation( Face.vtN) + if FaceOrientation[1].dRelativeMagnitude < 1 - 10 * GEO.EPS_SMALL then + + return false + end + + -- orientamento 2d: si determinano il piano della faccia e la direzione perpendicolare + local sPlane = FaceOrientation[1].sPlane + local vtPerpendicularToPlane + if sPlane == 'XY' then + vtPerpendicularToPlane = Z_AX() + elseif sPlane == 'XZ' then + vtPerpendicularToPlane = Y_AX() + elseif sPlane == 'YZ' then + vtPerpendicularToPlane = X_AX() + end + + -- se l'utensile è in direzione perpendicolare al piano, l'orientamento è sempre valido per DownUp + if AreSameOrOppositeVectorApprox( Edge.vtN, vtPerpendicularToPlane) then + + return true + end + + -- se tutte le condizioni precedenti sono soddisfatte, il DownUp si può fare se lungo l'asse in cui Face.vtN e Edge.vtN sono discordi il punto iniziale del lato è sul box + -- in pratica, ciò significa che il braccio non entrerà in collisione con la trave + -- TODO in realtà così si escludono dei casi di faccia non troncante in cui aumenterebbe l'elevation ma si potrebbe comunque lavorare + local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + -- Helper function: verifica se i vettori sono discordi lungo l'asse indicato e, se sì, se il punto iniziale della lavorazione è sul box oppure no, nella direzione dell'utensile + local function IsDiscordantAndOnBox( sAxis) + -- si compongono i metodi getX, getY, getZ in base all'asse in arrivo (Face.vtN[getX] equivale a Face.vtN:getX()) + local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) + local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) + local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) + local dMaxb3rawComponent = b3Raw:getMax()["get" .. sAxis](b3Raw:getMax()) + local dMinb3rawComponent = b3Raw:getMin()["get" .. sAxis](b3Raw:getMin()) + + if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then + if dEdgeComponent > GEO.EPS_SMALL then + return dPtonboxComponent > dMaxb3rawComponent - 500 * GEO.EPS_SMALL + else + return dPtonboxComponent < dMinb3rawComponent + 500 * GEO.EPS_SMALL + end + end + return false + end + -- in base all'orientamento, si verifica se il DownUp è fattibile + if sPlane == 'XY' then + if IsDiscordantAndOnBox( "X") then + return true + elseif IsDiscordantAndOnBox( "Y") then + return true + end + elseif sPlane == 'XZ' then + if IsDiscordantAndOnBox( "X") then + return true + elseif IsDiscordantAndOnBox( "Z") then + return true + end + elseif sPlane == 'YZ' then + if IsDiscordantAndOnBox( "Y") then + return true + elseif IsDiscordantAndOnBox( "Z") then + return true + end + end + + return false +end + +------------------------------------------------------------------------------------------------------------- +-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) +function MachiningLib.GetBladeEngagement( Face, Edge, b3Raw, Tool) + local sBladeEngagement = 'Standard' + local dDownUpElevation = Edge.dElevation + + -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio + if not IsFaceZOutOfRange( Face.vtN, Tool) then + + -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? + + return true, sBladeEngagement + end + + -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile + -- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta) + if IsFaceZOutOfRange( -Face.vtN, Tool) then + + return false + end + + -- faccia non rettangolare: non lavorabile in DownUp + if not FaceData.IsFaceRectangular( Face) then + + return false + end + + -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna + if IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) then + + sBladeEngagement = 'DownUp' + dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) + + return true, sBladeEngagement, dDownUpElevation + end + + return false +end + ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo FRESA con certe caratteristiche -- TODO qui vtToolDirection è in realtà vtN @@ -389,8 +524,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local ToolInfo = {} -- parametri obbligatori - if type( ToolSearchParameters.vtN) ~= 'table' then - error( 'FindBlade : missing tool direction') + if type( ToolSearchParameters.FaceToMachine) ~= 'table' then + error( 'FindBlade : missing face info') end if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then error( 'FindBlade : missing top head info') @@ -401,10 +536,15 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if not ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then error( 'FindBlade : wrong head info') end + local FaceToMachine = ToolSearchParameters.FaceToMachine + local bAllowTopHead = ToolSearchParameters.bAllowTopHead + local bAllowBottomHead = ToolSearchParameters.bAllowBottomHead -- parametri opzionali - ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0 - ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false + local dElevation = ToolSearchParameters.dElevation or 0 + local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false + local EdgeToMachine = ToolSearchParameters.EdgeToMachine + local b3Raw = ToolSearchParameters.b3Raw local nBestToolIndex local dBestToolResidualDepth = 0 @@ -412,21 +552,33 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local bIsToolCompatible = false if TOOLS[i].sFamily == 'SAWBLADE' then - if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then + if bAllowTopHead and not bAllowBottomHead then bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bTop - elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then + elseif bAllowBottomHead and not bAllowTopHead then bIsToolCompatible = TOOLS[i].SetupInfo.HeadType.bBottom else bIsToolCompatible = true end end - -- check angolo limite lama - if TOOLS[i].SetupInfo.HeadType.bTop and ToolSearchParameters.vtN:getZ() < TOOLS[i].SetupInfo.GetMinNz( ToolSearchParameters.vtN, TOOLS[i]) - GEO.EPS_ZERO then - bIsToolCompatible = false - end - if TOOLS[i].SetupInfo.HeadType.bBottom and ToolSearchParameters.vtN:getZ() > TOOLS[i].SetupInfo.GetMaxNz( ToolSearchParameters.vtN, TOOLS[i]) + GEO.EPS_ZERO then - bIsToolCompatible = false + -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama + if FaceToMachine and EdgeToMachine and dElevation then + local sBladeEngagement + local dDownUpElevation + bIsToolCompatible, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Raw, TOOLS[i]) + -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile + if not bIsToolCompatible + or ( sBladeEngagement == 'DownUp' + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then + + bIsToolCompatible = false + end + + -- se si ha solo la faccia si può verificare se questa è orientata correttamente + elseif FaceToMachine then + if IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then + bIsToolCompatible = false + end end -- se c'è una lista di utensili disponibili, si verifica che l'utensile attuale sia tra quelli @@ -436,13 +588,13 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if bIsToolCompatible then -- TODO gestire accorciamento massimo materiale per inclinazione - local dCurrentResidualDepth = ToolSearchParameters.dElevation - TOOLS[i].dMaxDepth + local dCurrentResidualDepth = dElevation - TOOLS[i].dMaxDepth if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL) then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth else - -- prediligo utensile per tagli lunghi, se richiesto - if ToolSearchParameters.bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then + -- prediligo utensile per tagli lungo vena, se richiesto + if bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth else diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 1fefe73..837d95e 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -187,141 +187,6 @@ local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) end --- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per il taglio scelto (Standard o DownUp) -local function IsFaceZOutOfRange ( vtNFace, Tool) - - -- lama sotto: angolo negativo troppo basso - if Tool.SetupInfo.HeadType.Top and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then - return true - end - -- lama sopra: angolo positivo troppo elevato - if Tool.SetupInfo.HeadType.Bottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then - return true - end - - return false -end - - -local function IsOrientationOkForDownUp( Face, Edge, b3Raw) - - -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp - if AreSameVectorApprox( Face.vtN, Edge) then - - return true - end - - -- orientamento 3d della faccia: non lavorabile in DownUp - -- TODO implementare gestione DownUp in 3d - local FaceOrientation = BeamLib.GetPlaneOrientation( Face.vtN) - if FaceOrientation[1].dRelativeMagnitude < 1 - 10 * GEO.EPS_SMALL then - - return false - end - - -- orientamento 2d: si determinano il piano della faccia e la direzione perpendicolare - local sPlane = FaceOrientation[1].sPlane - local vtPerpendicularToPlane - if sPlane == 'XY' then - vtPerpendicularToPlane = Z_AX() - elseif sPlane == 'XZ' then - vtPerpendicularToPlane = Y_AX() - elseif sPlane == 'YZ' then - vtPerpendicularToPlane = X_AX() - end - - -- se l'utensile è in direzione perpendicolare al piano, l'orientamento è sempre valido per DownUp - if AreSameOrOppositeVectorApprox( Edge.vtN, vtPerpendicularToPlane) then - - return true - end - - -- se tutte le condizioni precedenti sono soddisfatte, il DownUp si può fare se lungo l'asse in cui Face.vtN e Edge.vtN sono discordi il punto iniziale del lato è sul box - -- in pratica, ciò significa che il braccio non entrerà in collisione con la trave - -- TODO in realtà così si escludono dei casi di faccia non troncante in cui aumenterebbe l'elevation ma si potrebbe comunque lavorare - local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) - -- Helper function: verifica se i vettori sono discordi lungo l'asse indicato e, se sì, se il punto iniziale della lavorazione è sul box oppure no, nella direzione dell'utensile - local function IsDiscordantAndOnBox( sAxis) - -- si compongono i metodi getX, getY, getZ in base all'asse in arrivo (Face.vtN[getX] equivale a Face.vtN:getX()) - local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) - local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) - local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) - local dMaxb3rawComponent = b3Raw:getMax()["get" .. sAxis](b3Raw:getMax()) - local dMinb3rawComponent = b3Raw:getMin()["get" .. sAxis](b3Raw:getMin()) - - if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then - if dEdgeComponent > GEO.EPS_SMALL then - return dPtonboxComponent > dMaxb3rawComponent - 500 * GEO.EPS_SMALL - else - return dPtonboxComponent < dMinb3rawComponent + 500 * GEO.EPS_SMALL - end - end - return false - end - -- in base all'orientamento, si verifica se il DownUp è fattibile - if sPlane == 'XY' then - if IsDiscordantAndOnBox( "X") then - return true - elseif IsDiscordantAndOnBox( "Y") then - return true - end - elseif sPlane == 'XZ' then - if IsDiscordantAndOnBox( "X") then - return true - elseif IsDiscordantAndOnBox( "Z") then - return true - end - elseif sPlane == 'YZ' then - if IsDiscordantAndOnBox( "Y") then - return true - elseif IsDiscordantAndOnBox( "Z") then - return true - end - end - - return false -end - - --- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) -function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) - local sBladeEngagement = 'Standard' - local dDownUpElevation = Edge.dElevation - - -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio - if not IsFaceZOutOfRange( Face.vtN, Tool) then - - -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - - return true, sBladeEngagement - end - - -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile - -- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta) - if IsFaceZOutOfRange( -Face.vtN, Tool) then - - return false - end - - -- faccia non rettangolare: non lavorabile in DownUp - if not FaceData.IsFaceRectangular( Face) then - - return false - end - - -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna - if IsOrientationOkForDownUp( Face, Edge, b3Raw) then - - sBladeEngagement = 'DownUp' - dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) - - return true, sBladeEngagement, dDownUpElevation - end - - return false -end - - -- dato un certo offset radiale (uscente) e la distanza da mantenere dallo spigolo, calcola di quanto la lama deve arretrare lateralmente rispetto al centro per lavorare il lato function FACEBYBLADE.GetPathReductionLength( nToolIndex, dRadialOffset, OptionalParameters) local Tool = TOOLS[nToolIndex] @@ -413,7 +278,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dDownUpElevation = dDepthToMachine -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile if not Cutting.bIsApplicable @@ -434,6 +299,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade ToolSearchParameters.FaceToMachine = FaceToMachine ToolSearchParameters.EdgeToMachine = EdgeToMachine + ToolSearchParameters.b3Raw = Part.b3Raw local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex @@ -493,7 +359,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then From 2d1abbb3ccecde773bbb4db6d5fb29d8aa7f3de9 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 30 Oct 2025 18:53:31 +0100 Subject: [PATCH 09/21] - correzioni per tagli DownUp --- LuaLibs/BeamLib.lua | 2 +- LuaLibs/MachiningLib.lua | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index ba864d9..325c13b 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -813,7 +813,7 @@ function BeamLib.GetPlaneOrientation( vtN) end -- si ordina per incidenza in ogni piano - table.sort( Orientation, function (a, b) return a.dRatio > b.dRatio end) + table.sort( Orientation, function (a, b) return a.dRelativeMagnitude > b.dRelativeMagnitude end) return Orientation end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 01ff1a1..3168fe5 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -272,11 +272,11 @@ end local function IsFaceZOutOfRange ( vtNFace, Tool) -- lama sotto: angolo negativo troppo basso - if Tool.SetupInfo.HeadType.Top and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then + if Tool.SetupInfo.HeadType.bTop and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then return true end -- lama sopra: angolo positivo troppo elevato - if Tool.SetupInfo.HeadType.Bottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then + if Tool.SetupInfo.HeadType.bBottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then return true end @@ -287,7 +287,7 @@ end local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp - if AreSameVectorApprox( Face.vtN, Edge) then + if AreSameVectorApprox( Face.vtN, Edge.vtN) then return true end @@ -518,7 +518,7 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo LAMA con certe caratteristiche --- TODO da completare +-- TODO da rivedere/completare -- TODO il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo) function MachiningLib.FindBlade( Proc, ToolSearchParameters) local ToolInfo = {} @@ -562,22 +562,22 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) end -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama - if FaceToMachine and EdgeToMachine and dElevation then - local sBladeEngagement - local dDownUpElevation - bIsToolCompatible, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Raw, TOOLS[i]) - -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile - if not bIsToolCompatible - or ( sBladeEngagement == 'DownUp' - and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then + if bIsToolCompatible then + if FaceToMachine and EdgeToMachine and dElevation then + local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Raw, TOOLS[i]) + -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile + if not bIsBladeOk + or ( sBladeEngagement == 'DownUp' + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then - bIsToolCompatible = false - end + bIsToolCompatible = false + end - -- se si ha solo la faccia si può verificare se questa è orientata correttamente - elseif FaceToMachine then - if IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then - bIsToolCompatible = false + -- se si ha solo la faccia si può verificare se questa è orientata correttamente + elseif FaceToMachine then + if IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then + bIsToolCompatible = false + end end end From 7b4673acef3e86cd3a5368e905323aecf161d252 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 3 Nov 2025 16:29:12 +0100 Subject: [PATCH 10/21] - varie modifiche ai tagli di lama per DownUp, caso solo 2d - in FaceData.GetEdgesInfo si scrivono anche i ptStart e ptEnd; IsFaceRhomboid diventa IsFaceParallelogram - in BeamLib aggiunta IsEdgeOnBox --- LuaLibs/BeamLib.lua | 46 ++++++++++++++++++++++++++++++++--- LuaLibs/FaceData.lua | 29 ++++++++++++---------- LuaLibs/MachiningLib.lua | 42 +++++++++++++++++++++----------- StrategyLibs/BLADETOWASTE.lua | 20 +++++++-------- StrategyLibs/FACEBYBLADE.lua | 11 +++++---- 5 files changed, 102 insertions(+), 46 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 325c13b..321fddc 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -793,13 +793,13 @@ function BeamLib.GetPlaneOrientation( vtN) -- modulo della proiezione in ogni piano local Orientation = { - { sPlane = "XY", dMagnitude = sqrt( x^2 + y^2)}, - { sPlane = "XZ", dMagnitude = sqrt( x^2 + z^2)}, - { sPlane = "YZ", dMagnitude = sqrt( y^2 + z^2)} + { sPlane = "XY", dMagnitude = EgtClamp( sqrt( x^2 + y^2), 0, 1)}, + { sPlane = "XZ", dMagnitude = EgtClamp( sqrt( x^2 + z^2), 0, 1)}, + { sPlane = "YZ", dMagnitude = EgtClamp( sqrt( y^2 + z^2), 0, 1)} } -- modulo totale in 3d - local dTotalMagnitude = sqrt( x^2 + y^2 + z^2) + local dTotalMagnitude = EgtClamp( sqrt( x^2 + y^2 + z^2), 0, 1) -- incidenza del modulo in ogni piano for i = 1, #Orientation do @@ -818,6 +818,44 @@ function BeamLib.GetPlaneOrientation( vtN) return Orientation end +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsEdgeOnBox( Face, Edge, b3Box) + -- TODO sostituire con informazioni direttamente da box e rimuuovere il parametro Face + local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + + -- il lato è sul box se i suoi estremi sono entrambi sullo stesso lato del box + if ptEdge1:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL + and ptEdge2:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL + and ptEdge2:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL + and ptEdge2:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL + and ptEdge2:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL + and ptEdge2:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL + and ptEdge2:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL then + + return true + end +end + ------------------------------------------------------------------------------------------------------------- -- nNearSide : 3=Z+, -3=Z- function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, dMaxDist, nNearSide) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 8c8a120..d378ea1 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -136,6 +136,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace ) end CurrentEdge.bIsStartOpen = EdgesEgt[nPreviousEdgeIndex].Open CurrentEdge.bIsEndOpen = EdgesEgt[nNextEdgeIndex].Open + CurrentEdge.ptStart = Point3d( EdgesEgt[i].Start) + CurrentEdge.ptEnd = Point3d( EdgesEgt[nNextEdgeIndex].Start) CurrentEdge.sType = 'Standard' CurrentEdge.id = i - 1 @@ -216,13 +218,13 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) end ------------------------------------------------------------------------------------------------------------- -function FaceData.IsFaceRectangular( Face) +function FaceData.IsFaceRectangle( Face) -- recupero gruppo per geometrie temporanee local idTempGroup = BeamLib.GetTempGroup() local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then - error( 'IsFaceRectangular : too many loops') + error( 'IsFaceRectangle : too many loops') end local bIsRectangular = EgtCurveIsARectangle( nContourId) @@ -231,13 +233,13 @@ function FaceData.IsFaceRectangular( Face) end ------------------------------------------------------------------------------------------------------------- -function FaceData.IsFaceRhomboid( Face) +function FaceData.IsFaceParallelogram( Face) -- recupero gruppo per geometrie temporanee local idTempGroup = BeamLib.GetTempGroup() local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then - error( 'IsFaceRhomboid : too many loops') + error( 'IsFaceParallelogram : too many loops') end local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId) @@ -255,21 +257,22 @@ end ------------------------------------------------------------------------------------------------------------- -- calcola l'elevazione di un lato rispetto al box passato -function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) +function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Box ) -- recupero gruppo per geometrie temporanee local idTempGroup = BeamLib.GetTempGroup() - -- costruzione trimesh rettangolare centrata sul lato -- TODO sostituire EgtSurfTmFacetOppositeSide con punti direttamente in Edge local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) - local vtEdge = ptEdge2 - ptEdge1 - local vtMove = ( Edge.vtN ^ vtEdge) - local ptRectangleVertex1 = ptEdge1 + vtMove * 100 * GEO.EPS_SMALL - local ptRectangleVertex2 = ptEdge2 + vtMove * 100 * GEO.EPS_SMALL - local ptRectangleVertex3 = ptEdge1 - vtMove * 100 * GEO.EPS_SMALL - local idEdgeTrimesh = EgtSurfTmRectangle( idTempGroup, ptRectangleVertex1, ptRectangleVertex2, ptRectangleVertex3, GDB_RT.GLOB) + -- ptMid è traslato leggermente all'interno per assicurare l'intersezione con il box + local dExtraLength = 500 * GEO.EPS_SMALL + local ptMid = ( ptEdge1 + ptEdge2) / 2 + Edge.vtN * dExtraLength + local idEdgeTrimesh - local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Raw, true, GDB_ID.ROOT) + -- piano di taglio del box orientato come la normale del lato e passante da ptMid + idEdgeTrimesh = EgtSurfTmPlaneInBBox( idTempGroup, ptMid, Edge.vtN, b3Box, GDB_RT.GLOB) + + -- al calcolo dell'elevazione devo aggiungere la lunghezza di cui avevo traslato il ptMid + local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Box, true, GDB_ID.ROOT) + dExtraLength return dElevation end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 3168fe5..27fe912 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -284,13 +284,20 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end ------------------------------------------------------------------------------------------------------------- -local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) +local function IsBladeOrientationOkForDownUp( Face, Edge, b3Part) -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp if AreSameVectorApprox( Face.vtN, Edge.vtN) then return true end + + -- componente Z negativa di vtTool, ossia testa sotto alla trave e rischio collisione carro Z: non lavorabile in Downup + -- TODO con lama da sopra il test è per Z > 0!!! + if Edge.vtN:getZ() < - 10 * GEO.EPS_SMALL then + + return false + end -- orientamento 3d della faccia: non lavorabile in DownUp -- TODO implementare gestione DownUp in 3d @@ -327,14 +334,14 @@ local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) - local dMaxb3rawComponent = b3Raw:getMax()["get" .. sAxis](b3Raw:getMax()) - local dMinb3rawComponent = b3Raw:getMin()["get" .. sAxis](b3Raw:getMin()) + local dMaxb3PartComponent = b3Part:getMax()["get" .. sAxis](b3Part:getMax()) + local dMinb3PartComponent = b3Part:getMin()["get" .. sAxis](b3Part:getMin()) if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then if dEdgeComponent > GEO.EPS_SMALL then - return dPtonboxComponent > dMaxb3rawComponent - 500 * GEO.EPS_SMALL + return dPtonboxComponent > dMaxb3PartComponent - 500 * GEO.EPS_SMALL else - return dPtonboxComponent < dMinb3rawComponent + 500 * GEO.EPS_SMALL + return dPtonboxComponent < dMinb3PartComponent + 500 * GEO.EPS_SMALL end end return false @@ -365,7 +372,7 @@ end ------------------------------------------------------------------------------------------------------------- -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) -function MachiningLib.GetBladeEngagement( Face, Edge, b3Raw, Tool) +function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, bAllowEntryFromInternalEdge) local sBladeEngagement = 'Standard' local dDownUpElevation = Edge.dElevation @@ -384,17 +391,24 @@ function MachiningLib.GetBladeEngagement( Face, Edge, b3Raw, Tool) return false end - -- faccia non rettangolare: non lavorabile in DownUp - if not FaceData.IsFaceRectangular( Face) then + -- faccia non parallelogramma: non lavorabile in DownUp + if not FaceData.IsFaceParallelogram( Face) then + + return false + end + + -- se il lato di approccio non è sul box e non è espressamente consentito (es: cubetti), non lavorabile in DownUp + local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN) + if not bAllowEntryFromInternalEdge and not BeamLib.IsEdgeOnBox( Face, EdgeOpposite, b3Part) then return false end -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna - if IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) then + if IsBladeOrientationOkForDownUp( Face, Edge, b3Part) then sBladeEngagement = 'DownUp' - dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) + dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Part) return true, sBladeEngagement, dDownUpElevation end @@ -544,7 +558,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local dElevation = ToolSearchParameters.dElevation or 0 local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine - local b3Raw = ToolSearchParameters.b3Raw + local b3Part = ToolSearchParameters.b3Part local nBestToolIndex local dBestToolResidualDepth = 0 @@ -563,12 +577,12 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then - if FaceToMachine and EdgeToMachine and dElevation then - local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Raw, TOOLS[i]) + if FaceToMachine and EdgeToMachine and dElevation and b3Part then + local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Part, TOOLS[i]) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile if not bIsBladeOk or ( sBladeEngagement == 'DownUp' - and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then bIsToolCompatible = false end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index ce49c81..03a1432 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -280,7 +280,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationTop, FaceToMachine = Face, EdgeToMachine = EdgeToMachineTop, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexTop = ToolInfo.nToolIndex @@ -292,7 +292,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationBottom, FaceToMachine = Face, EdgeToMachine = EdgeToMachineBottom, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexBottom = ToolInfo.nToolIndex @@ -381,7 +381,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. - if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangular( FaceToMachine) then + if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangle( FaceToMachine) then local nToolIndexGuillotine -- ricerca lama migliore testa sopra @@ -390,7 +390,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachineList.Top, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -435,7 +435,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) -- ricerca lama testa sotto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { @@ -444,7 +444,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -462,7 +462,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -478,7 +478,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL end @@ -511,7 +511,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachine, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) -- se lama ci arriva si assegnano utensili e profondità da ritornare @@ -586,7 +586,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- se taglio da un lato non ce la fa, si prova da due lati -- TODO valutare se estendere ai non parallelogrammi - elseif FaceData.IsFaceRhomboid( Proc.Faces[1]) then + elseif FaceData.IsFaceParallelogram( Proc.Faces[1]) then local CuttingParametersList CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 837d95e..1e2a7f5 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -260,6 +260,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' + local bAllowEntryFromInternalEdge = OptionalParameters.bAllowEntryFromInternalEdge or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -278,7 +279,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dDownUpElevation = dDepthToMachine -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile if not Cutting.bIsApplicable @@ -299,7 +300,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade ToolSearchParameters.FaceToMachine = FaceToMachine ToolSearchParameters.EdgeToMachine = EdgeToMachine - ToolSearchParameters.b3Raw = Part.b3Raw + ToolSearchParameters.b3Part = Part.b3Part local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex @@ -349,7 +350,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità) - if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( FaceToMachine)) then + if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceParallelogram( FaceToMachine)) then OppositeToolDirectionMode = 'Disabled' @@ -359,7 +360,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then @@ -421,7 +422,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sEdgeUsage = 'Standard' if bReduceBladePath and ( Proc.nFct == 1) - and FaceData.IsFaceRectangular( FaceToMachine) then + and FaceData.IsFaceRectangle( FaceToMachine) then local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC From 2536244f1b85c10909a15763c978ebedb233d94e Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 3 Nov 2025 16:37:01 +0100 Subject: [PATCH 11/21] in MachiningLib.GetBladeEngagement aggiunti i parametri dDepthToMachine e bAvoidCollisionCheckForStandardCut --- LuaLibs/MachiningLib.lua | 7 ++++--- StrategyLibs/FACEBYBLADE.lua | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 27fe912..b082880 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -372,7 +372,7 @@ end ------------------------------------------------------------------------------------------------------------- -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) -function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, bAllowEntryFromInternalEdge) +function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, dDepthToMachine, bAvoidCollisionCheckForStandardCut) local sBladeEngagement = 'Standard' local dDownUpElevation = Edge.dElevation @@ -399,7 +399,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, bAllowEntryF -- se il lato di approccio non è sul box e non è espressamente consentito (es: cubetti), non lavorabile in DownUp local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN) - if not bAllowEntryFromInternalEdge and not BeamLib.IsEdgeOnBox( Face, EdgeOpposite, b3Part) then + if not bAvoidCollisionCheckForStandardCut and not BeamLib.IsEdgeOnBox( Face, EdgeOpposite, b3Part) then return false end @@ -559,6 +559,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine local b3Part = ToolSearchParameters.b3Part + local bAvoidCollisionCheckForStandardCut = ToolSearchParameters.bAvoidCollisionCheckForStandardCut or false local nBestToolIndex local dBestToolResidualDepth = 0 @@ -578,7 +579,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then if FaceToMachine and EdgeToMachine and dElevation and b3Part then - local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Part, TOOLS[i]) + local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Part, TOOLS[i], dElevation, bAvoidCollisionCheckForStandardCut) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile if not bIsBladeOk or ( sBladeEngagement == 'DownUp' diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 1e2a7f5..af2c439 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -260,7 +260,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' - local bAllowEntryFromInternalEdge = OptionalParameters.bAllowEntryFromInternalEdge or false + local bAvoidCollisionCheckForStandardCut = OptionalParameters.bAvoidCollisionCheckForStandardCut or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -279,7 +279,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dDownUpElevation = dDepthToMachine -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile if not Cutting.bIsApplicable @@ -360,7 +360,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then From ddff655240aff9355d874f74a6c36ea684ebbedc Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 4 Nov 2025 12:54:09 +0100 Subject: [PATCH 12/21] - in BatchProcessNew e BeamExec, dove si salva il Box del Part si salva anche idBoxTm, id della trimesh del box - in BeamLib rimosse funzioni GetPlaneOrientation e IsEdgeOnBox, non usate - in MachiningLib rivista completamente GetBladeEngagement e aggiunta Check2DBladeCollision --- BatchProcessNew.lua | 6 +- LuaLibs/BeamExec.lua | 15 ++-- LuaLibs/BeamLib.lua | 71 ----------------- LuaLibs/FaceData.lua | 2 +- LuaLibs/MachiningLib.lua | 140 +++++++++------------------------- StrategyLibs/BLADETOWASTE.lua | 19 ++--- StrategyLibs/FACEBYBLADE.lua | 15 +--- 7 files changed, 65 insertions(+), 203 deletions(-) diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 7d16ded..04f5a8e 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -235,7 +235,8 @@ elseif BEAM.FLAG == 9 then local Part = {} Part.id = EgtGetParent( EgtGetParent( BEAM.FEATUREID)) - Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + Part.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL) + Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD) local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part) Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i') @@ -573,7 +574,8 @@ if bToProcess then PARTS[i].dRawWidth = PARTS[i].b3Raw:getDimY() PARTS[i].dRawHeight = PARTS[i].b3Raw:getDimZ() -- dimensione pezzo finito - PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL) + PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD) PARTS[i].dLength = PARTS[i].b3Part:getDimX() PARTS[i].dWidth = PARTS[i].b3Part:getDimY() PARTS[i].dHeight = PARTS[i].b3Part:getDimZ() diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 27b073c..6bb9267 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -477,7 +477,8 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b PARTS[i].dWidth = PARTS[i].b3Raw:getDimY() PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ() PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL - PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL) + PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD) PARTS[i].nIndexInParts = i PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i]) PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}} @@ -1145,7 +1146,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation) end -- aggiorno info pezzo Part.b3Raw = EgtGetRawPartBBox( Part.idRaw) - Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD) -- si applicano le strategie if Proc.ChosenStrategy then -- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia) @@ -1171,7 +1172,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation) BeamLib.RotateRawPart( Part, 1 - nCurrRotation) -- aggiorno info pezzo Part.b3Raw = EgtGetRawPartBBox( Part.idRaw) - Part.b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Part.id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD) end return MACHININGS, bAreAllApplyOk end @@ -1227,14 +1228,14 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) BeamLib.RotateRawPart( PARTS[nPart], 1) -- aggiorno info pezzo PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) - PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end if bCalcBestPieceUnloadPosition then -- inversione pezzo testa-coda BeamLib.InvertRawPart( PARTS[nPart], 2) -- aggiorno info pezzo PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) - PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end end local Part = {} @@ -1543,14 +1544,14 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) BeamLib.RotateRawPart( PARTS[nPart], 1) -- aggiorno info pezzo PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) - PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end if bCalcBestPieceUnloadPosition then -- inversione del pezzo testa-coda BeamLib.InvertRawPart( PARTS[nPart], 2) -- aggiorno info pezzo PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) - PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end end end diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 321fddc..5719ac6 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -785,77 +785,6 @@ function BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtDirection) return BestEdge end -------------------------------------------------------------------------------------------------------------- -function BeamLib.GetPlaneOrientation( vtN) - local x = vtN:getX() - local y = vtN:getY() - local z = vtN:getZ() - - -- modulo della proiezione in ogni piano - local Orientation = { - { sPlane = "XY", dMagnitude = EgtClamp( sqrt( x^2 + y^2), 0, 1)}, - { sPlane = "XZ", dMagnitude = EgtClamp( sqrt( x^2 + z^2), 0, 1)}, - { sPlane = "YZ", dMagnitude = EgtClamp( sqrt( y^2 + z^2), 0, 1)} - } - - -- modulo totale in 3d - local dTotalMagnitude = EgtClamp( sqrt( x^2 + y^2 + z^2), 0, 1) - - -- incidenza del modulo in ogni piano - for i = 1, #Orientation do - -- se il modulo è nullo, si restituisce 0 in tutti i piani - if dTotalMagnitude == 0 then - Orientation[i].dRelativeMagnitude = 0 - -- altrimenti, si calcola l'incidenza relativa - else - Orientation[i].dRelativeMagnitude = Orientation[i].dMagnitude / dTotalMagnitude - end - end - - -- si ordina per incidenza in ogni piano - table.sort( Orientation, function (a, b) return a.dRelativeMagnitude > b.dRelativeMagnitude end) - - return Orientation -end - -------------------------------------------------------------------------------------------------------------- -function BeamLib.IsEdgeOnBox( Face, Edge, b3Box) - -- TODO sostituire con informazioni direttamente da box e rimuuovere il parametro Face - local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) - - -- il lato è sul box se i suoi estremi sono entrambi sullo stesso lato del box - if ptEdge1:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL - and ptEdge2:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL then - - return true - end - if ptEdge1:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL - and ptEdge2:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL then - - return true - end - if ptEdge1:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL - and ptEdge2:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL then - - return true - end - if ptEdge1:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL - and ptEdge2:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL then - - return true - end - if ptEdge1:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL - and ptEdge2:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL then - - return true - end - if ptEdge1:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL - and ptEdge2:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL then - - return true - end -end - ------------------------------------------------------------------------------------------------------------- -- nNearSide : 3=Z+, -3=Z- function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, dMaxDist, nNearSide) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index d378ea1..39c49f7 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -181,7 +181,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT) if Proc.nFct < 6 or FaceIsToGet( i) then -- frame OCS faccia - Faces[i].vtFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN) + Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN) -- elevazione calcolata rispetto al box della parte Faces[i].dElevation = EgtSurfTmFacetElevationInBBox( Proc.id, i - 1, Part.b3Part, true, GDB_ID.ROOT) -- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index b082880..8da8dd4 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -284,104 +284,47 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end ------------------------------------------------------------------------------------------------------------- -local function IsBladeOrientationOkForDownUp( Face, Edge, b3Part) +local function Check2DBladeCollision( Edge, vtHead, Part, Tool, dDepthToMachine) + local idTempGroup = BeamLib.GetTempGroup() - -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp - if AreSameVectorApprox( Face.vtN, Edge.vtN) then - - return true - end + -- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione - -- componente Z negativa di vtTool, ossia testa sotto alla trave e rischio collisione carro Z: non lavorabile in Downup - -- TODO con lama da sopra il test è per Z > 0!!! - if Edge.vtN:getZ() < - 10 * GEO.EPS_SMALL then - - return false - end + -- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore + local ptMid = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + local vtEdge = Edge.ptEnd - Edge.ptStart + vtEdge:normalize() + local frBlade = Frame3d( ptMid, vtEdge, Edge.vtN) - -- orientamento 3d della faccia: non lavorabile in DownUp - -- TODO implementare gestione DownUp in 3d - local FaceOrientation = BeamLib.GetPlaneOrientation( Face.vtN) - if FaceOrientation[1].dRelativeMagnitude < 1 - 10 * GEO.EPS_SMALL then - - return false + -- silhouette del pezzo nel riferimento + local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'Check2DBladeCollision : error in part box') end - -- orientamento 2d: si determinano il piano della faccia e la direzione perpendicolare - local sPlane = FaceOrientation[1].sPlane - local vtPerpendicularToPlane - if sPlane == 'XY' then - vtPerpendicularToPlane = Z_AX() - elseif sPlane == 'XZ' then - vtPerpendicularToPlane = Y_AX() - elseif sPlane == 'YZ' then - vtPerpendicularToPlane = X_AX() - end + -- flat region del pezzo nel riferimento + local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - -- se l'utensile è in direzione perpendicolare al piano, l'orientamento è sempre valido per DownUp - if AreSameOrOppositeVectorApprox( Edge.vtN, vtPerpendicularToPlane) then - - return true - end - - -- se tutte le condizioni precedenti sono soddisfatte, il DownUp si può fare se lungo l'asse in cui Face.vtN e Edge.vtN sono discordi il punto iniziale del lato è sul box - -- in pratica, ciò significa che il braccio non entrerà in collisione con la trave - -- TODO in realtà così si escludono dei casi di faccia non troncante in cui aumenterebbe l'elevation ma si potrebbe comunque lavorare - local _, ptOnBox = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) - -- Helper function: verifica se i vettori sono discordi lungo l'asse indicato e, se sì, se il punto iniziale della lavorazione è sul box oppure no, nella direzione dell'utensile - local function IsDiscordantAndOnBox( sAxis) - -- si compongono i metodi getX, getY, getZ in base all'asse in arrivo (Face.vtN[getX] equivale a Face.vtN:getX()) - local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) - local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) - local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) - local dMaxb3PartComponent = b3Part:getMax()["get" .. sAxis](b3Part:getMax()) - local dMinb3PartComponent = b3Part:getMin()["get" .. sAxis](b3Part:getMin()) - - if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then - if dEdgeComponent > GEO.EPS_SMALL then - return dPtonboxComponent > dMaxb3PartComponent - 500 * GEO.EPS_SMALL - else - return dPtonboxComponent < dMinb3PartComponent + 500 * GEO.EPS_SMALL - end - end - return false - end - -- in base all'orientamento, si verifica se il DownUp è fattibile - if sPlane == 'XY' then - if IsDiscordantAndOnBox( "X") then - return true - elseif IsDiscordantAndOnBox( "Y") then - return true - end - elseif sPlane == 'XZ' then - if IsDiscordantAndOnBox( "X") then - return true - elseif IsDiscordantAndOnBox( "Z") then - return true - end - elseif sPlane == 'YZ' then - if IsDiscordantAndOnBox( "Y") then - return true - elseif IsDiscordantAndOnBox( "Z") then - return true - end - end + -- flat region del motore nel riferimento return false end ------------------------------------------------------------------------------------------------------------- --- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) -function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, dDepthToMachine, bAvoidCollisionCheckForStandardCut) +-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) +-- TODO si dovrà decidere come tagliare anche in base a lavorazione di coda (spostare dopo separazione?) o pezzo corto (il motore non deve ingombrare con il pinzaggio) +-- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade +function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bAvoidCollisionCheckForStandardCut) local sBladeEngagement = 'Standard' - local dDownUpElevation = Edge.dElevation -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? + if bAvoidCollisionCheckForStandardCut or not Check2DBladeCollision( Edge, Face.vtN, Part, Tool, dDepthToMachine) then - return true, sBladeEngagement + return true, sBladeEngagement + end end -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile @@ -391,26 +334,22 @@ function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, dDepthToMach return false end - -- faccia non parallelogramma: non lavorabile in DownUp - if not FaceData.IsFaceParallelogram( Face) then - + -- rischio collisione carro Z: non lavorabile in Downup + local bIsToolBelowWorkpiece = Edge.vtN:getZ() < - 10 * GEO.EPS_SMALL + local bIsToolAboveWorkpiece = Edge.vtN:getZ() > 10 * GEO.EPS_SMALL + + if Tool.SetupInfo.HeadType.bTop and bIsToolBelowWorkpiece + or ( Tool.SetupInfo.HeadType.bBottom and bIsToolAboveWorkpiece) then + return false end - -- se il lato di approccio non è sul box e non è espressamente consentito (es: cubetti), non lavorabile in DownUp - local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN) - if not bAvoidCollisionCheckForStandardCut and not BeamLib.IsEdgeOnBox( Face, EdgeOpposite, b3Part) then - - return false - end - - -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna - if IsBladeOrientationOkForDownUp( Face, Edge, b3Part) then + -- orientamento faccia / utensile compatibili con DownUp: lavorabile + if not Check2DBladeCollision( Edge, -Face.vtN, Part, Tool, dDepthToMachine) then sBladeEngagement = 'DownUp' - dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Part) - return true, sBladeEngagement, dDownUpElevation + return true, sBladeEngagement end return false @@ -558,7 +497,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local dElevation = ToolSearchParameters.dElevation or 0 local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine - local b3Part = ToolSearchParameters.b3Part + local Part = ToolSearchParameters.Part local bAvoidCollisionCheckForStandardCut = ToolSearchParameters.bAvoidCollisionCheckForStandardCut or false local nBestToolIndex @@ -578,13 +517,10 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then - if FaceToMachine and EdgeToMachine and dElevation and b3Part then - local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Part, TOOLS[i], dElevation, bAvoidCollisionCheckForStandardCut) - -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile - if not bIsBladeOk - or ( sBladeEngagement == 'DownUp' - and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then - + if FaceToMachine and EdgeToMachine and Part and dElevation then + local bIsBladeOk = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bAvoidCollisionCheckForStandardCut) + -- orientamento non raggiungibile + if not bIsBladeOk then bIsToolCompatible = false end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 03a1432..95f79b0 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -280,7 +280,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationTop, FaceToMachine = Face, EdgeToMachine = EdgeToMachineTop, - b3Part = Part.b3Part + Part = Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexTop = ToolInfo.nToolIndex @@ -292,7 +292,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationBottom, FaceToMachine = Face, EdgeToMachine = EdgeToMachineBottom, - b3Part = Part.b3Part + Part = Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexBottom = ToolInfo.nToolIndex @@ -390,7 +390,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachineList.Top, - b3Part = Part.b3Part + Part = Part }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -435,7 +435,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Part = Part.b3Part + Part = Part }) -- ricerca lama testa sotto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { @@ -444,7 +444,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Part = Part.b3Part + Part = Part }) local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -462,7 +462,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Part = Part.b3Part + Part = Part }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -478,7 +478,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Part = Part.b3Part + Part = Part }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL end @@ -511,7 +511,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachine, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Part = Part.b3Part + Part = Part }) -- se lama ci arriva si assegnano utensili e profondità da ritornare @@ -822,7 +822,8 @@ local function CutWithDicing( Proc, Part, OptionalParameters) dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dRadialStepSpan = 0, - dExtendAfterTail = dExtendAfterTail + dExtendAfterTail = dExtendAfterTail, + bAvoidCollisionCheckForStandardCut = true } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index af2c439..30bd196 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -276,15 +276,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- ricerca utensile if nToolIndex then Cutting.nToolIndex = nToolIndex - local dDownUpElevation = dDepthToMachine -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) + Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile - if not Cutting.bIsApplicable - or ( Cutting.sBladeEngagement == 'DownUp' - and ( dDownUpElevation - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then + if not Cutting.bIsApplicable then Cutting.sMessage = 'Orientation not reachable' EgtOutLog( Cutting.sMessage) @@ -300,7 +297,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade ToolSearchParameters.FaceToMachine = FaceToMachine ToolSearchParameters.EdgeToMachine = EdgeToMachine - ToolSearchParameters.b3Part = Part.b3Part + ToolSearchParameters.Part = Part local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex @@ -360,19 +357,15 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) + local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then - - if sBladeEngagementOpposite ~= 'DownUp' - or ( ( dDownUpElevationOpposite - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then OppositeToolDirectionMode = 'Enabled' Cutting.sBladeEngagement = sBladeEngagementOpposite Cutting.vtToolDirection = -EdgeToMachine.vtN Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) Cutting.bInvert = not Cutting.bInvert - end -- se non possibile taglio opposto, si setta per tagliare verso l'alto else From d9d505fc44e0424ca0dde1166ab85770362ea649 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 4 Nov 2025 17:40:48 +0100 Subject: [PATCH 13/21] =?UTF-8?q?-=20update=20versione=20minima=20Cam5=20-?= =?UTF-8?q?=20in=20BeamExec=20corretto=20il=20calcolo=20di=20nCycles:=20or?= =?UTF-8?q?a=20il=20calcolo=20dell'inversione=20si=20fa=20solo=20se=20rich?= =?UTF-8?q?iesto=20-=20in=20BeamExec=20rimossa=20cancellazione=20entit?= =?UTF-8?q?=C3=A0=20temporanee:=20si=20mette=20tutto=20nel=20gruppo=20idTe?= =?UTF-8?q?mp;=20adeguate=20le=20funzioni=20che=20creano=20geometrie=20tem?= =?UTF-8?q?poranee=20-=20in=20MachiningLib=20Check2DBladeCollision=20migli?= =?UTF-8?q?orata=20e=20ultimata:=20da=20testare?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/BeamExec.lua | 20 ++-------- LuaLibs/DiceCut.lua | 47 ++++++++++++---------- LuaLibs/MachiningLib.lua | 52 +++++++++++++++---------- Strategies/Standard/STR0002/STR0002.lua | 31 ++++++--------- Strategies/Standard/STR0015/STR0015.lua | 12 +++--- StrategyLibs/BLADETOWASTE.lua | 25 ++++++------ Version.lua | 4 +- 7 files changed, 94 insertions(+), 97 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 6bb9267..b12cc13 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1205,7 +1205,8 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end local vProcRot = {} - local nCycles = EgtIf( bCalcBestPieceUnloadPosition, 2, 1) -- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti + -- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti + local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1) -- per ogni inversione for nInvertIndex = 1, nCycles do -- per ogni rotazione @@ -1529,7 +1530,7 @@ end function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) -- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni for nPart = 1, #PARTS do - local nCycles = EgtIf( bCalcBestPieceUnloadPosition, 2, 1) + local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1) -- per ogni inversione for nInvertIndex = 1, nCycles do -- calcolo della migliore strategia per ogni rotazione del pezzo @@ -1703,21 +1704,8 @@ function BeamExec.ProcessMachinings( PARTS) bAllStrategiesApplied = false MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition) - -- cancellazione entità create ma non usate - -- TODO funzione? - local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id) - local idCurrentEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL) - while idCurrentEntity do - if EgtGetLevel( idCurrentEntity) == GDB_LV.TEMP then - local idEntityToDelete = idCurrentEntity - idCurrentEntity = EgtGetNext( idCurrentEntity) - EgtErase( idEntityToDelete) - else - idCurrentEntity = EgtGetNext( idCurrentEntity) - end - end - -- ordinamento lavorazioni + -- TODO sostituire con sorting Egt -- TODO completare ordinamento. Mancano le dipendenze. -- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart]) diff --git a/LuaLibs/DiceCut.lua b/LuaLibs/DiceCut.lua index 0211b3e..7b0bde2 100644 --- a/LuaLibs/DiceCut.lua +++ b/LuaLibs/DiceCut.lua @@ -16,7 +16,7 @@ local BeamData = require( 'BeamData') ---------------------------------------------------------------------------------------------------------------------------------------------------- -- creo i piani paralleli -- GetParallelPlanes: restituisce un vettore con gli indici delle superfici --- nAddGrpId: il layer +-- idAddGroup: il layer -- b3BoxDicing: il grezzo della barra -- ptC: il punto centrale del piano della feature -- vtN: il versore normale del piano della feature @@ -30,7 +30,7 @@ local BeamData = require( 'BeamData') -- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) -- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) -- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) -local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) +local function GetParallelPlanes( idAddGroup, b3BoxDicing, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) local ptMyCCut local AreaMin = 5*5 if ptCCut and vtNCut then @@ -46,7 +46,7 @@ local function GetParallelPlanes( nAddGrpId, b3BoxDicing, ptC, vtN, nCopyPlane, local TabellaTmSurfParallel = {} local i = nCopyPlane while i < nStep do - local SurfId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB) + local SurfId = EgtSurfTmPlaneInBBox( idAddGroup, ptC + ( i * dOffset) * vtN, vtN, b3BoxDicing, GDB_RT.GLOB) local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) if nFacet == 0 then -- se sono al primo taglio do una possibilità in più di girare @@ -86,11 +86,11 @@ end ---------------------------------------------------------------------------------------------------------------------------------------------------- -- GetOrderedCutTable: --- nAddGrpId: il layer +-- idAddGroup: il layer -- TabParallelPlanes: tabella delle superfici dei piani paralleli -- TabOrtoPlanes: tabella delle superfici dei piani ortogonali -- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) -local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes) +local function GetOrderedCutTable( idAddGroup, TabParallelPlanes, TabOrtoPlanes) local StepParallel = #TabParallelPlanes local StepOrto = #TabOrtoPlanes local TabellaOrderParallelCut1 = {} @@ -99,8 +99,8 @@ local function GetOrderedCutTable( nAddGrpId, TabParallelPlanes, TabOrtoPlanes) TabellaOrderParallelCut1[IndexTmP] = {} for IndexOrto=1, StepOrto do local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) - local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId) - local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nAddGrpId) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, idAddGroup) if Copy1Id and ptOrtoN then EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) @@ -295,8 +295,8 @@ local function VerifyFirstOrthoCut( CutTable, dOffsetParallel, b3BoxDicing) local dLongSize = x1 + x2 -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti if dLongSize <= dOffsetParallel + 1.0 then - local nAddGrpId = EgtGetParent( Cut1Id) - local SurfId = EgtSurfTmBySewing( nAddGrpId, { Cut1Id, Cut2Id}) + local idAddGroup = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( idAddGroup, { Cut1Id, Cut2Id}) --EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) EgtErase( CutOId) table.remove( CutTable[1], 1) @@ -338,7 +338,7 @@ end ---------------------------------------------------------------------------------------------------------------------------------------------------- -- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature -- le funzioni commentate permettono di vedere la creazione di BoundingBox -local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint) +local function DistanzaMassima( idAddGroup, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, TPoint) -- calcolo il riferimento nel piano 1 local Frame1 = Frame3d( ptC1, vtN1) -- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani @@ -353,7 +353,7 @@ local function DistanzaMassima( nAddGrpId, ptC1, vtN1, ptC2, vtN2, b3BoxDicing, end -- eventuale altra faccia if ptC2 and vtN2 then - local IdAux = EgtGroup( nAddGrpId) + local IdAux = EgtGroup( idAddGroup) local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, b3BoxDicing, GDB_RT.GLOB) EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB) if IdSurf2 then @@ -394,7 +394,12 @@ end --------------------------------------------------------------------------------------------------------------- function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- gruppo per geometria addizionale - local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local idAddGroup + if OptionalParameters.bSaveAddedGeometries then + idAddGroup = BeamLib.GetAddGroup( Part.id) + else + idAddGroup = BeamLib.GetTempGroup() + end -- faccia primaria local ptCMainFace @@ -437,10 +442,10 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) if ptCSubordinateFace and vtNSubordinateFace then TBoxPoint = VerificaEstremiGrezzo( ptCSubordinateFace, vtNSubordinateFace, TBoxPoint) end - local dElevP = DistanzaMassima( nAddGrpId, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint) + local dElevP = DistanzaMassima( idAddGroup, ptCMainFace, vtNMainFace, ptCSubordinateFace, vtNSubordinateFace, b3BoxDicing, TBoxPoint) local dElevO if ptCSubordinateFace and vtNSubordinateFace and not AreOppositeVectorApprox( vtNSubordinateFace, vtNMainFace) then - dElevO = DistanzaMassima( nAddGrpId, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint) + dElevO = DistanzaMassima( idAddGroup, ptCSubordinateFace, vtNSubordinateFace, ptCMainFace, vtNMainFace, b3BoxDicing, TBoxPoint) end -- TODO parte sotto da aggiungere???? se sì va passata anche la dimensione cubetto ridotta dOffsetOrthogonalReduced @@ -474,7 +479,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- PIANI PARALLELI alla faccia di taglio local TabellaTmSurfP = {} - local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace) + local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCMainFace, vtNMainFace, 0, dOffsetParallel, nStepParallel, Color3d( FUCHSIA(), 60), dTolerance, true, ptCSubordinateFace, vtNSubordinateFace) for i = #TabFromIn, 1, -1 do table.insert( TabellaTmSurfP, TabFromIn[i]) end @@ -483,12 +488,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- orientamento definito da seconda faccia if not bGetOrtoPlanes then local TabellaTmSurfOrto = {} - local TabFromIn = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace) + local TabFromIn = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCSubordinateFace, vtNSubordinateFace, 0, dOffsetOrthogonal, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCMainFace, vtNMainFace) for i = #TabFromIn, 1, -1 do table.insert( TabellaTmSurfOrto, TabFromIn[i]) end - local TabellaOrderParallelCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati - local TabellaOrderOrtoCut = GetOrderedCutTable( nAddGrpId, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + local TabellaOrderParallelCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( idAddGroup, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati @@ -535,12 +540,12 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) if OffsetRel and CopyPlane and dCenOffs then ptCInner = ptCInner + dCenOffs * vtO - local TabRight = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60), + local TabRight = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, -OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) if CopyPlane == 0 then CopyPlane = 1 end - local TabLeft = GetParallelPlanes( nAddGrpId, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60), + local TabLeft = GetParallelPlanes( idAddGroup, b3BoxDicing, ptCStart, vtO, CopyPlane, OffsetRel, nStepOrthogonal, Color3d( GREEN(), 60), dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) -- carico la tabella con gli indici riordinati local TempOrtoTab = {} @@ -551,7 +556,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) table.insert( TempOrtoTab, TabRight[i]) end -- creo una tabella per ogni piano per generare i tagli sulla Inner - local TempParTab = GetOrderedCutTable( nAddGrpId, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + local TempParTab = GetOrderedCutTable( idAddGroup, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) for i = 1, #TempParTab do table.insert( TabFUCHSIA, TempParTab[i]) end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 8da8dd4..9f530b5 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -284,28 +284,44 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end ------------------------------------------------------------------------------------------------------------- -local function Check2DBladeCollision( Edge, vtHead, Part, Tool, dDepthToMachine) +-- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione +local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) local idTempGroup = BeamLib.GetTempGroup() - -- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione - -- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore - local ptMid = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + local ptMachining = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine) local vtEdge = Edge.ptEnd - Edge.ptStart vtEdge:normalize() - local frBlade = Frame3d( ptMid, vtEdge, Edge.vtN) - -- silhouette del pezzo nel riferimento - local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup) + -- costruzione flat region del pezzo nel piano perpendicolare al taglio + -- si estrae prima la silhouette nel piano + local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) -- se più curve c'è qualcosa che non va: errore if nCurveCount > 1 then error( 'Check2DBladeCollision : error in part box') end - - -- flat region del pezzo nel riferimento + -- creazione flat region dalla silhouette local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - -- flat region del motore nel riferimento + -- costruzione flat region approssimata del motore nel piano perpendicolare al taglio + -- punto di congiunzione tra motore e lama + local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial + -- se taglio standard (no DownUp) il punto va spostato dello spessore lama + if AreSameVectorApprox( vtNFace, vtHead) then + ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness + end + -- TODO qui sostituire con il valore reale letto dal SetupInfo + local dHeadDepth = 480 + local dHeadWidth = 480 + local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth + local ptCross = ptOpposite + vtHead * dHeadDepth + local idHeadRectangle = EgtRectangle3P( idTempGroup, ptMaxElev, ptCross, ptOpposite, GDB_RT.GLOB) + -- flat region dal rettangolo + local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle) + + -- intersezione + --local idTestSurfFr = EgtCopyGlob( idPartSurfFr, idTempGroup) + local bCollisionFound = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) return false end @@ -321,7 +337,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - if bAvoidCollisionCheckForStandardCut or not Check2DBladeCollision( Edge, Face.vtN, Part, Tool, dDepthToMachine) then + if bAvoidCollisionCheckForStandardCut or not Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) then return true, sBladeEngagement end @@ -345,7 +361,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- orientamento faccia / utensile compatibili con DownUp: lavorabile - if not Check2DBladeCollision( Edge, -Face.vtN, Part, Tool, dDepthToMachine) then + if not Check2DBladeCollision( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) then sBladeEngagement = 'DownUp' @@ -1387,9 +1403,9 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) local ProcTm = FeatureLib.GetProcFromTrimesh( Machining.Geometry[1][1], Part) local dDepthToMachine = min( ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation, ( Machining.dMaxElev or ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation)) - ( max( 0, Machining.dResidualDepth or 0)) local nSteps = max( ceil( ( dDepthToMachine - 50 * GEO.EPS_SMALL) / TOOLS[Machining.nToolIndex].dStep), 1) - local nAddGroupId = BeamLib.GetAddGroup( Part.id) + local idTempGroup = BeamLib.GetTempGroup() -- TODO in futuro creare flatregion (se ci fossero isole il calcolo del percorso non sarebbe corretto) - local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], nAddGroupId) + local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], idTempGroup) -- si settano i lati aperti della curva derivata dalla superficie for i = 1, #ProcTm.Faces[Machining.Geometry[1][2] + 1].Edges do if ProcTm.Faces[Machining.Geometry[1][2] + 1].Edges[i].bIsOpen then @@ -1397,7 +1413,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) end end -- dal momento che la funzione EgtPocketing non considera il grezzo, nei casi ottimizzati si deve correggere l'offset - local idTestCurve = EgtCopyGlob( idFaceContour, nAddGroupId ) + local idTestCurve = EgtCopyGlob( idFaceContour, idTempGroup ) local bIsOptimizedPocketing = ( TOOLS[Machining.nToolIndex].dDiameter > TOOLS[Machining.nToolIndex].dSideStep - 10 * GEO.EPS_SMALL) and EgtOffsetCurve( idTestCurve, -TOOLS[Machining.nToolIndex].dDiameter / 2 - 10 * GEO.EPS_SMALL) if not bIsOptimizedPocketing then @@ -1413,7 +1429,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) end end -- calcolo percorso di svuotatura replicando il calcolo che fa la svuotatura - local idPocketingPath = EgtPocketing( idFaceContour, TOOLS[Machining.nToolIndex].dDiameter / 2, TOOLS[Machining.nToolIndex].dSideStep, 0, Machining.nSubType, true, nAddGroupId) + local idPocketingPath = EgtPocketing( idFaceContour, TOOLS[Machining.nToolIndex].dDiameter / 2, TOOLS[Machining.nToolIndex].dSideStep, 0, Machining.nSubType, true, idTempGroup) local dPocketingPathLength = EgtCurveLength( idPocketingPath) -- calcolo lunghezze e tempi totali if dPocketingPathLength then @@ -1425,10 +1441,6 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) dLengthToMachineAllStepsWithLeadInOut = 99999 * nSteps dTimeToMachineTotal = dLengthToMachineAllStepsWithLeadInOut / dToolFeed end - -- le geometrie create si settano da cancellare - EgtSetLevel( idFaceContour, GDB_LV.TEMP) - EgtSetLevel( idPocketingPath, GDB_LV.TEMP) - EgtSetLevel( idTestCurve, GDB_LV.TEMP) else error( 'GetTimeToMachineAllStepsWithLeadInOut : unknown machining type') end diff --git a/Strategies/Standard/STR0002/STR0002.lua b/Strategies/Standard/STR0002/STR0002.lua index d47f3a6..eda5f52 100644 --- a/Strategies/Standard/STR0002/STR0002.lua +++ b/Strategies/Standard/STR0002/STR0002.lua @@ -428,7 +428,12 @@ end local function GetSplitSurfaces( Proc, Part, bAddMachining) local vAddId = {} local vAddIdTunnel = {} - local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local idAddGroup + if bAddMachining then + idAddGroup = BeamLib.GetAddGroup( Part.id) + else + idAddGroup = BeamLib.GetTempGroup() + end local nOriginalTmIdTunnel = GDB_ID.NULL if Proc.MainFaces.TunnelAddedFaces then nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id @@ -438,18 +443,14 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining) local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) if #FeatureSplittingPoints == 0 then - local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL - if not bAddMachining then - EgtSetLevel( nAddId, GDB_LV.TEMP) - EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP) - end + local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL table.insert( vAddId, nAddId) table.insert( vAddIdTunnel, nAddIdTunnel) else for i = 1, #FeatureSplittingPoints do - local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL + local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL if i == 1 then -- prima superficie, va tagliata solo a sinistra local ptSplit = FeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0) @@ -465,23 +466,15 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining) EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB) EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB) end - if not bAddMachining then - EgtSetLevel( nAddId, GDB_LV.TEMP) - EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP) - end table.insert( vAddId, nAddId) table.insert( vAddIdTunnel, nAddIdTunnel) end -- taglio ultima superficie, va tagliata solo a destra - local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL + local nAddId = EgtCopyGlob( Proc.id, idAddGroup) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, idAddGroup) or GDB_ID.NULL local ptSplit = FeatureSplittingPoints[#FeatureSplittingPoints] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0) EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB) EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB) - if not bAddMachining then - EgtSetLevel( nAddId, GDB_LV.TEMP) - EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP) - end table.insert( vAddId, nAddId) table.insert( vAddIdTunnel, nAddIdTunnel) end diff --git a/Strategies/Standard/STR0015/STR0015.lua b/Strategies/Standard/STR0015/STR0015.lua index c53cff6..1be1101 100644 --- a/Strategies/Standard/STR0015/STR0015.lua +++ b/Strategies/Standard/STR0015/STR0015.lua @@ -108,15 +108,17 @@ local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries) local nMidFacet = Proc.nFct // 2 -- faccia a metà circa local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT) - local nAddGroupId = BeamLib.GetAddGroup( Part.id) + local idAddGroup + if bSaveAddedGeometries then + idAddGroup = BeamLib.GetAddGroup( Part.id) + else + idAddGroup = BeamLib.GetTempGroup() + end -- aggiungo piano di sgrossatura e lo lavoro local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN) - local AddId = EgtSurfTmPlaneInBBox( nAddGroupId, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB) + local AddId = EgtSurfTmPlaneInBBox( idAddGroup, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB) -- se la faccia è stata creata if AddId then - if not bSaveAddedGeometries then - EgtSetLevel( AddId, GDB_LV.TEMP) - end -- creo piano di taglio sulla testa del tenone local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 95f79b0..1989ea3 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -343,13 +343,8 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) 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) - EgtSetInfo( idDiceFace, 'TASKID', Proc.idTask) - if not bSaveAddedGeometries then - EgtSetLevel( idDiceFace, GDB_LV.TEMP) - end +local function SetDiceFaceInfo( Proc, idDiceFace) + EgtSetName( idDiceFace, 'Face' .. tostring( Proc.idFeature or 'Add') .. '_Dice') end @@ -699,6 +694,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing + OptionalParametersDiceCut.bSaveAddedGeometries = bSaveAddedGeometries local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) -- se nessun cubetto trovato, si richiama ricorsivamente la BladeToWaste forzando di non fare i cubetti @@ -715,7 +711,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) local bAreOrthogonalCutsInverted = false for i = 1, #vCuts do for j = 1, #vCuts[i] do - SetDiceFaceInfo( Proc, vCuts[i][j], bSaveAddedGeometries) + SetDiceFaceInfo( Proc, vCuts[i][j]) if ( i % 2) == 1 then local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) if ( Face1.vtN:getY() > 0.766 and vtO:getY() < -0.05) or @@ -968,13 +964,14 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) -- TODO qui sostituire con check topologia DoubleBevel if dAngleBetweenFaces > 10 * GEO.EPS_SMALL then -- si creano superfici singole per le facce, estese fino al box della parte - local nAddGrpId = BeamLib.GetAddGroup( Part.id) - local idFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT) - local idFace2 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT) - if not bSaveAddedGeometries then - EgtSetLevel( idFace1, GDB_LV.TEMP) - EgtSetLevel( idFace2, GDB_LV.TEMP) + local idAddGroup + if bSaveAddedGeometries then + idAddGroup = BeamLib.GetAddGroup( Part.id) + else + idAddGroup = BeamLib.GetTempGroup() end + local idFace1 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT) + local idFace2 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT) -- lavorazione facce local Machinings1, Result1 = MakeOneFace( idFace1, Part, OptionalParameters) diff --git a/Version.lua b/Version.lua index 5b1915f..113782f 100644 --- a/Version.lua +++ b/Version.lua @@ -2,5 +2,5 @@ -- Gestione della versione di Beam NAME = 'Beam' -VERSION = '2.6d1' -MIN_EXE = '2.6g1' +VERSION = '2.8a1' +MIN_EXE = '2.7j2' From 43b096f531d8b0db7501f89b684926492a1525d3 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 5 Nov 2025 11:02:02 +0100 Subject: [PATCH 14/21] - tutte le chiamate a EgtSurfTmFacetOppositeSide sostituite con i lati letti in EdgesInfo - correzioni e migliorie legate e GetBladeEngagement --- LuaLibs/FaceData.lua | 22 ----------- LuaLibs/MachiningLib.lua | 8 ++-- Strategies/Standard/STR0005/STR0005.lua | 2 +- StrategyLibs/BLADETOWASTE.lua | 10 +++-- StrategyLibs/FACEBYBLADE.lua | 50 +++++++++++++++---------- StrategyLibs/FACEBYCHAINSAW.lua | 2 +- StrategyLibs/FACEBYMILL.lua | 3 +- 7 files changed, 44 insertions(+), 53 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 39c49f7..56e969f 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -255,28 +255,6 @@ function FaceData.IsFaceParallelogram( Face) return bIsRhomboid end -------------------------------------------------------------------------------------------------------------- --- calcola l'elevazione di un lato rispetto al box passato -function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Box ) - -- recupero gruppo per geometrie temporanee - local idTempGroup = BeamLib.GetTempGroup() - - -- TODO sostituire EgtSurfTmFacetOppositeSide con punti direttamente in Edge - local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) - -- ptMid è traslato leggermente all'interno per assicurare l'intersezione con il box - local dExtraLength = 500 * GEO.EPS_SMALL - local ptMid = ( ptEdge1 + ptEdge2) / 2 + Edge.vtN * dExtraLength - local idEdgeTrimesh - - -- piano di taglio del box orientato come la normale del lato e passante da ptMid - idEdgeTrimesh = EgtSurfTmPlaneInBBox( idTempGroup, ptMid, Edge.vtN, b3Box, GDB_RT.GLOB) - - -- al calcolo dell'elevazione devo aggiungere la lunghezza di cui avevo traslato il ptMid - local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Box, true, GDB_ID.ROOT) + dExtraLength - - return dElevation -end - ------------------------------------------------------------------------------------------------------------- local function CompareEdgesBottomFace( EdgeA, EdgeB) -- prima i lati con facce adiacenti diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 9f530b5..0e3f1d7 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -330,14 +330,14 @@ end -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) -- TODO si dovrà decidere come tagliare anche in base a lavorazione di coda (spostare dopo separazione?) o pezzo corto (il motore non deve ingombrare con il pinzaggio) -- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade -function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bAvoidCollisionCheckForStandardCut) +function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bCollisionCheckForDownUpOnly) local sBladeEngagement = 'Standard' -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - if bAvoidCollisionCheckForStandardCut or not Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) then + if bCollisionCheckForDownUpOnly or not Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) then return true, sBladeEngagement end @@ -514,7 +514,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine local Part = ToolSearchParameters.Part - local bAvoidCollisionCheckForStandardCut = ToolSearchParameters.bAvoidCollisionCheckForStandardCut or false + local bCollisionCheckForDownUpOnly = ToolSearchParameters.bCollisionCheckForDownUpOnly or false local nBestToolIndex local dBestToolResidualDepth = 0 @@ -534,7 +534,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then - local bIsBladeOk = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bAvoidCollisionCheckForStandardCut) + local bIsBladeOk = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false diff --git a/Strategies/Standard/STR0005/STR0005.lua b/Strategies/Standard/STR0005/STR0005.lua index 0c5e5ac..405ffe6 100644 --- a/Strategies/Standard/STR0005/STR0005.lua +++ b/Strategies/Standard/STR0005/STR0005.lua @@ -36,7 +36,7 @@ local function IsTwoFacesCommonEdgeTooLong( Proc, Part) end -- se due facce, cubetti troppo lunghi in X non si possono fare - local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, Proc.Faces[1].id, -Proc.Faces[1].Edges[nCommonEdge].vtN, GDB_ID.ROOT) + local ptEdge1, ptEdge2 = Proc.Faces[1].Edges[nCommonEdge].ptStart, Proc.Faces[1].Edges[nCommonEdge].ptEnd local b3BoxEdge = BBox3d( ptEdge1, ptEdge2) local dEdgeLengthOnX = b3BoxEdge:getDimX() if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 1989ea3..bfb8e8c 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -433,12 +433,13 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) Part = Part }) -- ricerca lama testa sotto + -- lavorando dalla direzione opposta, faccio le verifiche come se lavorassi il lato opposto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { bAllowTopHead = false, bAllowBottomHead = true, dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, - EdgeToMachine = EdgeToMachine, + EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN), Part = Part }) @@ -451,12 +452,13 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dDepthToMachineTop = TOOLS[ToolInfoTopBlade.nToolIndex].dMaxMaterial dDepthToMachineBottom = EdgeToMachine.dElevation - dDepthToMachineTop + BeamData.CUT_EXTRA_MIN -- ricerca lama sotto con la nuova depth + -- lavorando dalla direzione opposta, faccio le verifiche come se lavorassi il lato opposto ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { bAllowTopHead = false, bAllowBottomHead = true, dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, - EdgeToMachine = EdgeToMachine, + EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN), Part = Part }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -819,7 +821,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) nToolIndex = nToolIndex, dRadialStepSpan = 0, dExtendAfterTail = dExtendAfterTail, - bAvoidCollisionCheckForStandardCut = true + bCollisionCheckForDownUpOnly = true } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) @@ -921,7 +923,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) end end -- se due facce, cubetti troppo lunghi in X non si possono fare - local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, Proc.Faces[1].id, -Proc.Faces[1].Edges[nCommonEdge].vtN, GDB_ID.ROOT) + local ptEdge1, ptEdge2 = Proc.Faces[1].Edges[nCommonEdge].ptStart, Proc.Faces[1].Edges[nCommonEdge].ptEnd local b3BoxEdge = BBox3d( ptEdge1, ptEdge2) local dEdgeLengthOnX = b3BoxEdge:getDimX() if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 30bd196..621a2c2 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -260,7 +260,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' - local bAvoidCollisionCheckForStandardCut = OptionalParameters.bAvoidCollisionCheckForStandardCut or false + local bCollisionCheckForDownUpOnly = OptionalParameters.bCollisionCheckForDownUpOnly or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -270,25 +270,15 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.vtToolDirection = EdgeToMachine.vtN end Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN - -- TODO conviene spostare questi calcoli nel FaceData? - Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) + Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd - -- ricerca utensile + -- l'utensile arriva da fuori: si determina se il taglio è fattibile e il modo di lavorare della lama if nToolIndex then + Cutting.nToolIndex = nToolIndex + Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) - -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) - - -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile - if not Cutting.bIsApplicable then - - Cutting.sMessage = 'Orientation not reachable' - EgtOutLog( Cutting.sMessage) - return Cutting, EdgeToMachine.dElevation - end - - -- si prende la lama migliore che può effettuare questo taglio, senza particolari analisi + -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else local ToolSearchParameters = {} ToolSearchParameters.dElevation = dDepthToMachine @@ -302,8 +292,30 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex Cutting.sBladeEngagement = ToolInfo.sBladeEngagement + + -- se non trovato utensile, la lavorazione non è applicabile + if not Cutting.nToolIndex then + Cutting.bIsApplicable = false + end end - if not TOOLS[Cutting.nToolIndex] then + + -- in caso di OppositeToolDirectionMode abilitata si analizza anche il lato opposto + if OppositeToolDirectionMode ~= 'Disabled' then + + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) + local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + + if not bIsApplicableOpposite then + if OppositeToolDirectionMode == 'Enabled' then + Cutting.bIsApplicable = false + elseif OppositeToolDirectionMode == 'Optimized' then + OppositeToolDirectionMode = 'Disabled' + end + end + end + + -- orientamento non raggiungibile o lama non trovata: non applicabile + if not Cutting.bIsApplicable then Cutting.sMessage = 'Blade not found' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) @@ -357,14 +369,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bAvoidCollisionCheckForStandardCut) + local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then OppositeToolDirectionMode = 'Enabled' Cutting.sBladeEngagement = sBladeEngagementOpposite Cutting.vtToolDirection = -EdgeToMachine.vtN - Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) + Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachineOpposite.ptStart, EdgeToMachineOpposite.ptEnd Cutting.bInvert = not Cutting.bInvert -- se non possibile taglio opposto, si setta per tagliare verso l'alto diff --git a/StrategyLibs/FACEBYCHAINSAW.lua b/StrategyLibs/FACEBYCHAINSAW.lua index 521c2dc..5f044fc 100644 --- a/StrategyLibs/FACEBYCHAINSAW.lua +++ b/StrategyLibs/FACEBYCHAINSAW.lua @@ -83,7 +83,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional Mortising.vtToolDirection = EdgeToMachine.vtN end Mortising.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN - Mortising.ptEdge1, _, Mortising.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Mortising.vtToolDirection, GDB_ID.ROOT) + Mortising.ptEdge1, Mortising.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd -- ricerca utensile local ToolSearchParameters = {} diff --git a/StrategyLibs/FACEBYMILL.lua b/StrategyLibs/FACEBYMILL.lua index fd5ed3d..ff40437 100644 --- a/StrategyLibs/FACEBYMILL.lua +++ b/StrategyLibs/FACEBYMILL.lua @@ -204,8 +204,7 @@ function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPara Milling.vtToolDirection = EdgeToMachine.vtN end Milling.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN - -- TODO conviene spostare questi calcoli nel FaceData? - Milling.ptEdge1, _, Milling.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Milling.vtToolDirection, GDB_ID.ROOT) + Milling.ptEdge1, Milling.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd -- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert) if nToolIndex and not dMinNzDownUp then From d8a3f257d829af0adcc748b47108fc417d16a666 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 5 Nov 2025 11:11:39 +0100 Subject: [PATCH 15/21] - in BLADETOWASTE corrette chiamate a GetEdgeToMachine --- StrategyLibs/BLADETOWASTE.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index bfb8e8c..80e3355 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -416,7 +416,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) -- se possibile, si prova il doppio taglio orizzontale con mix testa sopra/sotto (questa modalità si esclude se l'utensile arriva dall'esterno) -- TODO valutare se farlo anche doppio orizzontale solo con testa sopra, se la lama ha la corsa per andare sotto! - EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'HorizontalBottom') + EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, 'HorizontalBottom') if not nToolIndex and AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Z_AX()) then -- inizialmente si prova a lavorare in mezzeria @@ -498,7 +498,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) end -- arrivati qui si prova il taglio doppio verticale (taglio doppio orizzontale non si può fare oppure non ci arriva) - EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Vertical') + EdgeToMachine = GetEdgeToMachine( FaceToMachine.Edges, 'Vertical') local dDepthToMachine = EdgeToMachine.dElevation / 2 + BeamData.CUT_EXTRA_MIN -- ricerca lama testa sopra @@ -756,8 +756,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) -- scelta lato da lavorare per stabilire la vtToolDirection local EdgeToMachine = {} local _, Edges = FaceData.GetEdgesInfo( vCuts[i][1], 0) - local vtNCurrentFace = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT) - EdgeToMachine = GetEdgeToMachine( Edges, vtNCurrentFace, sChosenBladeType) + EdgeToMachine = GetEdgeToMachine( Edges, sChosenBladeType) vtToolDirection = EdgeToMachine.vtN end end From 6d319d17b6093c812452141f9a6099aedc860364 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 5 Nov 2025 17:38:55 +0100 Subject: [PATCH 16/21] - corretti alcuni casi in cui si calcolava il caso invertito anche se non necessario - in MachiningLib.Check2DBladeCollision esclusi i casi in cui l'utensile arriva da una direzione principale - in BLADETOWASTE.GetDualSideCutStrategy si verifica GetBladeEngagement anche per il lato opposto - in FACEBYBLADE refactoring e verifica GetBladeEngagement quando necessario --- LuaLibs/BeamExec.lua | 4 +- LuaLibs/MachiningLib.lua | 10 +++ StrategyLibs/BLADETOWASTE.lua | 12 +++- StrategyLibs/FACEBYBLADE.lua | 114 ++++++++++++++++++---------------- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index b12cc13..3259c07 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1231,7 +1231,7 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end - if bCalcBestPieceUnloadPosition then + if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then -- inversione pezzo testa-coda BeamLib.InvertRawPart( PARTS[nPart], 2) -- aggiorno info pezzo @@ -1547,7 +1547,7 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) end - if bCalcBestPieceUnloadPosition then + if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then -- inversione del pezzo testa-coda BeamLib.InvertRawPart( PARTS[nPart], 2) -- aggiorno info pezzo diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 0e3f1d7..bfc88fe 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -286,6 +286,15 @@ end ------------------------------------------------------------------------------------------------------------- -- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) + + -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica + if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) + or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) + or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then + + return false + end + local idTempGroup = BeamLib.GetTempGroup() -- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore @@ -321,6 +330,7 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT -- intersezione --local idTestSurfFr = EgtCopyGlob( idPartSurfFr, idTempGroup) + -- TODO ritornare correttamente local bCollisionFound = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) return false diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 80e3355..4c99b14 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -433,7 +433,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) Part = Part }) -- ricerca lama testa sotto - -- lavorando dalla direzione opposta, faccio le verifiche come se lavorassi il lato opposto + -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { bAllowTopHead = false, bAllowBottomHead = true, @@ -452,7 +452,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dDepthToMachineTop = TOOLS[ToolInfoTopBlade.nToolIndex].dMaxMaterial dDepthToMachineBottom = EdgeToMachine.dElevation - dDepthToMachineTop + BeamData.CUT_EXTRA_MIN -- ricerca lama sotto con la nuova depth - -- lavorando dalla direzione opposta, faccio le verifiche come se lavorassi il lato opposto + -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { bAllowTopHead = false, bAllowBottomHead = true, @@ -513,6 +513,14 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) -- se lama ci arriva si assegnano utensili e profondità da ritornare if ToolInfo.nToolIndex and ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then + + -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN) + local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[ToolInfo.nToolIndex], dDepthToMachine) + if not bIsApplicableOpposite then + return CuttingParametersList, EdgeToMachine + end + -- si deve decidere se fare per primo il taglio opposto oppure no local bIsOppositeCutFirst = false local vtTemp = EdgeToMachine.vtN ^ FaceToMachine.vtN diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 621a2c2..7b78014 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -264,13 +264,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength - if OppositeToolDirectionMode == 'Enabled' then - Cutting.vtToolDirection = -EdgeToMachine.vtN - else - Cutting.vtToolDirection = EdgeToMachine.vtN - end Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN + Cutting.vtToolDirection = EdgeToMachine.vtN Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN) -- l'utensile arriva da fuori: si determina se il taglio è fattibile e il modo di lavorare della lama if nToolIndex then @@ -299,26 +296,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end - -- in caso di OppositeToolDirectionMode abilitata si analizza anche il lato opposto - if OppositeToolDirectionMode ~= 'Disabled' then - - local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) - - if not bIsApplicableOpposite then - if OppositeToolDirectionMode == 'Enabled' then - Cutting.bIsApplicable = false - elseif OppositeToolDirectionMode == 'Optimized' then - OppositeToolDirectionMode = 'Disabled' - end - end - end - -- orientamento non raggiungibile o lama non trovata: non applicabile if not Cutting.bIsApplicable then Cutting.sMessage = 'Blade not found' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) + return Cutting, EdgeToMachine.dElevation end @@ -328,6 +311,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sMessage = 'Pocket too narrow for blade thickness' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) + return Cutting, EdgeToMachine.dElevation end -- se tasca chiusa da entrambi i lati e più stretta della lama la lavorazione non è applicabile @@ -336,6 +320,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sMessage = 'Pocket too narrow for blade diameter' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) + return Cutting, EdgeToMachine.dElevation end end @@ -358,47 +343,48 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.bInvert = false end - -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità) - if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceParallelogram( FaceToMachine)) then + -- analisi fattibilità lavorazione dal lato opposto + if OppositeToolDirectionMode ~= 'Disabled' then - OppositeToolDirectionMode = 'Disabled' + -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto + local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) - -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza - if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) - or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then + -- taglio opposto non fattibile + if not bIsApplicableOpposite then + -- se richiesto, si ritorna non applicabile + if OppositeToolDirectionMode == 'Enabled' then - -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta - local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + Cutting.sMessage = 'Orientation not reachable' + Cutting.bIsApplicable = false + EgtOutLog( Cutting.sMessage) - if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then - - OppositeToolDirectionMode = 'Enabled' - Cutting.sBladeEngagement = sBladeEngagementOpposite - Cutting.vtToolDirection = -EdgeToMachine.vtN - Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachineOpposite.ptStart, EdgeToMachineOpposite.ptEnd - Cutting.bInvert = not Cutting.bInvert - - -- se non possibile taglio opposto, si setta per tagliare verso l'alto - else - if Cutting.nWorkside == MCH_MILL_WS.RIGHT then - Cutting.nWorkside = MCH_MILL_WS.LEFT - Cutting.bInvert = false - else - Cutting.nWorkside = MCH_MILL_WS.RIGHT - Cutting.bInvert = true - end + return Cutting, EdgeToMachine.dElevation + + -- se opzionale, si disabilita + elseif OppositeToolDirectionMode == 'Optimized' then + OppositeToolDirectionMode = 'Disabled' end end - elseif OppositeToolDirectionMode == 'Enabled' then - Cutting.bInvert = not Cutting.bInvert - end + -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità) + if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceParallelogram( FaceToMachine)) then - -- ToolInvert - if Cutting.sBladeEngagement == 'DownUp' then - Cutting.bToolInvert = true - Cutting.bInvert = not Cutting.bInvert + OppositeToolDirectionMode = 'Disabled' + + -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza + if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) + or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then + + OppositeToolDirectionMode = 'Enabled' + Cutting.sBladeEngagement = sBladeEngagementOpposite + end + end + + if OppositeToolDirectionMode == 'Enabled' then + Cutting.vtToolDirection = EdgeToMachineOpposite.vtN + Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachineOpposite.ptStart, EdgeToMachineOpposite.ptEnd + Cutting.bInvert = not Cutting.bInvert + end end -- profondità da lavorare e offset radiale @@ -429,6 +415,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar and ( Proc.nFct == 1) and FaceData.IsFaceRectangle( FaceToMachine) then + -- TODO la lama sotto deve poter ridurre. Ghigliottina sì o no? local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachine.dLength) @@ -444,6 +431,21 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end end + + -- si ritesta la fattibilità del taglio con le nuove profondità + local EdgeToMachineForEngagement = EdgeToMachine + if OppositeToolDirectionMode == 'Enabled' then + EdgeToMachineForEngagement = EdgeToMachineOpposite + end + local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[nToolIndex], dDepthToMachine) + if bIsApplicable then + Cutting.sBladeEngagement = sBladeEngagement + else + Cutting.sEdgeUsage = 'Standard' + dDepthToMachine = Cutting.dDepthToMachine + end + + -- offset radiale (cambia se taglio opposto) if OppositeToolDirectionMode == 'Enabled' then Cutting.dRadialOffset = -dDepthToMachine else @@ -451,6 +453,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end + -- ToolInvert + if Cutting.sBladeEngagement == 'DownUp' then + Cutting.bToolInvert = true + Cutting.bInvert = not Cutting.bInvert + end + -- completamento Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100 From 15db75dfadc445838b69205fecc72b03c02a8f47 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 5 Nov 2025 18:56:02 +0100 Subject: [PATCH 17/21] =?UTF-8?q?-=20in=20FACEBYBLADE=20correzioni=20a=20c?= =?UTF-8?q?hiamata=20Cutting.nToolIndex=20-=20in=20MachiningLib.Check2DBla?= =?UTF-8?q?deCollision=20ora=20si=20controlla=20correttamente=20se=20c'?= =?UTF-8?q?=C3=A8=20intersezione?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/MachiningLib.lua | 18 +++++++++++++----- StrategyLibs/FACEBYBLADE.lua | 12 ++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index bfc88fe..17fee4b 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -320,6 +320,7 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness end -- TODO qui sostituire con il valore reale letto dal SetupInfo + -- per Fast si dovrà aggiungere la lunghezza del massimo utensile utilizzabile con lama local dHeadDepth = 480 local dHeadWidth = 480 local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth @@ -328,12 +329,19 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT -- flat region dal rettangolo local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle) - -- intersezione - --local idTestSurfFr = EgtCopyGlob( idPartSurfFr, idTempGroup) - -- TODO ritornare correttamente - local bCollisionFound = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) + -- intersezione (se fallisce si inverte la flat region del motore, probabile normale opposta) + local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) + if not bIntersectSuccess then + EgtInvertSurf( idHeadSurfFr) + bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) + end + if not bIntersectSuccess then + error( 'Check2DBladeCollision : intersect fail') + end - return false + local bCollisionFound = EgtExistsObj( idPartSurfFr) + + return bCollisionFound end ------------------------------------------------------------------------------------------------------------- diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 7b78014..f1a762e 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -273,7 +273,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if nToolIndex then Cutting.nToolIndex = nToolIndex - Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else @@ -347,7 +347,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode ~= 'Disabled' then -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto - local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) -- taglio opposto non fattibile if not bIsApplicableOpposite then @@ -416,9 +416,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar and FaceData.IsFaceRectangle( FaceToMachine) then -- TODO la lama sotto deve poter ridurre. Ghigliottina sì o no? - local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop - Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC - Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachine.dLength) + local bIsTopBlade = TOOLS[Cutting.nToolIndex].SetupInfo.HeadType.bTop + Cutting.dMaxRadialOffset = TOOLS[Cutting.nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC + Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( Cutting.nToolIndex, EdgeToMachine.dLength) if Cutting.dMaxRadialOffset > 10 * GEO.EPS_SMALL then -- taglio a ghigliottina if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine < Cutting.dMaxRadialOffset - 10 * GEO.EPS_SMALL) then @@ -437,7 +437,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode == 'Enabled' then EdgeToMachineForEngagement = EdgeToMachineOpposite end - local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[nToolIndex], dDepthToMachine) + local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) if bIsApplicable then Cutting.sBladeEngagement = sBladeEngagement else From 4ce77a479249783d2948c2ec00e3baa75d735e82 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 7 Nov 2025 10:15:01 +0100 Subject: [PATCH 18/21] =?UTF-8?q?-=20in=20MachiningLib.FindBlade=20si=20re?= =?UTF-8?q?stituisce=20il=20BladeEngagement,=20se=20presente=20-=20in=20BL?= =?UTF-8?q?ADETOWASTE.GetEdgeToMachine=20aggiunta=20la=20possibilit=C3=A0?= =?UTF-8?q?=20di=20restituire=20l'n-esimo=20lato=20della=20lista=20ordinat?= =?UTF-8?q?a;=20in=20GetSingleCutStrategy=20si=20tenta=20di=20cambiare=20l?= =?UTF-8?q?ato=20se=20il=20con=20il=20primo=20set=20non=20si=20=C3=A8=20tr?= =?UTF-8?q?ovato=20alcun=20utensile;=20altre=20piccole=20correzioni=20-=20?= =?UTF-8?q?in=20FACEBYBLADE=20refactoring=20per=20contemplare=20i=20vari?= =?UTF-8?q?=20casi=20di=20inversione?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/MachiningLib.lua | 16 +++++++-- StrategyLibs/BLADEKEEPWASTE.lua | 1 + StrategyLibs/BLADETOWASTE.lua | 61 +++++++++++++++++++++++---------- StrategyLibs/FACEBYBLADE.lua | 43 +++++++++++++---------- 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 17fee4b..3ab9cfc 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -369,8 +369,9 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- rischio collisione carro Z: non lavorabile in Downup - local bIsToolBelowWorkpiece = Edge.vtN:getZ() < - 10 * GEO.EPS_SMALL - local bIsToolAboveWorkpiece = Edge.vtN:getZ() > 10 * GEO.EPS_SMALL + -- TODO questo test è da spostare sulla macchina, non è universale + local bIsToolBelowWorkpiece = Edge.vtN:getZ() < - 0.5 + local bIsToolAboveWorkpiece = Edge.vtN:getZ() > 0.5 if Tool.SetupInfo.HeadType.bTop and bIsToolBelowWorkpiece or ( Tool.SetupInfo.HeadType.bBottom and bIsToolAboveWorkpiece) then @@ -536,6 +537,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local nBestToolIndex local dBestToolResidualDepth = 0 + local sCurrentBladeEngagement + local sBestBladeEngagement for i = 1, #TOOLS do local bIsToolCompatible = false @@ -552,7 +555,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then - local bIsBladeOk = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) + local bIsBladeOk = false + bIsBladeOk, sCurrentBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false @@ -577,11 +581,13 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL) then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth + sBestBladeEngagement = sCurrentBladeEngagement else -- prediligo utensile per tagli lungo vena, se richiesto if bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth + sBestBladeEngagement = sCurrentBladeEngagement else -- entrambi completi if dBestToolResidualDepth <= 10 * GEO.EPS_SMALL and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL then @@ -592,11 +598,13 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) GetIndexToolInAvailableToolList( ToolSearchParameters.AvailableToolList, TOOLS[nBestToolIndex].sName) then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth + sBestBladeEngagement = sCurrentBladeEngagement end -- si sceglie quello con le performance migliori elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex + 10 * GEO.EPS_SMALL then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth + sBestBladeEngagement = sCurrentBladeEngagement end -- entrambi incompleti elseif dBestToolResidualDepth > 10 * GEO.EPS_SMALL and dCurrentResidualDepth > 10 * GEO.EPS_SMALL then @@ -604,6 +612,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if dCurrentResidualDepth > dBestToolResidualDepth then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth + sBestBladeEngagement = sCurrentBladeEngagement end end end @@ -613,6 +622,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) ToolInfo.nToolIndex = nBestToolIndex ToolInfo.dResidualDepth = dBestToolResidualDepth + ToolInfo.sBladeEngagement = sBestBladeEngagement return ToolInfo end diff --git a/StrategyLibs/BLADEKEEPWASTE.lua b/StrategyLibs/BLADEKEEPWASTE.lua index b39a87d..0c5409b 100644 --- a/StrategyLibs/BLADEKEEPWASTE.lua +++ b/StrategyLibs/BLADEKEEPWASTE.lua @@ -119,6 +119,7 @@ end function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) -- TODO verificare funzionamento con lama da sotto + -- TODO scelta utensile è corretto lasciarla a FaceByBlade? -- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????) -- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 4c99b14..b4b7e0f 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -204,9 +204,14 @@ local function CompareEdgesNoPreference( EdgeA, EdgeB) end -local function GetEdgeToMachine( Edges, sBladeType, bAllowFastCuts) +local function GetEdgeToMachine( Edges, sBladeType, OptionalParameters) local EdgeToMachine = {} + -- parametri opzionali + OptionalParameters = OptionalParameters or {} + local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false + local nIndex = OptionalParameters.nIndex or 1 + local EdgesSorted = {} for i = 1, #Edges do table.insert( EdgesSorted, Edges[i]) @@ -218,23 +223,23 @@ local function GetEdgeToMachine( Edges, sBladeType, bAllowFastCuts) else table.sort( EdgesSorted, CompareEdgesTopHead) end - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] elseif sBladeType == 'Bottom' then table.sort( EdgesSorted, CompareEdgesBottomHead) - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] elseif sBladeType == 'TopGuillotine' then table.sort( EdgesSorted, CompareEdgesTopHeadGuillotine) - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] elseif sBladeType == 'HorizontalBottom' then table.sort( EdgesSorted, CompareEdgesHorizontalBottom) - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] elseif sBladeType == 'Vertical' then table.sort( EdgesSorted, CompareEdgesVertical) - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] -- TODO non testato; non si dovrebbe mai entrare in questo caso else table.sort( EdgesSorted, CompareEdgesNoPreference) - EdgeToMachine = EdgesSorted[1] + EdgeToMachine = EdgesSorted[nIndex] end return EdgeToMachine @@ -357,24 +362,44 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1] -- lati da lavorare in base al tipo di lama - -- se non arrivano dall'esterno si cercano i migliori disponibili + -- se non arrivano dall'esterno si cercano i migliori disponibili, dapprima ignorando il flag bAllowFastCuts local EdgeToMachineList = OptionalParameters.EdgeToMachineList or { - Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', bAllowFastCuts), - Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', bAllowFastCuts), - TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, 'TopGuillotine', bAllowFastCuts) + Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top'), + Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom'), + TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, 'TopGuillotine') } local sChosenBladeType - -- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato local OptionalParametersGetBestBlade = { EdgeToMachineTop = EdgeToMachineList.Top, EdgeToMachineBottom = EdgeToMachineList.Bottom, nToolIndex = nToolIndex } + -- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + -- se non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, si prova a cambiare lato (si prende il secondo della lista), sempre ignorando bAllowFastCuts + if not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then + EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { nIndex = 2}) + EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { nIndex = 2}) + OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top + OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom + + nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + end + + -- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il lato "veloce" (bAllowFastCuts) + if bAllowFastCuts and not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then + EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { bAllowFastCuts = true}) + EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { bAllowFastCuts = true}) + OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top + OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom + + nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + end + -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangle( FaceToMachine) then local nToolIndexGuillotine @@ -384,7 +409,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) bAllowTopHead = true, bAllowBottomHead = false, FaceToMachine = FaceToMachine, - EdgeToMachine = EdgeToMachineList.Top, + EdgeToMachine = EdgeToMachineList.TopGuillotine, Part = Part }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -590,7 +615,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) -- se taglio da un lato non ce la fa, si prova da due lati - -- TODO valutare se estendere ai non parallelogrammi + -- TODO valutare se deve funzionare solo per i rettangoli elseif FaceData.IsFaceParallelogram( Proc.Faces[1]) then local CuttingParametersList @@ -798,9 +823,6 @@ local function CutWithDicing( Proc, Part, OptionalParameters) -- caso standard (tagli perpendicolari o paralleli non accorpabili) if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then for j = 1, #vCuts[i] do - local Cutting = {} - local vtNCurrentFace = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) - local FaceToMachine = { id = 0, vtN = vtNCurrentFace} -- in generale sta sollevato di pochissimo local dExtraCut = -0.1 -- se tagli paralleli @@ -819,9 +841,10 @@ local function CutWithDicing( Proc, Part, OptionalParameters) end end end + local Cutting = {} local ProcTrimesh = FeatureLib.GetProcFromTrimesh( vCuts[i][j], Part) - local _, Edges = FaceData.GetEdgesInfo( vCuts[i][j], 0) - local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( Edges, vtToolDirection) + local FaceToMachine = ProcTrimesh.Faces[1] + local EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, vtToolDirection) local dDepthToMachine = EdgeToMachine.dElevation + dExtraCut local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index f1a762e..cd94b20 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -343,6 +343,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.bInvert = false end + -- ToolInvert + if Cutting.sBladeEngagement == 'DownUp' then + Cutting.bToolInvert = true + Cutting.bInvert = not Cutting.bInvert + end + -- analisi fattibilità lavorazione dal lato opposto if OppositeToolDirectionMode ~= 'Disabled' then @@ -372,11 +378,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar OppositeToolDirectionMode = 'Disabled' -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza - if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) + -- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione + if ( sBladeEngagementOpposite == Cutting.sBladeEngagement) + and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then OppositeToolDirectionMode = 'Enabled' - Cutting.sBladeEngagement = sBladeEngagementOpposite end end @@ -422,8 +429,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if Cutting.dMaxRadialOffset > 10 * GEO.EPS_SMALL then -- taglio a ghigliottina if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine < Cutting.dMaxRadialOffset - 10 * GEO.EPS_SMALL) then + dDepthToMachine = Cutting.dDepthToMachine + Cutting.dRadialOffsetGuillotine Cutting.sEdgeUsage = 'Guillotine' + -- taglio ridotto else dDepthToMachine = Cutting.dDepthToMachine + Cutting.dMaxRadialOffset @@ -432,17 +441,19 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end - -- si ritesta la fattibilità del taglio con le nuove profondità - local EdgeToMachineForEngagement = EdgeToMachine - if OppositeToolDirectionMode == 'Enabled' then - EdgeToMachineForEngagement = EdgeToMachineOpposite - end - local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) - if bIsApplicable then - Cutting.sBladeEngagement = sBladeEngagement - else - Cutting.sEdgeUsage = 'Standard' - dDepthToMachine = Cutting.dDepthToMachine + -- se cambiata la profondità dDepthToMachine, si ritesta la fattibilità del taglio + if Cutting.sEdgeUsage ~= 'Standard' then + local EdgeToMachineForEngagement = EdgeToMachine + if OppositeToolDirectionMode == 'Enabled' then + EdgeToMachineForEngagement = EdgeToMachineOpposite + end + local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) + + -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce + if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement)) then + Cutting.sEdgeUsage = 'Standard' + dDepthToMachine = Cutting.dDepthToMachine + end end -- offset radiale (cambia se taglio opposto) @@ -453,12 +464,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end - -- ToolInvert - if Cutting.sBladeEngagement == 'DownUp' then - Cutting.bToolInvert = true - Cutting.bInvert = not Cutting.bInvert - end - -- completamento Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100 From 711ac3930d459e5fa748efc452c3c7e0a1ddd602 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 7 Nov 2025 15:41:06 +0100 Subject: [PATCH 19/21] - in FaceData corretta assegnazione ptStart e ptEnd nei MainEdges - in FeatureLib.GetAdditionalInfo gestita correttamente 61 (Text) --- LuaLibs/BeamExec.lua | 2 ++ LuaLibs/DiceCut.lua | 1 + LuaLibs/FaceData.lua | 6 ++++++ LuaLibs/FeatureLib.lua | 2 +- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 3259c07..bd24d0a 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -716,6 +716,7 @@ local function AreDrillingsMirrored( Proc, ProcMirror, Part) if AreOppositeVectorApprox( vtExtr, vtExtrMirror) then -- fori lungo Y -- per macchine tipo PF il foro principale è sul lato back, per macchine tipo PF1250 è sul lato front + -- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste? if ( BeamData.TWO_EQUAL_HEADS and AreSameVectorApprox( vtExtr, Y_AX())) or ( BeamData.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then nDouble = 2 @@ -792,6 +793,7 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part) Proc.bPassedByHole = true end -- verifiche per specchiature + -- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste? if BeamData.DOWN_HEAD or BeamData.TWO_EQUAL_HEADS then -- forature if BeamData.DOUBLE_HEAD_DRILLING and ID.IsDrill( Proc) and ID.IsDrill( ProcB) and not Proc.Mirror then diff --git a/LuaLibs/DiceCut.lua b/LuaLibs/DiceCut.lua index 7b0bde2..00e9457 100644 --- a/LuaLibs/DiceCut.lua +++ b/LuaLibs/DiceCut.lua @@ -450,6 +450,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) -- TODO parte sotto da aggiungere???? se sì va passata anche la dimensione cubetto ridotta dOffsetOrthogonalReduced -- se non c'è testa da sotto e normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + -- TODO eliminare i riferimenti a DOWN_HEAD e TWO_EQUAL_HEADS e sostituirli con check iniziale sulla disponibilità di teste? -- if not BD.TURN and not BD.DOWN_HEAD and abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then -- dOffsetOrthogonal = dOffsetOrthogonalReduced -- end diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 56e969f..aeae3be 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -426,6 +426,8 @@ local function GetBottomFaces( Proc) CurrentEdge.dElevation = BottomFaces[1].Edges[i].dElevation CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[i].bIsStartOpen CurrentEdge.bIsEndOpen = BottomFaces[1].Edges[i].bIsEndOpen + CurrentEdge.ptStart = BottomFaces[1].Edges[i].ptStart + CurrentEdge.ptEnd = BottomFaces[1].Edges[i].ptEnd if nFirstLongEdgeIndex then if i == nFirstLongEdgeIndex then @@ -521,6 +523,8 @@ local function GetLongFaces( Proc, MainFaces) CurrentEdge.dElevation = LongFaces[i].Edges[j].dElevation CurrentEdge.bIsStartOpen = LongFaces[i].Edges[j].bIsStartOpen CurrentEdge.bIsEndOpen = LongFaces[i].Edges[j].bIsEndOpen + CurrentEdge.ptStart = LongFaces[i].Edges[j].ptStart + CurrentEdge.ptEnd = LongFaces[i].Edges[j].ptEnd if Proc.Topology.sFamily == 'Tunnel' then if CurrentEdge.idAdjacentFace > -1 then @@ -617,6 +621,8 @@ local function GetSideFaces( Proc, MainFaces) CurrentEdge.dElevation = SideFaces[i].Edges[j].dElevation CurrentEdge.bIsStartOpen = SideFaces[i].Edges[j].bIsStartOpen CurrentEdge.bIsEndOpen = SideFaces[i].Edges[j].bIsEndOpen + CurrentEdge.ptStart = SideFaces[i].Edges[j].ptStart + CurrentEdge.ptEnd = SideFaces[i].Edges[j].ptEnd if Proc.Topology.sFamily == 'Tunnel' then if CurrentEdge.idAdjacentFace > -1 then diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 28a9c4c..2c6886c 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -323,7 +323,7 @@ function FeatureLib.GetAdditionalInfo( Proc, Part) elseif ID.IsRidgeLap( Proc) then Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) Proc.Faces = FaceData.GetFacesInfo( Proc, Part) - elseif ID.IsMarking( Proc) then + elseif ID.IsMarking( Proc) or ID.IsText( Proc) then Proc.FeatureInfo = FeatureLib.GetMarkTextData( Proc) elseif ID.IsHipValleyRafterNotch( Proc) then Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) From 8f2a09e5c78255e3d0c4c6e6f58c59b9a2707ed6 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 11 Nov 2025 12:12:00 +0100 Subject: [PATCH 20/21] =?UTF-8?q?-=20in=20BLADEKEEPWASTE,=20se=20lavorazio?= =?UTF-8?q?ne=20fallisce=20da=20un=20lato,=20si=20fa=20codolo=20tutto=20da?= =?UTF-8?q?=20un=20lato=20alla=20massima=20profondit=C3=A0=20-=20in=20BLAD?= =?UTF-8?q?ETOWASTE.CutWholeWaste,=20se=20fallisce=20il=20taglio=20doppio,?= =?UTF-8?q?=20si=20verificano=20i=20lati=20a=20minor=20elevazione=20Machin?= =?UTF-8?q?ingLib.GetBladeEngagement=20si=20restituisce=20anche=20se=20la?= =?UTF-8?q?=20lavorazione=20richiede=20separazione,=20verificata=20in=20Ch?= =?UTF-8?q?eck2DBladeCollision=20-=20in=20FACEBYBLADE=20gestita=20forzatur?= =?UTF-8?q?a=20dopo=20split=20dall'esterno=20-=20in=20BatchProcessNew=20e?= =?UTF-8?q?=20Process=20si=20restituisce=20sempre=20sMsg,=20anche=20se=20f?= =?UTF-8?q?eature=20completa=20-=20in=20FaceData=20rimosso=20logging=20Mai?= =?UTF-8?q?nFaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BatchProcessNew.lua | 2 +- LuaLibs/FaceData.lua | 4 -- LuaLibs/MachiningLib.lua | 61 +++++++++++++++++++++---- Process.lua | 2 +- Strategies/Standard/STR0005/STR0005.lua | 3 +- StrategyLibs/BLADEKEEPWASTE.lua | 48 +++++++++++++++---- StrategyLibs/BLADETOWASTE.lua | 43 +++++++++++++++-- StrategyLibs/FACEBYBLADE.lua | 14 ++++-- 8 files changed, 141 insertions(+), 36 deletions(-) diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 04f5a8e..62f6506 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -673,7 +673,7 @@ if bToProcess then -- trovata almeno una strategia e feature lavorata completamente if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then BEAM.ERR = 0 - BEAM.MSG = '---' + BEAM.MSG = sMsg or '' BEAM.ROT = -( RESULT[i].nRotation or 1) + 1 BEAM.CUTID = RESULT[i].idCut BEAM.TASKID = RESULT[i].idTask diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index aeae3be..3013d82 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -674,10 +674,6 @@ function FaceData.GetMainFaces( Proc, Part) MainFaces.LongFaces = GetLongFaces( Proc, MainFaces) MainFaces.SideFaces = GetSideFaces( Proc, MainFaces) - -- scrivo informazioni delle facce nel log - if EgtGetDebugLevel() >= 3 then - Logs.WriteMainFacesLog( Proc, MainFaces) - end else MainFaces = nil EgtOutLog( '---MainFaces NOT NEEDED---') diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 3ab9cfc..51c5c1e 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -271,11 +271,11 @@ end -- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per la lavorazione scelta (per DownUp passare vtNFace opposta) local function IsFaceZOutOfRange ( vtNFace, Tool) - -- lama sotto: angolo negativo troppo basso + -- lama sopra: angolo negativo troppo basso if Tool.SetupInfo.HeadType.bTop and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then return true end - -- lama sopra: angolo positivo troppo elevato + -- lama sotto: angolo positivo troppo elevato if Tool.SetupInfo.HeadType.bBottom and vtNFace:getZ() > Tool.SetupInfo.GetMaxNz( vtNFace, Tool) + GEO.EPS_ZERO then return true end @@ -312,6 +312,22 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT -- creazione flat region dalla silhouette local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) + -- costruzione flat region del grezzo restante nel piano perpendicolare al taglio + -- si costruisce il box in globale + local ptRestLengthMax = Point3d( Part.b3Part:getMin() + X_AX() * 500 * GEO.EPS_SMALL) + local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) + -- si crea la trimesh dal box + local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB) + -- si estrae la silhouette nel piano + idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'Check2DBladeCollision : error in part box') + end + -- creazione flat region dalla silhouette + local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) + -- costruzione flat region approssimata del motore nel piano perpendicolare al taglio -- punto di congiunzione tra motore e lama local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial @@ -329,7 +345,7 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT -- flat region dal rettangolo local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle) - -- intersezione (se fallisce si inverte la flat region del motore, probabile normale opposta) + -- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta) local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) if not bIntersectSuccess then EgtInvertSurf( idHeadSurfFr) @@ -339,9 +355,24 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT error( 'Check2DBladeCollision : intersect fail') end - local bCollisionFound = EgtExistsObj( idPartSurfFr) + local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) - return bCollisionFound + -- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione + local bCollisionFoundRestLength + if not bCollisionFoundPiece then + bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr) + if not bIntersectSuccess then + EgtInvertSurf( idHeadSurfFr) + bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr) + end + if not bIntersectSuccess then + error( 'Check2DBladeCollision : intersect fail') + end + + bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr) + end + + return bCollisionFoundPiece, bCollisionFoundRestLength end ------------------------------------------------------------------------------------------------------------- @@ -355,9 +386,10 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - if bCollisionCheckForDownUpOnly or not Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) then + local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + if bCollisionCheckForDownUpOnly or not bCollisionFound then - return true, sBladeEngagement + return true, sBladeEngagement, bMoveAfterSplit end end @@ -380,11 +412,12 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- orientamento faccia / utensile compatibili con DownUp: lavorabile - if not Check2DBladeCollision( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) then + local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + if not bCollisionFound then sBladeEngagement = 'DownUp' - return true, sBladeEngagement + return true, sBladeEngagement, bMoveAfterSplit end return false @@ -539,6 +572,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local dBestToolResidualDepth = 0 local sCurrentBladeEngagement local sBestBladeEngagement + local bCurrentMoveAfterSplit + local bBestMoveAfterSplit for i = 1, #TOOLS do local bIsToolCompatible = false @@ -556,7 +591,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then local bIsBladeOk = false - bIsBladeOk, sCurrentBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) + bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false @@ -582,12 +617,14 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth sBestBladeEngagement = sCurrentBladeEngagement + bBestMoveAfterSplit = bCurrentMoveAfterSplit else -- prediligo utensile per tagli lungo vena, se richiesto if bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth sBestBladeEngagement = sCurrentBladeEngagement + bBestMoveAfterSplit = bCurrentMoveAfterSplit else -- entrambi completi if dBestToolResidualDepth <= 10 * GEO.EPS_SMALL and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL then @@ -599,12 +636,14 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth sBestBladeEngagement = sCurrentBladeEngagement + bBestMoveAfterSplit = bCurrentMoveAfterSplit end -- si sceglie quello con le performance migliori elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex + 10 * GEO.EPS_SMALL then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth sBestBladeEngagement = sCurrentBladeEngagement + bBestMoveAfterSplit = bCurrentMoveAfterSplit end -- entrambi incompleti elseif dBestToolResidualDepth > 10 * GEO.EPS_SMALL and dCurrentResidualDepth > 10 * GEO.EPS_SMALL then @@ -613,6 +652,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth sBestBladeEngagement = sCurrentBladeEngagement + bBestMoveAfterSplit = bCurrentMoveAfterSplit end end end @@ -623,6 +663,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) ToolInfo.nToolIndex = nBestToolIndex ToolInfo.dResidualDepth = dBestToolResidualDepth ToolInfo.sBladeEngagement = sBestBladeEngagement + ToolInfo.bMoveAfterSplit = bBestMoveAfterSplit return ToolInfo end diff --git a/Process.lua b/Process.lua index b67d4d9..f89550b 100644 --- a/Process.lua +++ b/Process.lua @@ -320,7 +320,7 @@ local function MyProcessFeatures() sMsg = string.gsub( sMsg or '', '\r', ' ', 10) -- trovata almeno una strategia e feature lavorata completamente if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then - -- nulla da segnalare + sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '') -- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia elseif RESULT[i].sType == 'Feature' diff --git a/Strategies/Standard/STR0005/STR0005.lua b/Strategies/Standard/STR0005/STR0005.lua index 405ffe6..9fe8b74 100644 --- a/Strategies/Standard/STR0005/STR0005.lua +++ b/Strategies/Standard/STR0005/STR0005.lua @@ -111,13 +111,14 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) or bKeepWasteAttached then local BladeKeepWasteResult - local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth} + local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth, bForced = bKeepWasteAttached} AuxiliaryData.bIgnoreNotClampableLength = true Blade.Result, BladeKeepWasteResult = BladeKeepWaste.Make( Proc, Part, OptionalParameters) dTimeToMachine = BladeKeepWasteResult.dTimeToMachine dMRRBlade = BladeKeepWasteResult.dMRR dCompletionPercentage = BladeKeepWasteResult.dCompletionPercentage dQuality = BladeKeepWasteResult.dQuality + Strategy.Result.sInfo = BladeKeepWasteResult.sInfo or '' end -- lavorazione a cubetti / taglio singolo diff --git a/StrategyLibs/BLADEKEEPWASTE.lua b/StrategyLibs/BLADEKEEPWASTE.lua index 0c5409b..9ac4d8b 100644 --- a/StrategyLibs/BLADEKEEPWASTE.lua +++ b/StrategyLibs/BLADEKEEPWASTE.lua @@ -11,6 +11,7 @@ require( 'EgtBase') local FeatureLib = require( 'FeatureLib') local FaceData = require( 'FaceData') local MachiningLib = require( 'MachiningLib') +local BeamLib = require('BeamLib') -- strategie di base local FaceByBlade = require('FACEBYBLADE') local FaceByMill = require('FACEBYMILL') @@ -121,7 +122,6 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) -- TODO verificare funzionamento con lama da sotto -- TODO scelta utensile è corretto lasciarla a FaceByBlade? -- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????) - -- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo) local Result = {} local Machinings = {} @@ -172,6 +172,8 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) bFinishWithMill = OptionalParameters.bFinishWithMill end local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1 + local dStripWidth = OptionalParameters.dStripWidth or 5 + local bForced = OptionalParameters.bForced or false -- volume della feature local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part) @@ -218,19 +220,41 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) end -- taglio con codolo faccia di fondo - local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - OptionalParameters.dStripWidth / 2 - local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} + local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - dStripWidth / 2 + local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} -- primo lato - Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade) + Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1) Cutting1.nInternalSortingPriority = 3 Cutting1.dResultWeight = 0.3 - table.insert( CalculatedMachinings, Cutting1) + -- secondo lato - OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Enabled' - Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade) + local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1) + OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled' + Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2) Cutting2.nInternalSortingPriority = 3 Cutting2.dResultWeight = 0.3 - table.insert( CalculatedMachinings, Cutting2) + + -- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto + if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then + + dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth) + OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine + + Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2) + table.insert( CalculatedMachinings, Cutting2) + + elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then + + dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth) + OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine + + Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1) + table.insert( CalculatedMachinings, Cutting1) + + else + table.insert( CalculatedMachinings, Cutting1) + table.insert( CalculatedMachinings, Cutting2) + end -- fresatura eventuali facce di chiusura if bFinishWithMill then @@ -254,8 +278,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) end end - -- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili - Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings) + -- calcolo completamento (non applicabili devono essere incluse) + -- se codolo non forzato si ritorna completa solo al 94% (completion index 4) + Result.dCompletionPercentage = bForced and GetStrategyCompletionPercentage( CalculatedMachinings) or 94 Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage) -- aggiunta eventuali lavorazioni splittate @@ -273,6 +298,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) if Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Result.sStatus = 'Completed' + if bForced then + Result.sInfo = 'Waste attached. Remove manually.' + end else Result.sStatus = 'Not-Completed' end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index b4b7e0f..b9f6128 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -390,7 +390,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) end - -- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il lato "veloce" (bAllowFastCuts) + -- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il primo lato a minor elevazione (bAllowFastCuts) if bAllowFastCuts and not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { bAllowFastCuts = true}) EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { bAllowFastCuts = true}) @@ -400,6 +400,17 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) end + + -- se ancora non è stato trovato un utensile e utensile e lati non arrivavano dall'esterno, se permesso, si prova a scegliere il secondo lato a minor elevazione (bAllowFastCuts) + if bAllowFastCuts and not nToolIndex and not OptionalParameters.nToolIndex and not OptionalParameters.EdgeToMachineList then + EdgeToMachineList.Top = GetEdgeToMachine( FaceToMachine.Edges, 'Top', { bAllowFastCuts = true, nIndex = 2}) + EdgeToMachineList.Bottom = GetEdgeToMachine( FaceToMachine.Edges, 'Bottom', { bAllowFastCuts = true, nIndex = 2}) + OptionalParametersGetBestBlade.EdgeToMachineTop = EdgeToMachineList.Top + OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom + + nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + end + -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangle( FaceToMachine) then local nToolIndexGuillotine @@ -645,6 +656,30 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) end end + -- se nessun taglio è riuscito si riprova il taglio singolo permettendo i lati a minor elevazione, abbassando la qualità + if not ( Cutting and Cutting.bIsApplicable) or not ( CuttingDouble and CuttingDouble.bIsApplicable) then + + OptionalParameters.bAllowFastCuts = true + nToolIndex, EdgeToMachine, sChosenBladeType = GetSingleCutStrategy( Proc, Part, OptionalParameters) + + if nToolIndex then + local OptionalParametersFaceByBlade = { + dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA, + nToolIndex = nToolIndex, + dExtendAfterTail = dExtendAfterTail, + bReduceBladePath = bReduceBladePath + } + if sChosenBladeType == 'Top' or sChosenBladeType == 'Bottom' then + OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' + end + + Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) + end + + -- si abbassa la qualità per le possibili scheggiature + Result.dQuality = FeatureLib.GetStrategyQuality( 'STD') + end + if Cutting and Cutting.bIsApplicable then table.insert( Machinings, Cutting) dCompletionPercentage = Cutting.dCompletionPercentage or dCompletionPercentage @@ -665,7 +700,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) end Result.dCompletionPercentage = dCompletionPercentage Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage) - Result.dQuality = FeatureLib.GetStrategyQuality( Machinings) + Result.dQuality = Result.dQuality or FeatureLib.GetStrategyQuality( Machinings) Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) else @@ -1050,10 +1085,10 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) end -- feature concava >= 90deg: lavorata con cubetti, se attivi - elseif ( not bDisableDicing) and ( dAngleBetweenFaces >= -91) then + elseif not ( bDisableDicing or FeatureInfo.bIsFeatureSmall) and ( dAngleBetweenFaces >= -91) then Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters) - -- qui arrivano feature concave < 90deg, oppure >= 90deg con cubetti disabilitati: lavorata come 2 facce singole con accorciamento + -- qui arrivano feature concave < 90deg, oppure >= 90deg con cubetti disabilitati: lavorata come 2 facce singole con eventuale accorciamento else -- per ogni faccia si calcola la lavorazione for i = 1, #Proc.Faces do diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index cd94b20..e87380c 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -273,7 +273,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if nToolIndex then Cutting.nToolIndex = nToolIndex - Cutting.bIsApplicable, Cutting.sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else @@ -289,6 +289,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex Cutting.sBladeEngagement = ToolInfo.sBladeEngagement + Cutting.bMoveAfterSplit = ToolInfo.bMoveAfterSplit -- se non trovato utensile, la lavorazione non è applicabile if not Cutting.nToolIndex then @@ -353,7 +354,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode ~= 'Disabled' then -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto - local bIsApplicableOpposite, sBladeEngagementOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) -- taglio opposto non fattibile if not bIsApplicableOpposite then @@ -380,6 +381,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza -- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione if ( sBladeEngagementOpposite == Cutting.sBladeEngagement) + and ( bMoveAfterSplit == Cutting.MoveAfterSplit) and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then @@ -447,10 +449,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode == 'Enabled' then EdgeToMachineForEngagement = EdgeToMachineOpposite end - local bIsApplicable, sBladeEngagement = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) + local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce - if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement)) then + if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.MoveAfterSplit)) then Cutting.sEdgeUsage = 'Standard' dDepthToMachine = Cutting.dDepthToMachine end @@ -545,7 +547,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- se lavorazione aperta sulla coda, eventuali aggiustamenti -- TODO valutare se fare funzione a parte local bIsTruncatingCutOnTail = Proc.Topology and ( Proc.Topology.sName == 'Cut-1-Through' or Proc.Topology.sName == 'TailCut') and Proc.AffectedFaces.bLeft - if bIsTruncatingCutOnTail then + if Cutting.bMoveAfterSplit or bIsTruncatingCutOnTail then Cutting.sStage = 'AfterTail' elseif Proc.AffectedFaces.bLeft and ( EdgeToMachine.sType == 'Bottom' or ( Cutting.vtToolDirection:getX() < 0.707)) then local dLengthOnX = Cutting.dLengthOnX @@ -562,12 +564,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then Cutting.sStage = 'AfterTail' + Cutting.bMoveAfterSplit = true else Cutting.bIsApplicable = false end elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then Cutting.sStage = 'AfterTail' + Cutting.bMoveAfterSplit = true else if bStartLeft then Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail From f9b1a957f6c1c5318cec5a192084fb47aa534844 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 11 Nov 2025 13:49:54 +0100 Subject: [PATCH 21/21] =?UTF-8?q?-=20in=20BatchProcessNew=20corretta=20res?= =?UTF-8?q?tituzione=20sMsg=20-=20in=20BLADETOWASTE=20si=20assegna=20quali?= =?UTF-8?q?t=C3=A0=20bassa=20a=20tutti=20i=20tagli=20con=20lati=20brutti?= =?UTF-8?q?=20-=20in=20FACEBYBLADE=20corretto=20typo=20in=20nome=20variabi?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BatchProcessNew.lua | 9 +++++++-- StrategyLibs/BLADETOWASTE.lua | 21 ++++++++++++--------- StrategyLibs/FACEBYBLADE.lua | 4 ++-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 62f6506..916d580 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -672,8 +672,13 @@ if bToProcess then sMsg = string.gsub( sMsg or '', '\r', ' ', 10) -- trovata almeno una strategia e feature lavorata completamente if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then - BEAM.ERR = 0 - BEAM.MSG = sMsg or '' + if #EgtTrim( sMsg) > 0 then + BEAM.ERR = -19 + BEAM.MSG = sMsg + else + BEAM.ERR = 0 + BEAM.MSG = '---' + end BEAM.ROT = -( RESULT[i].nRotation or 1) + 1 BEAM.CUTID = RESULT[i].idCut BEAM.TASKID = RESULT[i].idTask diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index b9f6128..2d3db48 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -398,6 +398,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + sChosenBladeType = sChosenBladeType .. 'Fast' end @@ -409,6 +410,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) OptionalParametersGetBestBlade.EdgeToMachineBottom = EdgeToMachineList.Bottom nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) + sChosenBladeType = sChosenBladeType .. 'Fast' end -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. @@ -619,7 +621,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) dExtendAfterTail = dExtendAfterTail, bReduceBladePath = bReduceBladePath } - if sChosenBladeType == 'Top' or sChosenBladeType == 'Bottom' then + if sChosenBladeType ~= 'TopGuillotine' then OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' end @@ -657,7 +659,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) end -- se nessun taglio è riuscito si riprova il taglio singolo permettendo i lati a minor elevazione, abbassando la qualità - if not ( Cutting and Cutting.bIsApplicable) or not ( CuttingDouble and CuttingDouble.bIsApplicable) then + if not ( Cutting and Cutting.bIsApplicable) or ( CuttingDouble and not CuttingDouble.bIsApplicable) then OptionalParameters.bAllowFastCuts = true nToolIndex, EdgeToMachine, sChosenBladeType = GetSingleCutStrategy( Proc, Part, OptionalParameters) @@ -669,15 +671,12 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) dExtendAfterTail = dExtendAfterTail, bReduceBladePath = bReduceBladePath } - if sChosenBladeType == 'Top' or sChosenBladeType == 'Bottom' then - OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' - end + if sChosenBladeType ~= 'TopGuillotine' then + OptionalParametersFaceByBlade.OppositeToolDirectionMode = 'Optimized' + end Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) end - - -- si abbassa la qualità per le possibili scheggiature - Result.dQuality = FeatureLib.GetStrategyQuality( 'STD') end if Cutting and Cutting.bIsApplicable then @@ -700,7 +699,11 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) end Result.dCompletionPercentage = dCompletionPercentage Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage) - Result.dQuality = Result.dQuality or FeatureLib.GetStrategyQuality( Machinings) + Result.dQuality = FeatureLib.GetStrategyQuality( Machinings) + -- per tagli con lati brutti o ghigliottina si abbassa la qualità + if ( sChosenBladeType ~= 'Top') and ( sChosenBladeType ~= 'Bottom') then + Result.dQuality = FeatureLib.GetStrategyQuality( 'STD') + end Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) else diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index e87380c..0d3b71c 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -381,7 +381,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza -- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione if ( sBladeEngagementOpposite == Cutting.sBladeEngagement) - and ( bMoveAfterSplit == Cutting.MoveAfterSplit) + and ( bMoveAfterSplit == Cutting.bMoveAfterSplit) and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then @@ -452,7 +452,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce - if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.MoveAfterSplit)) then + if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)) then Cutting.sEdgeUsage = 'Standard' dDepthToMachine = Cutting.dDepthToMachine end