- funzioni IsFaceZOutOfRange, IsBladeOrientationOkForDownUp e GetBladeEngagement spostate in MachiningLib (da FACEBYBLADE)

This commit is contained in:
luca.mazzoleni
2025-10-30 16:49:49 +01:00
parent ecd2147e83
commit 25dbaed63b
2 changed files with 170 additions and 152 deletions
+167 -15
View File
@@ -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