-- 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 = 0 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 EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL 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 = abs( EdgeToMachine.dElevation) Cutting.dBladeMarkLength = 0 Cutting.sEdgeType = EdgeToMachine.sType -- parametri opzionali if not OptionalParameters then OptionalParameters = {} end local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false -- lunghezze e punti caratteristici della lavorazione e del lato lavorato Cutting.dLengthToMachine = EdgeToMachine.dLength Cutting.dLengthOnX = abs( EdgeToMachine.dLength * EdgeToMachine.vtToolDirection:getY()) Cutting.dEdgeLength = EdgeToMachine.dLength Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -EdgeToMachine.vtToolDirection, GDB_ID.ROOT) Cutting.vtEdgeDirection = EdgeToMachine.vtToolDirection ^ FaceToMachine.vtN local dPocketHeight = 0 if Proc.Topology.sFamily == 'Tunnel' then dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength else if FaceToMachine.sType == 'Long' then dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength elseif FaceToMachine.sType == 'Side' then dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength end end -- ricerca utensile local ToolSearchParameters = {} ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation) ToolSearchParameters.vtToolDirection = EdgeToMachine.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 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.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 EdgeToMachine.dElevation < -10 * GEO.EPS_SMALL 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 > abs( EdgeToMachine.dElevation) - 10 * GEO.EPS_SMALL then -- TODO la depth dovrebbe essere quella del machining Cutting.dDepthToMachine = abs( EdgeToMachine.dElevation) Cutting.dResidualDepth = 0 if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then Cutting.dRadialOffset = 0 else Cutting.dRadialOffset = EdgeToMachine.dElevation end else Cutting.dDepthToMachine = TOOLS[Cutting.nToolIndex].dMaxDepth - 1 Cutting.dResidualDepth = abs( EdgeToMachine.dElevation) - Cutting.dDepthToMachine if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then Cutting.dRadialOffset = EdgeToMachine.dElevation - Cutting.dDepthToMachine else Cutting.dRadialOffset = -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 EdgeToMachine.dElevation > - 10 * GEO.EPS_SMALL then Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( EdgeToMachine.vtToolDirection) else Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -EdgeToMachine.vtToolDirection) end -- SCC Cutting.nSCC = GetSCC( EdgeToMachine.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 = {{Proc.id, FaceToMachine.id}} -- nome operazione Cutting.sOperationName = 'Cut_' .. ( EgtGetName( Cutting.idProc) or tostring( Cutting.idProc)) .. '_' .. tostring( FaceToMachine.id + 1) -- eventuale avviso di danneggiamento pezzo successivo -- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza -- local dOffsideLength = max( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength) + TOOLS[Cutting.nToolIndex].dDiameter / 2 + 10 * GEO.EPS_SMALL -- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then -- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : sawblade can damage next piece.' -- if #Cutting.sMessage > 0 then -- Cutting.sMessage = Cutting.sMessage .. '\n' .. sDamageNextPieceMessage -- else -- Cutting.sMessage = sDamageNextPieceMessage -- end -- EgtOutLog( sDamageNextPieceMessage) -- end return Cutting end ------------------------------------------------------------------------------------------------------------- return SLOTBYBLADE