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