260 lines
12 KiB
Lua
260 lines
12 KiB
Lua
-- Strategia: SLOTBYCHAINSAW
|
|
-- Descrizione
|
|
-- Strategia di base per la lavorazione delle slot o tasche con sega a catena
|
|
-- Feature: tipo lapjoint
|
|
|
|
-- carico librerie
|
|
local BeamLib = require( 'BeamLib')
|
|
local BeamData = require( 'BeamData')
|
|
local MachiningLib = require( 'MachiningLib')
|
|
|
|
-- Tabella per definizione modulo
|
|
local SLOTBYCHAINSAW = {}
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
|
|
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
|
|
|
|
return LeadIn, LeadOut
|
|
end
|
|
|
|
|
|
-- TODO calcolo area lavorata per completamento
|
|
function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
|
|
local Mortising = {}
|
|
Mortising.bIsApplicable = true
|
|
Mortising.dDepthToMachine = 0
|
|
Mortising.dResidualDepth = EdgeToMachine.dElevation
|
|
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 bStopAtHalfElevation = OptionalParameters.bStopAtHalfElevation or false
|
|
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
|
|
local dPocketHeight = OptionalParameters.dPocketHeight or 0
|
|
local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false
|
|
local bOppositeToolDirection = OptionalParameters.bOppositeToolDirection or false
|
|
|
|
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
|
|
Mortising.dLengthToMachine = dLengthToMachine
|
|
-- TODO serve un modo migliore di calcolare la lunghezza lungo X; attenzione che serve la lunghezza reale di lavoro, non quella del lato
|
|
-- TODO andrà aggiornata dopo il calcolo LeadIn/Out
|
|
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY())
|
|
Mortising.dEdgeLength = EdgeToMachine.dLength
|
|
if bOppositeToolDirection then
|
|
Mortising.vtToolDirection = -EdgeToMachine.vtN
|
|
else
|
|
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)
|
|
|
|
-- ricerca utensile
|
|
local bExtendWithCornerRadius = false
|
|
if not bStopAtHalfElevation then
|
|
if ( EdgeToMachine.sType == 'Side' and Proc.Topology.sName == 'Groove-3-Through') or
|
|
( EdgeToMachine.sType == 'Opposite' and Proc.Topology.sFamily == 'Tunnel') then
|
|
|
|
bExtendWithCornerRadius = true
|
|
Mortising.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
|
|
else
|
|
Mortising.dDepthToMachine = EdgeToMachine.dElevation
|
|
end
|
|
else
|
|
bExtendWithCornerRadius = true
|
|
Mortising.dDepthToMachine = EdgeToMachine.dElevation / 2 + BeamData.CUT_EXTRA_MIN
|
|
end
|
|
local ToolSearchParameters = {}
|
|
local ToolInfo = {}
|
|
ToolSearchParameters.vtToolDirection = Mortising.vtToolDirection
|
|
ToolSearchParameters.bAllowTopHead = true
|
|
ToolSearchParameters.bAllowBottomHead = true
|
|
ToolSearchParameters.dElevation = Mortising.dDepthToMachine
|
|
ToolSearchParameters.bExtendWithCornerRadius = bExtendWithCornerRadius
|
|
ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters)
|
|
Mortising.nToolIndex = ToolInfo.nToolIndex
|
|
Mortising.nType = MCH_OY.MORTISING
|
|
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 strategia 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
|
|
if Proc.MainFaces and #( Proc.MainFaces.SideFaces) > 1 then
|
|
-- se tasca più stretta della sega a catena la strategia non è applicabile
|
|
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 = 'TH'
|
|
-- 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 bOppositeToolDirection 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
|
|
Mortising.dDepthToMachine = Mortising.dDepthToMachine + TOOLS[Mortising.nToolIndex].dCornerRadius
|
|
end
|
|
if TOOLS[Mortising.nToolIndex].dMaxMaterial > Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
|
|
Mortising.dResidualDepth = 0
|
|
if bOppositeToolDirection then
|
|
Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - Mortising.dDepthToMachine
|
|
else
|
|
Mortising.dLongitudinalOffset = 0
|
|
end
|
|
else
|
|
Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMaterial - 1
|
|
Mortising.dResidualDepth = EdgeToMachine.dElevation - Mortising.dDepthToMachine
|
|
if bOppositeToolDirection 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 = 100 - Mortising.dResidualDepth / Mortising.dDepthToMachine
|
|
-- 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
|
|
-- faceuse
|
|
if bOppositeToolDirection 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)
|
|
end
|
|
-- approccio e retrazione
|
|
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine)
|
|
-- eventuale step verticale
|
|
Mortising.VerticalSteps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Mortising.nToolIndex].dThickness)
|
|
-- 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 SLOTBYCHAINSAW |