diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 088f12d..2c1cc5c 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -199,6 +199,7 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo FRESA con certe caratteristiche +-- TODO qui vtToolDirection è in realtà vtN function MachiningLib.FindMill( Proc, ToolSearchParameters) local ToolInfo = {} diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 7d3da3c..c4a2cda 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -1,7 +1,6 @@ -- Strategia: FACEBYBLADE -- Descrizione --- Strategia di base per la lavorazione delle slot o tasche con lama --- Feature: tipo lapjoint +-- Strategia di base per la lavorazione delle facce con lama -- carico librerie local BeamLib = require( 'BeamLib') @@ -204,7 +203,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then Cutting.bToolInvert = true - Cutting.bInvert = not Cutting.bInvert else Cutting.bToolInvert = false end @@ -230,7 +228,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection) if FaceToMachine.vtN:getZ() < dMinNzDownUp then Cutting.bToolInvert = true - Cutting.bInvert = not Cutting.bInvert end end Cutting.nToolIndex = ToolInfo.nToolIndex diff --git a/StrategyLibs/FACEBYCHAINSAW.lua b/StrategyLibs/FACEBYCHAINSAW.lua index f930ad6..02272d7 100644 --- a/StrategyLibs/FACEBYCHAINSAW.lua +++ b/StrategyLibs/FACEBYCHAINSAW.lua @@ -1,7 +1,6 @@ -- Strategia: FACEBYCHAINSAW -- Descrizione --- Strategia di base per la lavorazione delle slot o tasche con sega a catena --- Feature: tipo lapjoint +-- Strategia di base per la lavorazione delle facce con sega a catena -- carico librerie local BeamLib = require( 'BeamLib') diff --git a/StrategyLibs/FACEBYMILL.lua b/StrategyLibs/FACEBYMILL.lua new file mode 100644 index 0000000..861640e --- /dev/null +++ b/StrategyLibs/FACEBYMILL.lua @@ -0,0 +1,391 @@ +-- Strategia: FACEBYMILL +-- Descrizione +-- Strategia di base per la lavorazione delle facce con fresa + +-- carico librerie +local BeamLib = require( 'BeamLib') +local BeamData = require( 'BeamData') +local MachiningLib = require( 'MachiningLib') + +-- Tabella per definizione modulo +local FACEBYMILL = {} + +------------------------------------------------------------------------------------------------------------- +local function GetLeadInOutType( Machining) + local sLeadInOutType = '' + + if Machining.bIsStartClosed or Machining.bIsEndClosed then + sLeadInOutType = 'Perpendicular' + else + -- testa sopra + if TOOLS[Machining.nToolIndex].SetupInfo.HeadType.bTop then + if Machining.vtToolDirection:getX() < 0.7 then + if Machining.vtToolDirection:getZ() > -0.087 + or abs( Machining.vtToolDirection:getX()) < 0.34202 then + sLeadInOutType = 'Perpendicular' + else + sLeadInOutType = 'Tangent' + end + elseif abs( Machining.vtEdgeDirection:getZ()) < 0.7 then + sLeadInOutType = 'Tangent' + else + -- TODO qui attacco tangenziale speciale tutto da un lato + sLeadInOutType = 'Tangent' + end + -- testa sotto + elseif TOOLS[Machining.nToolIndex].SetupInfo.HeadType.bBottom then + if Machining.vtToolDirection:getX() < 0.7 then + if Machining.vtToolDirection:getZ() < -GEO.EPS_SMALL + or abs( Machining.vtToolDirection:getX()) < 0.34202 then + sLeadInOutType = 'Perpendicular' + else + sLeadInOutType = 'Tangent' + end + elseif abs( Machining.vtEdgeDirection:getZ()) > 0.7 then + sLeadInOutType = 'Tangent' + else + -- TODO qui attacco tangenziale speciale tutto da un lato + sLeadInOutType = 'Tangent' + end + -- se testa senza preferenza Top e Bottom si fa sempre attacco tangenziale + else + sLeadInOutType = 'Tangent' + end + end + + return sLeadInOutType +end + + +local function CalculateLeadInOut( Machining, EdgeToMachine, Part) + -- 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 = {} + Machining.sLeadInOutType = '' + LeadIn.dStartAddLength = 0 + LeadOut.dEndAddLength = 0 + LeadIn.nType = MCH_MILL_LI.LINEAR + LeadOut.nType = MCH_MILL_LI.LINEAR + LeadIn.dPerpDistance = 0 + LeadOut.dPerpDistance = 0 + LeadIn.dTangentDistance = 0 + LeadOut.dTangentDistance = 0 + -- TODO da rimuovere controllo numero step quando si sistema la funzione che crea i cloni + if Machining.bIsStartClosed + or Machining.bIsEndClosed + or Machining.CloneStepsHorizontal.nCount > 1 then + + Machining.sLeadInOutType = 'Perpendicular' + if AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then + LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset + LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset + else + LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset + LeadOut.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset + end + else + Machining.sLeadInOutType = GetLeadInOutType( Machining) + if Machining.sLeadInOutType == 'Perpendicular' then + LeadIn.dPerpDistance = 1 + LeadOut.dPerpDistance = 1 + else + LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + end + 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 vtMachiningDirection:getZ() < -0.9 then + nSCC = MCH_SCC.ADIR_ZM + elseif vtMachiningDirection:getZ() > 0.9 then + nSCC = MCH_SCC.ADIR_ZP + elseif vtMachiningDirection:getY() < -0.707 then + nSCC = MCH_SCC.ADIR_YM + elseif vtMachiningDirection:getY() > 0.707 then + nSCC = MCH_SCC.ADIR_YP + elseif vtMachiningDirection:getX() < -0.707 then + nSCC = MCH_SCC.ADIR_XM + elseif vtMachiningDirection:getX() > 0.707 then + nSCC = MCH_SCC.ADIR_XP + end + + return nSCC +end + + +-- TODO calcolo area lavorata per completamento +-- TODO EdgeToMachineAlternative da gestire +function FACEBYMILL.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters) + local Milling = {} + Milling.bIsApplicable = true + Milling.dDepthToMachine = 0 + Milling.sMessage = '' + Milling.idProc = Proc.id + Milling.dResidualDepth = EdgeToMachine.dElevation + Milling.dBladeMarkLength = 0 + Milling.sEdgeType = EdgeToMachine.sType + Milling.nFeatureSegment = 1 + + -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end + local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 + local dPocketHeight = OptionalParameters.dPocketHeight or 0 + local dDepthToMachine = OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation + local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false + local bOppositeToolDirection = OptionalParameters.bOppositeToolDirection or false + local bDisableHorizontalSteps = OptionalParameters.bDisableHorizontalSteps or false + local sDepth = OptionalParameters.sDepth or 0 + local nToolIndex = OptionalParameters.nToolIndex + local dLongitudinalOffset = OptionalParameters.dLongitudinalOffset or 0 + if OptionalParameters.dPocketHeight then + dLongitudinalOffset = 0 + end + local dMinNzDownUp = OptionalParameters.dMinNzDownUp + local sUserNotes = OptionalParameters.sUserNotes or '' + + -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato + Milling.dLengthToMachine = EdgeToMachine.dLength + Milling.dEdgeLength = EdgeToMachine.dLength + if bOppositeToolDirection then + Milling.vtToolDirection = -EdgeToMachine.vtN + else + Milling.vtToolDirection = EdgeToMachine.vtN + end + Milling.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN + -- TODO conviene spostare questi calcoli nel FaceData? + Milling.ptEdge1, _, Milling.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Milling.vtToolDirection, GDB_ID.ROOT) + local b3BoxEdge = BBox3d( Milling.ptEdge1, Milling.ptEdge2) + Milling.dLengthOnX = b3BoxEdge:getDimX() + + -- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert) + if nToolIndex and not dMinNzDownUp then + dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Milling.vtToolDirection) + end + if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then + Milling.bToolInvert = true + else + Milling.bToolInvert = false + end + + -- ricerca utensile + if nToolIndex then + Milling.nToolIndex = nToolIndex + else + local ToolSearchParameters = {} + ToolSearchParameters.sMillShape = 'TSHAPEMILL' + ToolSearchParameters.dElevation = dDepthToMachine + -- TODO qui ToolSearchParameters.vtToolDirection andrà sosituito con vtN!! + if Milling.bToolInvert then + ToolSearchParameters.vtToolDirection = -FaceToMachine.vtN + else + ToolSearchParameters.vtToolDirection = FaceToMachine.vtN + end + ToolSearchParameters.bAllowTopHead = true + -- TODO bisognerà implementare anche la lama da sotto + ToolSearchParameters.bAllowBottomHead = false + local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) + -- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire + if ToolInfo.nToolIndex and not dMinNzDownUp then + dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Milling.vtToolDirection) + if FaceToMachine.vtN:getZ() < dMinNzDownUp then + Milling.bToolInvert = true + end + end + Milling.nToolIndex = ToolInfo.nToolIndex + end + Milling.nType = MCH_OY.MILLING + if not TOOLS[Milling.nToolIndex] or not TOOLS[Milling.nToolIndex].sName then + Milling.sMessage = 'Mill not found' + Milling.bIsApplicable = false + EgtOutLog( Milling.sMessage) + return Milling, EdgeToMachine.dElevation + end + + -- verifica dimensioni tasca compatibili + -- se tasca meno spessa della fresa la lavorazione non è applicabile + if OptionalParameters.dPocketHeight and ( not TOOLS[Milling.nToolIndex].bIsTMill or ( TOOLS[Milling.nToolIndex].dMaxMaterial > dPocketHeight + 10 * GEO.EPS_SMALL)) then + Milling.sMessage = 'Pocket too narrow for blade thickness' + Milling.bIsApplicable = false + EgtOutLog( Milling.sMessage) + return Milling, EdgeToMachine.dElevation + end + -- se tasca chiusa da entrambi i lati e più stretta della fresa la lavorazione non è applicabile + if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then + if TOOLS[Milling.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then + Milling.sMessage = 'Pocket too narrow for blade diameter' + Milling.bIsApplicable = false + EgtOutLog( Milling.sMessage) + return Milling, EdgeToMachine.dElevation + end + end + + -- parametri della lavorazione + -- profondità (parametro DEPTH) + Milling.sDepth = sDepth + -- inizio e fine aperti o chiusi + Milling.bIsStartClosed = not EdgeToMachine.bIsStartOpen + Milling.bIsEndClosed = not EdgeToMachine.bIsEndOpen + -- lato di lavoro e inversione + if TOOLS[Milling.nToolIndex].bIsCCW then + Milling.nWorkside = MCH_MILL_WS.RIGHT + Milling.bInvert = true + else + Milling.nWorkside = MCH_MILL_WS.LEFT + Milling.bInvert = false + end + if bOppositeToolDirection then + Milling.bInvert = not Milling.bInvert + end + if Milling.bToolInvert then + Milling.bInvert = not Milling.bInvert + end + -- profondità da lavorare e offset radiale + if TOOLS[Milling.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then + -- TODO la depth dovrebbe essere quella del machining + Milling.dDepthToMachine = dDepthToMachine + Milling.dResidualDepth = 0 + if bOppositeToolDirection then + Milling.dRadialOffset = -dDepthToMachine + else + Milling.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine + end + else + Milling.dDepthToMachine = TOOLS[Milling.nToolIndex].dMaxDepth - 1 + Milling.dResidualDepth = dDepthToMachine - Milling.dDepthToMachine + if bOppositeToolDirection then + Milling.dRadialOffset = -Milling.dDepthToMachine + else + Milling.dRadialOffset = EdgeToMachine.dElevation - Milling.dDepthToMachine + end + end + -- completamento + Milling.dCompletionPercentage = 100 - Milling.dResidualDepth / Milling.dDepthToMachine + -- step verticale e offset longitudinale + Milling.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Milling.nToolIndex].dThickness) + Milling.Steps.nStepType = MCH_MILL_ST.ONEWAY + Milling.dMaxElev = Milling.Steps.dStep * Milling.Steps.nCount - 10 * GEO.EPS_SMALL + if Milling.bToolInvert then + if Milling.Steps.nCount > 1 then + Milling.dLongitudinalOffset = - dPocketHeight + else + Milling.dLongitudinalOffset = - TOOLS[Milling.nToolIndex].dThickness - dLongitudinalOffset + end + else + Milling.dLongitudinalOffset = dLongitudinalOffset + end + -- distanza di sicurezza + Milling.dStartSafetyLength = BeamData.CUT_SIC + -- overlap + Milling.dOverlap = 0 + -- faceuse e frame lavorazione + if bOppositeToolDirection then + Milling.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Milling.vtToolDirection) + Milling.vtFaceUse = -Milling.vtToolDirection + else + Milling.nFaceuse = BeamLib.GetNearestOrthoOpposite( Milling.vtToolDirection) + Milling.vtFaceUse = Milling.vtToolDirection + end + -- SCC + Milling.nSCC = GetSCC( Milling.vtToolDirection) + -- asse bloccato + Milling.sBlockedAxis = ''BeamLib.GetBlockedAxis( Milling.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX()))'' + -- eventuale step orizzontale + Milling.CloneStepsHorizontal = {} + if not bDisableHorizontalSteps and TOOLS[Milling.nToolIndex].dSideStep then + Milling.CloneStepsHorizontal = MachiningLib.GetMachiningSteps( Milling.dDepthToMachine, TOOLS[Milling.nToolIndex].dSideStep) + else + Milling.CloneStepsHorizontal.nCount = 1 + Milling.CloneStepsHorizontal.dStep = 0 + end + -- approccio e retrazione + Milling.LeadIn, Milling.LeadOut = CalculateLeadInOut( Milling, EdgeToMachine, Part) + -- lunghezza impronta lama + if Milling.bIsStartClosed and Milling.bIsEndClosed then + Milling.dBladeMarkLength = abs( min( Milling.LeadIn.dStartAddLength, Milling.LeadOut.dEndAddLength)) + elseif Milling.bIsStartClosed then + Milling.dBladeMarkLength = abs( Milling.LeadIn.dStartAddLength) + elseif Milling.bIsEndClosed then + Milling.dBladeMarkLength = abs( Milling.LeadOut.dEndAddLength) + end + -- geometria + Milling.Geometry = {{Milling.idProc, FaceToMachine.id}} + -- note utente + Milling.sUserNotes = sUserNotes + -- nome operazione + Milling.sOperationName = 'Milling_' .. ( EgtGetName( Milling.idProc) or tostring( Milling.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 ( Milling.vtToolDirection:getX() < 0.707)) then + local dLengthOnX = Milling.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( Milling) + local dAddLengthLeftSide = Milling.LeadOut.dEndAddLength + local dAddLengthToReduce = sqrt( Milling.dDepthToMachine * TOOLS[Milling.nToolIndex].dDiameter - Milling.dDepthToMachine * Milling.dDepthToMachine) + if bStartLeft then + dAddLengthLeftSide = Milling.LeadIn.dStartAddLength + end + if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtN, Y_AX()) then + if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then + Milling.sStage = 'AfterTail' + else + Milling.bIsApplicable = false + end + elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then + if MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) then + Milling.sStage = 'AfterTail' + else + if bStartLeft then + Milling.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail + else + Milling.LeadOut.dEndAddLength = - dAddLengthToReduce + dExtendAfterTail + end + end + end + end + + return Milling + +end + +------------------------------------------------------------------------------------------------------------- + + return FACEBYMILL \ No newline at end of file