Files
databeamnew/StrategyLibs/FACEBYCHAINSAW.lua
T
luca.mazzoleni a40cc026c9 - in STR0002 implementato AntiSplint
- in ANTISPLINTONFACE piccole modifiche
2026-04-02 18:13:25 +02:00

287 lines
13 KiB
Lua

-- Strategia: FACEBYCHAINSAW
-- Descrizione
-- Strategia di base per la lavorazione delle facce con sega a catena
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local PreSimulationLib = require( 'PreSimulationLib')
-- Tabella per definizione modulo
local FACEBYCHAINSAW = {}
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLengthToMachine)
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
-- si determina l'eventuale riduzione da applicare in caso di inizio o fine chiusi
local dAddLengthToReduce = 0
dAddLengthToReduce = TOOLS[Machining.nToolIndex].dDiameter / 2
if Machining.bInvert then
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
end
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
if sSideToMachine == 'End' then
LeadIn.dStartAddLength = dAddLengthToReduce + dLengthToMachine + BeamData.CUT_EXTRA - EdgeToMachine.dLength
elseif Machining.bIsStartClosed then
LeadIn.dStartAddLength = -dAddLengthToReduce
else
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
end
if sSideToMachine == 'Start' then
LeadOut.dEndAddLength = dAddLengthToReduce + dLengthToMachine + BeamData.CUT_EXTRA - EdgeToMachine.dLength
elseif Machining.bIsEndClosed then
LeadOut.dEndAddLength = -dAddLengthToReduce
else
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
end
-- punti dell'attacco
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * LeadIn.dStartAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * LeadOut.dEndAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
return LeadIn, LeadOut
end
-- TODO calcolo area lavorata per completamento
function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
local Mortising = MachiningLib.InitMachiningParameters( MCH_MY.MORTISING)
Mortising.bIsApplicable = true
Mortising.dDepthToMachine = 0
Mortising.dResidualDepth = EdgeToMachine.dElevation
Mortising.dCompletionPercentage = 0
Mortising.sMessage = ''
Mortising.idProc = Proc.id
Mortising.sEdgeType = EdgeToMachine.sType
Mortising.nFeatureSegment = 1
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
local bUseZigZagMortising = OptionalParameters.bUseZigZagMortising or false
local sSideToMachine = OptionalParameters.sSideToMachine or ''
local dLengthToMachine = OptionalParameters.dLengthToMachine or EdgeToMachine.dLength
local dCustomMaxElev = OptionalParameters.dMaxElev or EdgeToMachine.dElevation
local dDepthToMachine = OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation
local bExtendWithCornerRadius = OptionalParameters.bExtendWithCornerRadius or false
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local dPocketHeight = OptionalParameters.dPocketHeight or 0
local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false
local OppositeToolDirectionMode = OptionalParameters.OppositeToolDirectionMode or 'Disabled'
local sDepth = OptionalParameters.sDepth or 'TH'
local dLongitudinalStepSpan = OptionalParameters.dLongitudinalStepSpan
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
Mortising.dEdgeLength = EdgeToMachine.dLength
if OppositeToolDirectionMode == 'Enabled' then
Mortising.vtToolDirection = -EdgeToMachine.vtN
else
Mortising.vtToolDirection = EdgeToMachine.vtN
end
Mortising.vtEdgeDirection = Vector3d( EdgeToMachine.vtEdge)
Mortising.ptEdge1, Mortising.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
-- ricerca utensile
local ToolSearchParameters = {}
local ToolInfo = {}
ToolSearchParameters.vtToolDirection = Mortising.vtToolDirection
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.dElevation = dDepthToMachine
ToolSearchParameters.bExtendWithCornerRadius = bExtendWithCornerRadius
ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters)
Mortising.nToolIndex = ToolInfo.nToolIndex
if not TOOLS[Mortising.nToolIndex] or not TOOLS[Mortising.nToolIndex].sName then
Mortising.sMessage = 'Chainsaw not found'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
-- verifica dimensioni tasca compatibili
-- se tasca meno spessa della sega a catena la lavorazione non è applicabile
if OptionalParameters.dPocketHeight and ( TOOLS[Mortising.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL) then
Mortising.sMessage = 'Pocket too narrow for chainsaw thickness'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
-- se tasca chiusa da entrambi i lati e più stretta della sega a catena la lavorazione non è applicabile
if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
if TOOLS[Mortising.nToolIndex].dWidth > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
Mortising.sMessage = 'Pocket too narrow for chainsaw width'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
end
-- parametri della lavorazione
-- TODO gestire ToolInvert per rispettare direzione migliore di lavorazione
-- profondità (parametro DEPTH) non usata
Mortising.sDepth = sDepth
-- inizio e fine aperti o chiusi
Mortising.bIsStartClosed = not EdgeToMachine.bIsStartOpen
Mortising.bIsEndClosed = not EdgeToMachine.bIsEndOpen
-- lato di lavoro e inversioni
Mortising.bInvert = false
if OppositeToolDirectionMode == 'Enabled' then
Mortising.nWorkside = MCH_MILL_WS.LEFT
Mortising.bToolInvert = true
else
Mortising.nWorkside = MCH_MILL_WS.RIGHT
Mortising.bToolInvert = false
end
-- profondità e offset longitudinale
if bExtendWithCornerRadius then
dDepthToMachine = dDepthToMachine + TOOLS[Mortising.nToolIndex].dCornerRadius
end
if TOOLS[Mortising.nToolIndex].dMaxMaterial > dDepthToMachine - 10 * GEO.EPS_SMALL then
Mortising.dDepthToMachine = dDepthToMachine
Mortising.dResidualDepth = 0
if OppositeToolDirectionMode == 'Enabled' then
Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - dDepthToMachine
else
Mortising.dLongitudinalOffset = 0
end
else
Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMaterial - 1
Mortising.dResidualDepth = dDepthToMachine - Mortising.dDepthToMachine
if OppositeToolDirectionMode == 'Enabled' then
Mortising.dLongitudinalOffset = 0
else
Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - Mortising.dDepthToMachine
end
Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw elevation (' .. EgtNumToString( EdgeToMachine.dElevation, 1) .. ') bigger than max tool depth (' .. EgtNumToString( Mortising.dDepthToMachine, 1) .. ')'
EgtOutLog( Mortising.sMessage)
end
-- completamento
Mortising.dCompletionPercentage = ( 1 - Mortising.dResidualDepth / Mortising.dDepthToMachine) * 100
-- massima elevazione
if dCustomMaxElev < Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
Mortising.dMaxElev = max( dCustomMaxElev, dCustomMaxElev - Mortising.dLongitudinalOffset)
end
-- offset radiale
Mortising.dRadialOffset = 0
-- distanza di sicurezza
Mortising.dStartSafetyLength = max( EdgeToMachine.dElevation, ( TOOLS[Mortising.nToolIndex].SetupInfo.dZSafeDelta or 60) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ))
-- overlap
Mortising.dOverlap = 0
-- step
Mortising.Steps = {}
if bUseZigZagMortising then
Mortising.Steps.nStepType = MCH_MILL_ST.ZIGZAG
else
Mortising.Steps.nStepType = MCH_MILL_ST.ONEWAY
end
Mortising.Steps.dStep = TOOLS[Mortising.nToolIndex].dStep
Mortising.Steps.nCount = max( 1, ceil( ( min( Mortising.dDepthToMachine, ( Mortising.dMaxElev or Mortising.dDepthToMachine)) + 10 * GEO.EPS_SMALL) / Mortising.Steps.dStep))
-- faceuse
if OppositeToolDirectionMode == 'Enabled' then
Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( -Mortising.vtToolDirection)
else
Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( Mortising.vtToolDirection)
end
-- SCC
Mortising.SCC = MCH_SCC.NONE
-- asse bloccato e angoli suggeriti
local vtRes = FaceToMachine.vtN ^ EdgeToMachine.vtN
if abs( vtRes:getZ()) < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 1)
elseif EdgeToMachine.vtN:getZ() < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 2)
-- TODO al momento si contempla solo sega a catena con asse bloccato
else
Mortising.bIsApplicable = false
return Mortising
end
-- approccio e retrazione
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine)
-- check finecorsa nei punti di attacco
local PointsOnToolTipCenter = {
Mortising.LeadIn.ptPoint,
Mortising.LeadOut.ptPoint
}
local vtAux = FaceToMachine.vtN
if Mortising.bToolInvert then
vtAux = -FaceToMachine.vtN
end
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, Mortising.vtToolDirection, Mortising.nSCC, TOOLS[Mortising.nToolIndex], vtAux, Mortising.sBlockedAxis)
if bOutOfStroke then
Mortising.sMessage = 'Out of stroke'
Mortising.bIsApplicable = false
return Mortising
end
-- eventuale step verticale
Mortising.CloneStepsLongitudinal = {}
if not dLongitudinalStepSpan then
dLongitudinalStepSpan = dPocketHeight
end
if dLongitudinalStepSpan > 10 * GEO.EPS_SMALL then
Mortising.CloneStepsLongitudinal = MachiningLib.GetMachiningSteps( true, dLongitudinalStepSpan, TOOLS[Mortising.nToolIndex].dThickness)
else
Mortising.CloneStepsLongitudinal.nCount = 1
Mortising.CloneStepsLongitudinal.dStep = dPocketHeight
end
-- lunghezza lavorata
-- TODO per il calcolo della dlengthOnX ripetere il calcolo del FACEBYBLADE con proiezione del lato; serve prolungare con la Add Length secondo la vtEdgeDirection
-- TODO fare funzione EstimatePathLength o simile
Mortising.dLengthToMachine = Mortising.dEdgeLength + Mortising.LeadIn.dStartAddLength + Mortising.LeadOut.dEndAddLength
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY())
Mortising.dTimeToMachine, Mortising.dLengthToMachineAllStepsWithLeadInOut = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Mortising, Part)
-- area lavorata
Mortising.dAreaToMachine = min( EdgeToMachine.dElevation, Mortising.dDepthToMachine) * ( min( Mortising.dEdgeLength, Mortising.dLengthToMachine + TOOLS[Mortising.nToolIndex].dDiameter))
-- geometria
Mortising.Geometry = {{Proc.id, FaceToMachine.id}}
-- nome operazione
Mortising.sOperationName = 'Chainsaw_' .. ( EgtGetName( Mortising.idProc) or tostring( Mortising.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
-- TODO valutare se fare funzione a parte
if Proc.AffectedFaces.bLeft and ( EdgeToMachine.sType == 'Bottom' or ( Mortising.vtToolDirection:getX() < 0.707)) then
local dLengthOnX = Mortising.dLengthOnX
-- se feature splittata non si considera la lunghezza della feature per il check spostamento dopo separazione
if bIsSplitFeature then
dLengthOnX = 0
end
local bStartLeft = MachiningLib.StartsLeftSide( Mortising)
local dAddLengthLeftSide = Mortising.LeadOut.dEndAddLength
if bStartLeft then
dAddLengthLeftSide = Mortising.LeadIn.dStartAddLength
end
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
Mortising.sStage = 'AfterTail'
else
Mortising.bIsApplicable = false
end
elseif dAddLengthLeftSide + TOOLS[Mortising.nToolIndex].dDiameter / 2 > dExtendAfterTail then
if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then
Mortising.sStage = 'AfterTail'
else
if bStartLeft then
Mortising.LeadIn.dStartAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
else
Mortising.LeadOut.dEndAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
end
end
end
end
return Mortising
end
-------------------------------------------------------------------------------------------------------------
return FACEBYCHAINSAW