-- Strategia: SLOTBYBLADE -- Descrizione -- Strategia di base per la lavorazione delle slot o tasche con lama -- Feature: tipo lapjoint -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') -- Tabella per definizione modulo local SLOTBYBLADE = {} ------------------------------------------------------------------------------------------------------------- local function CalculateLeadInOut( Machining, EdgeToMachine) -- 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 = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine) if Machining.bInvert then Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed end local LeadIn = {} local LeadOut = {} LeadIn.dStartAddLength = 0 LeadOut.dEndAddLength = 0 LeadIn.nType = MCH_MILL_LI.LINEAR LeadOut.nType = MCH_MILL_LI.LINEAR LeadIn.dTangentDistance = 0 LeadOut.dTangentDistance = 0 if AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC else LeadIn.dPerpDistance = BeamData.CUT_SIC LeadOut.dPerpDistance = BeamData.CUT_SIC end LeadIn.dElevation = 0 LeadOut.dElevation = 0 LeadIn.dCompLength = 0 LeadOut.dCompLength = 0 if Machining.bIsStartClosed and Machining.bIsEndClosed then LeadIn.dStartAddLength = -dAddLengthToReduce LeadOut.dEndAddLength = -dAddLengthToReduce elseif Machining.bIsStartClosed then LeadIn.dStartAddLength = -dAddLengthToReduce -- eventuale correzione per accorciamento maggiore di larghezza tasca LeadOut.dEndAddLength = max( -LeadIn.dStartAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA) elseif Machining.bIsEndClosed then LeadOut.dEndAddLength = -dAddLengthToReduce -- eventuale correzione per accorciamento maggiore di larghezza tasca LeadIn.dStartAddLength = max( -LeadOut.dEndAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA) else LeadIn.dStartAddLength = BeamData.CUT_EXTRA LeadOut.dEndAddLength = BeamData.CUT_EXTRA end return LeadIn, LeadOut end local function GetSCC( vtMachiningDirection) -- TODO implementare SCC come per FacesBySaw local nSCC = MCH_SCC.NONE if AreSameVectorApprox( vtMachiningDirection, Z_AX()) then nSCC = MCH_SCC.ADIR_ZP elseif AreOppositeVectorApprox( vtMachiningDirection, Z_AX()) then nSCC = MCH_SCC.ADIR_ZM elseif AreSameVectorApprox( vtMachiningDirection, Y_AX()) then nSCC = MCH_SCC.ADIR_YP elseif AreOppositeVectorApprox( vtMachiningDirection, Y_AX()) then nSCC = MCH_SCC.ADIR_YM elseif AreSameVectorApprox( vtMachiningDirection, X_AX()) then nSCC = MCH_SCC.ADIR_XP elseif AreOppositeVectorApprox( vtMachiningDirection, X_AX()) then nSCC = MCH_SCC.ADIR_XM end return nSCC end -- TODO calcolo area lavorata per completamento function SLOTBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters) local Cutting = {} Cutting.bIsApplicable = true Cutting.dDepthToMachine = 0 Cutting.sMessage = '' Cutting.idProc = Proc.id Cutting.dResidualDepth = EdgeToMachine.dElevation Cutting.dBladeMarkLength = 0 Cutting.sEdgeType = EdgeToMachine.sType Cutting.nFeatureSegment = 1 -- parametri opzionali if not OptionalParameters then OptionalParameters = {} end local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local dPocketHeight = OptionalParameters.dPocketHeight or 0 local dDepthToMachine = min( OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation, EdgeToMachine.dElevation) local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false local bOppositeToolDirection = OptionalParameters.bOppositeToolDirection or false -- lunghezze e punti caratteristici della lavorazione e del lato lavorato Cutting.dLengthToMachine = EdgeToMachine.dLength Cutting.dEdgeLength = EdgeToMachine.dLength if bOppositeToolDirection then Cutting.vtToolDirection = -EdgeToMachine.vtN else Cutting.vtToolDirection = EdgeToMachine.vtN end Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN -- TODO conviene spostare questi calcoli nel FaceData? Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) local b3BoxEdge = BBox3d( Cutting.ptEdge1, Cutting.ptEdge2) Cutting.dLengthOnX = b3BoxEdge:getDimX() -- -- ricerca utensile local ToolSearchParameters = {} ToolSearchParameters.dElevation = EdgeToMachine.dElevation ToolSearchParameters.vtToolDirection = Cutting.vtToolDirection ToolSearchParameters.bAllowTopHead = true ToolSearchParameters.bAllowBottomHead = false ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex Cutting.nType = MCH_OY.MILLING if not TOOLS[Cutting.nToolIndex].sName then Cutting.sMessage = 'Blade not found' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end -- verifica dimensioni tasca compatibili -- se tasca meno spessa della lama la strategia non è applicabile if OptionalParameters.dPocketHeight and ( TOOLS[Cutting.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL) then Cutting.sMessage = 'Pocket too narrow for blade thickness' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end if Proc.MainFaces and #( Proc.MainFaces.SideFaces) > 1 then -- se tasca più stretta della lama la strategia non è applicabile if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then Cutting.sMessage = 'Pocket too narrow for blade diameter' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end end -- parametri della lavorazione -- profondità (parametro DEPTH) non usata Cutting.sDepth = 0 -- inizio e fine aperti o chiusi Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen -- lato di lavoro e inversioni if TOOLS[Cutting.nToolIndex].bIsCCW then Cutting.nWorkside = MCH_MILL_WS.RIGHT Cutting.bInvert = true else Cutting.nWorkside = MCH_MILL_WS.LEFT Cutting.bInvert = false end if bOppositeToolDirection then Cutting.bInvert = not Cutting.bInvert end -- TODO gestire lama da sotto e lama downUp if FaceToMachine.vtN:getZ() < - 10 * GEO.EPS_SMALL then Cutting.bToolInvert = true Cutting.bInvert = not Cutting.bInvert else Cutting.bToolInvert = false end -- profondità da lavorare e offset radiale if TOOLS[Cutting.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then -- TODO la depth dovrebbe essere quella del machining Cutting.dDepthToMachine = dDepthToMachine Cutting.dResidualDepth = 0 if bOppositeToolDirection then Cutting.dRadialOffset = -dDepthToMachine else Cutting.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine end else Cutting.dDepthToMachine = TOOLS[Cutting.nToolIndex].dMaxDepth - 1 Cutting.dResidualDepth = EdgeToMachine.dElevation - Cutting.dDepthToMachine if bOppositeToolDirection then Cutting.dRadialOffset = -Cutting.dDepthToMachine else Cutting.dRadialOffset = EdgeToMachine.dElevation - Cutting.dDepthToMachine end end -- completamento Cutting.dCompletionPercentage = 100 - Cutting.dResidualDepth / Cutting.dDepthToMachine -- step verticale e offset longitudinale Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness) Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY Cutting.dMaxElev = Cutting.Steps.dStep * Cutting.Steps.nCount - 10 * GEO.EPS_SMALL if Cutting.bToolInvert and Cutting.Steps.nCount > 1 then Cutting.dLongitudinalOffset = - dPocketHeight else Cutting.dLongitudinalOffset = 0 end -- distanza di sicurezza Cutting.dStartSafetyLength = 10 -- overlap Cutting.dOverlap = 0 -- faceuse if bOppositeToolDirection then Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection) else Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( Cutting.vtToolDirection) end -- SCC Cutting.nSCC = GetSCC( Cutting.vtToolDirection) -- asse bloccato Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX())) -- approccio e retrazione Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine) -- eventuale step orizzontale Cutting.HorizontalSteps = {} if TOOLS[Cutting.nToolIndex].dSideStep then Cutting.HorizontalSteps = MachiningLib.GetMachiningSteps( Cutting.dDepthToMachine, TOOLS[Cutting.nToolIndex].dSideStep) else Cutting.HorizontalSteps.nCount = 1 Cutting.HorizontalSteps.dStep = 0 end -- lunghezza impronta lama if Cutting.bIsStartClosed and Cutting.bIsEndClosed then Cutting.dBladeMarkLength = abs( min( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength)) elseif Cutting.bIsStartClosed then Cutting.dBladeMarkLength = abs( Cutting.LeadIn.dStartAddLength) elseif Cutting.bIsEndClosed then Cutting.dBladeMarkLength = abs( Cutting.LeadOut.dEndAddLength) end -- geometria Cutting.Geometry = {{Cutting.idProc, FaceToMachine.id}} -- nome operazione Cutting.sOperationName = 'Cut_' .. ( EgtGetName( Cutting.idProc) or tostring( Cutting.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 ( Cutting.vtToolDirection:getX() < 0.707)) then local dLengthOnX = Cutting.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( Cutting) local dAddLengthLeftSide = Cutting.LeadOut.dEndAddLength local dAddLengthToReduce = sqrt( Cutting.dDepthToMachine * TOOLS[Cutting.nToolIndex].dDiameter - Cutting.dDepthToMachine * Cutting.dDepthToMachine) if bStartLeft then dAddLengthLeftSide = Cutting.LeadIn.dStartAddLength end if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then Cutting.sStage = 'AfterTail' else Cutting.bIsApplicable = false end elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then Cutting.sStage = 'AfterTail' else if bStartLeft then Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail else Cutting.LeadOut.dEndAddLength = - dAddLengthToReduce + dExtendAfterTail end end end end return Cutting end ------------------------------------------------------------------------------------------------------------- return SLOTBYBLADE