-- 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