From f5f362c3185677b6ad2f5d424fe0c44b63cf5f07 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 14 Jun 2024 18:47:14 +0200 Subject: [PATCH] - creazione BasicStrategies e strategia SLOTBYCHAINSAW - modifiche a STR0003 per contemplare strategie base - modifiche parziali da completare --- CoreStrategies/SLOTBYCHAINSAW.lua | 503 ++++++++++++++++++++++++++++++ LuaLibs/FaceData.lua | 2 +- LuaLibs/MachiningLib.lua | 10 +- Process.lua | 7 + Strategies/STR0003/STR0003.lua | 100 ++++-- 5 files changed, 588 insertions(+), 34 deletions(-) create mode 100644 CoreStrategies/SLOTBYCHAINSAW.lua diff --git a/CoreStrategies/SLOTBYCHAINSAW.lua b/CoreStrategies/SLOTBYCHAINSAW.lua new file mode 100644 index 0000000..bbda623 --- /dev/null +++ b/CoreStrategies/SLOTBYCHAINSAW.lua @@ -0,0 +1,503 @@ +-- 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') +local FeatureData = require( 'FeatureData') + +-- Tabella per definizione modulo +local SLOTBYCHAINSAW = {} +local Strategy = {} +local Chainsaw = {} +Result = {} + +------------------------------------------------------------------------------------------------------------- + +local function IsTopologyOk( Proc) + if Proc.Topology.bAllRightAngles and + ( Proc.Topology.sName == 'Pocket-5-Blind' or + Proc.Topology.sName == 'Groove-3-Through' or + Proc.Topology.sName == 'Groove-4-Blind' or + Proc.Topology.sName == 'Tunnel-4-Through') then + + return true + else + return false + end +end + + +local function GetCompletionPercentage( Proc, Result) + local dNotMachinedArea = 0 + local dCompletionPercentage = 0 + + if Proc.Topology.sFamily == 'Tunnel' then + dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined) + if #Result == 2 then + dNotMachinedArea = dNotMachinedArea - Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[2].dDepthMachined) + end + else + if #Result == 1 then + dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined) + elseif #Result == 2 then + dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined) + elseif #Result == 3 then + dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined - Result[3].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined) + end + end + dCompletionPercentage = 100 - dNotMachinedArea / Proc.MainFaces.LongFaces[1].dArea * 100 + + return dCompletionPercentage +end + + +local function AddResult( Machining) + table.insert( Result, {}) + Result[#Result].bIsApplicable = Machining.bIsApplicable + Result[#Result].sMessage = Machining.sMessage + Result[#Result].dDepthMachined = Machining.dDepthToMachine + Result[#Result].bIsApplyOk = Machining.bIsApplyOk + Result[#Result].sApplyMessage = Machining.sApplyMessage + + return Result +end + + +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 bIsMortising = ( Machining.nType == MCH_OY.MORTISING) + local dAddLengthToReduce = 0 + if bIsMortising then + dAddLengthToReduce = TOOLS[Machining.nToolIndex].dDiameter / 2 + else + dAddLengthToReduce = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine) + end + + if Machining.bInvert then + Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed + end + + local LeadIn = {} + local LeadOut = {} + LeadIn.dStartAddLength = 0 + LeadOut.dEndAddLength = 0 + if not bIsMortising then + 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 + else + if Machining.bIsStartClosed then + LeadIn.dStartAddLength = -dAddLengthToReduce + else + LeadIn.dStartAddLength = BeamData.CUT_EXTRA + end + if Machining.bIsEndClosed then + LeadOut.dEndAddLength = -dAddLengthToReduce + else + LeadOut.dEndAddLength = BeamData.CUT_EXTRA + end + end + + return LeadIn, LeadOut +end + + +function CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, Part) + local Mortising = {} + Mortising.bIsApplicable = true + Mortising.dDepthToMachine = 0 + Mortising.sMessage = '' + Mortising.idProc = Proc.id + -- OneSide | OneSideAndExtend | BothSides | BothSidesAndExtend + local sMortisingType + + local dPocketHeight = 0 + if Proc.Topology.sFamily == 'Tunnel' then + dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength + else + if FaceToMachine.Type == 'Long' then + dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength + elseif FaceToMachine.Type == 'Side' then + dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength + end + end + + -- ricerca utensile + local ToolSearchParameters = {} + local ToolInfo = {} + ToolSearchParameters.vtToolDirection = EdgeToMachine.vtToolDirection + ToolSearchParameters.bAllowTopHead = true + ToolSearchParameters.bAllowBottomHead = false + if Proc.Topology.sFamily == 'Tunnel' then + sMortisingType = 'OneSideAndExtend' + ToolSearchParameters.bExtendWithCornerRadius = true + ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation) + BeamData.CUT_EXTRA + ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters) + if ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL then + sMortisingType = 'BothSidesAndExtend' + ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation) / 2 + BeamData.CUT_EXTRA_MIN + ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters) + end + elseif EdgeToMachine.sType == 'Side' and #( Proc.MainFaces.SideFaces) == 0 then + sMortisingType = 'BothSidesAndExtend' + ToolSearchParameters.bExtendWithCornerRadius = true + ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation) / 2 + BeamData.CUT_EXTRA_MIN + ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters) + else + sMortisingType = 'OneSide' + ToolSearchParameters.bExtendWithCornerRadius = false + ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation) + BeamData.CUT_EXTRA + ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters) + end + if ToolSearchParameters.bExtendWithCornerRadius and ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL then + if sMortisingType == 'BothSidesAndExtend' then + sMortisingType = 'BothSides' + elseif sMortisingType == 'OneSideAndExtend' then + sMortisingType = 'OneSide' + end + ToolSearchParameters.bExtendWithCornerRadius = false + ToolSearchParameters.dElevation = nil + ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters) + end + Mortising.nToolIndex = ToolInfo.nToolIndex + Mortising.nType = MCH_OY.MORTISING + if not TOOLS[Mortising.nToolIndex].sName then + Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - chainsaw not found' + Mortising.bIsApplicable = false + EgtOutLog( Mortising.sMessage) + return Mortising, EdgeToMachine.dElevation + end + + -- verifica dimensioni tasca compatibili + -- se tasca meno spessa della sega a catena la strategia non è applicabile + if TOOLS[Mortising.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL then + Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for chainsaw thickness' + Mortising.bIsApplicable = false + EgtOutLog( Mortising.sMessage) + return Mortising, EdgeToMachine.dElevation + end + if #( 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 = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for chainsaw width' + Mortising.bIsApplicable = false + EgtOutLog( Mortising.sMessage) + return Mortising, EdgeToMachine.dElevation + end + end + + -- parametri della 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 EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then + Mortising.nWorkside = MCH_MILL_WS.RIGHT + Mortising.bToolInvert = false + else + Mortising.nWorkside = MCH_MILL_WS.LEFT + Mortising.bToolInvert = true + end + -- profondità e offset longitudinale + if sMortisingType == 'OneSide' then + Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) + elseif sMortisingType == 'OneSideAndExtend' then + Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) + TOOLS[Mortising.nToolIndex].dCornerRadius + BeamData.CUT_EXTRA_MIN + elseif sMortisingType == 'BothSides' then + Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) / 2 + elseif sMortisingType == 'BothSidesAndExtend' then + Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) / 2 + TOOLS[Mortising.nToolIndex].dCornerRadius + BeamData.CUT_EXTRA_MIN + end + if TOOLS[Mortising.nToolIndex].dMaxMaterial > Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then + if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then + Mortising.dLongitudinalOffset = 0 + else + Mortising.dLongitudinalOffset = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine + end + else + Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMaterial - 1 + Mortising.dResidualDepth = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine + if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then + Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - Mortising.dDepthToMachine + else + Mortising.dLongitudinalOffset = 0 + 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 + -- offset radiale + Mortising.dRadialOffset = 0 + -- distanza di sicurezza + Mortising.dStartSafetyLength = max( EdgeToMachine.dElevation, 10) + -- overlap + Mortising.dOverlap = 0 + -- step + Mortising.Steps = {} + if Strategy.Parameters.bUseZigZagMortising then + Mortising.Steps.nStepType = MCH_MILL_ST.ZIGZAG + else + Mortising.Steps.nStepType = MCH_MILL_ST.ONEWAY + end + -- faceuse + if EdgeToMachine.dElevation > - 10 * GEO.EPS_SMALL then + Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( EdgeToMachine.vtToolDirection) + else + Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( -EdgeToMachine.vtToolDirection) + end + -- SCC + Mortising.SCC = MCH_SCC.NONE + -- asse bloccato e angoli suggeriti + local vtRes = FaceToMachine.vtN ^ EdgeToMachine.vtToolDirection + 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.vtToolDirection, 1) + elseif EdgeToMachine.vtToolDirection:getZ() < 10 * GEO.EPS_SMALL then + Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN) + Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtToolDirection, 2) + end + -- approccio e retrazione + Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine) + -- 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) + + -- 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( Mortising.LeadIn.dStartAddLength, Mortising.LeadOut.dEndAddLength) + TOOLS[Mortising.nToolIndex].dWidth / 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 .. ' : chainsaw can damage next piece.' +-- if #Mortising.sMessage > 0 then +-- Mortising.sMessage = Mortising.sMessage .. '\n' .. sDamageNextPieceMessage +-- else +-- Mortising.sMessage = sDamageNextPieceMessage +-- end +-- EgtOutLog( sDamageNextPieceMessage) +-- end + + return Mortising +end + + +function AddMachiningAllSteps( Proc, Mortising) + local bIsMortisingOk = false + local sMortisingApplyMessage = '' + + local dOriginalRadialOffsetMortising = Mortising.dRadialOffset + for i = Mortising.VerticalSteps.nCount, 1, -1 do + Mortising.dRadialOffset = dOriginalRadialOffsetMortising + Mortising.VerticalSteps.dStepLength * ( i - 1) + -- applicazione lavorazione + bIsMortisingOk, sMortisingApplyMessage = MachiningLib.AddNewMachining( Proc, Mortising) + -- update messaggi + if sMortisingApplyMessage and #sMortisingApplyMessage > 0 then + Mortising.sMessage = Mortising.sMessage .. '\n' .. 'Apply : ' .. sMortisingApplyMessage .. '\n' + end + end + + return bIsMortisingOk, sMortisingApplyMessage +end + + +function SLOTBYCHAINSAW.Make( bAddMachining, Proc, Part, Parameters) + -- TODO da implementare gestione feature lunghe e spezzatura + Strategy.Parameters = Parameters + Strategy.Result = {} + Strategy.Result.sInfo = '' + + local Machinings = {} + + if not IsTopologyOk( Proc) then + local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented' + EgtOutLog( sErr) + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.sInfo = 'Topology' + return false, Strategy.Result + end + + -- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto) + if Proc.AffectedFaces.bBottom and ( Proc.nFct > 3 or not Proc.AffectedFaces.bTop) then + local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket on bottom face' + EgtOutLog( sErr) + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.sInfo = 'Direction' + return false, Strategy.Result + end + + if Proc.Topology.sFamily == 'Tunnel' then + -- Tunnel side 1 + Mortising = {} + Mortising.bIsApplicable = false + Mortising = CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], Part) + Machinings.TunnelSide1 = Mortising + -- Tunnel side 2 + Mortising = {} + Mortising.bIsApplicable = false + Mortising = CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], Part) + Machinings.TunnelSide2 = Mortising + + if Machinings.TunnelSide1.bIsApplicable and Machinings.TunnelSide1.dResidualDepth < GEO.EPS_SMALL then + + elseif Machinings.TunnelSide2.bIsApplicable and Machinings.TunnelSide2.dResidualDepth < GEO.EPS_SMALL then + + else + + end + else + -- Bottom + local Mortising = {} + Mortising.bIsApplicable = false + Mortising = CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, Part) + Machinings.Bottom = Mortising + -- Side (start) + Mortising = {} + Mortising.bIsApplicable = false + if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then + Mortising = CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], Part) + end + Machinings.SideStart = Mortising + -- Side (end) + Mortising = {} + Mortising.bIsApplicable = false + if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then + Mortising = CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], Part) + end + Machinings.SideEnd = Mortising + + if Machinings.Bottom.bIsApplicable and Machinings.Bottom.dResidualDepth < GEO.EPS_SMALL then + + elseif Machinings.SideStart.bIsApplicable and Machinings.SideStart.dResidualDepth < GEO.EPS_SMALL then + + elseif Machinings.SideEnd.bIsApplicable and Machinings.SideEnd.dResidualDepth < GEO.EPS_SMALL then + + end + end + + + + + + + + -- sega a catena + -- parametri lavorazione con sega a catena - fondo della tasca o tunnel + local Mortising = {} + if Proc.Topology.sFamily == 'Tunnel' then + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], Part) + else + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, Part) + -- si lavora solo quanto non lavorato dalla lama + Mortising.MaxElev = dBottomDepthToMachine + BeamData.CUT_EXTRA + end + if bAddMachining and Mortising.bIsApplicable then + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) + end + Chainsaw.AddResult( Mortising) + -- lato opposto del tunnel + if Proc.Topology.sFamily == 'Tunnel' then + if dResidualDepth > 10 * GEO.EPS_SMALL then + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], Part) + if bAddMachining and Mortising.bIsApplicable then + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) + end + Chainsaw.AddResult( Mortising) + end + else + -- se la sega a catena non è arrivata sul fondo e c'è almeno un lato aperto va lavorato + if dResidualDepth > 10 * GEO.EPS_SMALL then + -- eventuale lavorazione di sega a catena - lato della tasca da cui inizia la lavorazione + if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], Part) + if bAddMachining and Mortising.bIsApplicable then + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) + end + Chainsaw.AddResult( Mortising) + end + -- eventuale lavorazione di sega a catena - lato della tasca in cui finisce la lavorazione + if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], Part) + if bAddMachining and Mortising.bIsApplicable then + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) + end + Chainsaw.AddResult( Mortising) + end + end + end + + -- TODO da migliorare / refactoring in funzione + local nCanApplyCount = 0 + local nApplyOkCount = 0 + local bAreAllApplyOk + local dCompletionPercentage = 0 + for i = 1, #Chainsaw.Result do + Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result[i].sMessage .. '\n' .. ( Chainsaw.Result[i].sApplyMessage or '') + if Chainsaw.Result[i].bIsApplicable then + nCanApplyCount = nCanApplyCount + 1 + end + if Chainsaw.Result[i].bIsApplyOk then + nApplyOkCount = nApplyOkCount + 1 + end + end + if bAddMachining then + bAreAllApplyOk = ( nApplyOkCount == #Chainsaw.Result) + end + if nCanApplyCount == 0 then + Strategy.Result.sStatus = 'Not-Applicable' + else + dCompletionPercentage = GetCompletionPercentage( Proc, Chainsaw.Result) + if ( nCanApplyCount == #Chainsaw.Result) and dCompletionPercentage > 99 + 10 * GEO.EPS_SMALL then + Strategy.Result.sStatus = 'Completed' + else + Strategy.Result.sStatus = 'Not-Completed' + end + end + Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dCompletionPercentage) + Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Chainsaw') + local MRRParameters = { dStep = TOOLS[Cutting.nToolIndex].dThickness, + dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength), + dFeed = TOOLS[Cutting.nToolIndex].Feeds.dFeed} + Strategy.Result.dMRR = MachiningLib.GetToolMRR( MRRParameters) + + return bAreAllApplyOk, Strategy.Result +end + +------------------------------------------------------------------------------------------------------------- + + return STR0003 \ No newline at end of file diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index e022bdf..c186e37 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -153,7 +153,7 @@ end ------------------------------------------------------------------------------------------------------------- -- TODO valutare refactoring per mettere i calcoli del tunnel in una funzione --- TODO valutare se restituire anche altre informazioni oltre alle facce (es: box); magari metterle in funzione a parte chiamata allo stesso livello della GetMainFaces +-- TODO creare le facce tunnel solo se non ci sono già. Verirficare all'inizio se già presente in AddGrpId e nel caso riferire all'id di quella esistente e ricalcolare solo le informazioni della faccia. local function GetTunnelFaces( Proc, Part) local TunnelAddedFaces = {} diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 4c8327d..eb20abd 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -323,10 +323,12 @@ function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd) if not MachiningToAdd.sToolName then MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName end - local MachiningAppo = {} - MachiningAppo.Proc = ProcToAdd - MachiningAppo.Machining = MachiningToAdd - table.insert( MACHININGS, MachiningAppo) + + local Machining = {} + Machining.Proc = ProcToAdd + Machining.Machining = MachiningToAdd + table.insert( MACHININGS, Machining) + return true end diff --git a/Process.lua b/Process.lua index cea53a8..dc373cf 100644 --- a/Process.lua +++ b/Process.lua @@ -13,6 +13,7 @@ EgtEnableDebug( true) EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua') -- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\?.lua') +EgtAddToPackagePath( BEAM.BASEDIR .. '\\CoreStrategies\\?.lua') -- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi local sMachDir = EgtGetCurrMachineDir() @@ -57,6 +58,12 @@ for i = 1, 999 do _G.package.loaded[sLibraryConfigToReload] = nil end end +local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\CoreStrategies\\*.lua') +for i = 1, #vtCoreStrategiesNames do + if _G.package.loaded[vtCoreStrategiesNames[i]] then + _G.package.loaded[vtCoreStrategiesNames[i]] = nil + end +end local BeamExec = require( 'BeamExec') diff --git a/Strategies/STR0003/STR0003.lua b/Strategies/STR0003/STR0003.lua index 91f0a66..053d0b5 100644 --- a/Strategies/STR0003/STR0003.lua +++ b/Strategies/STR0003/STR0003.lua @@ -8,6 +8,8 @@ local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureData = require( 'FeatureData') +-- strategie di base +local SlotByChainSaw = BEAM.BASEDIR .. '\\CoreStrategies\\SLOTBYCHAINSAW.lua' -- Tabella per definizione modulo local STR0003 = {} @@ -59,9 +61,11 @@ end local function AddResult( Machining, Result) table.insert( Result, {}) - Result[#Result].bCanApply = Machining.bCanApply + Result[#Result].bIsApplicable = Machining.bIsApplicable Result[#Result].sMessage = Machining.sMessage Result[#Result].dDepthMachined = Machining.dDepthToMachine + Result[#Result].dResidualDepth = Machining.dResidualDepth + Result[#Result].dBladeMarkLength = Machining.dBladeMarkLength Result[#Result].bIsApplyOk = Machining.bIsApplyOk Result[#Result].sApplyMessage = Machining.sApplyMessage @@ -160,11 +164,12 @@ end function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, Part) local Cutting = {} - Cutting.bCanApply = true + Cutting.bIsApplicable = true Cutting.dDepthToMachine = 0 Cutting.sMessage = '' Cutting.idProc = Proc.id - local dResidualDepth = 0 + Cutting.dResidualDepth = 0 + Cutting.dBladeMarkLength = 0 local dPocketHeight = 0 if Proc.Topology.sFamily == 'Tunnel' then @@ -189,7 +194,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, Cutting.nType = MCH_OY.MILLING if not TOOLS[Cutting.nToolIndex].sName then Cutting.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - saw blade not found' - Cutting.bCanApply = false + Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end @@ -198,7 +203,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, -- se tasca meno spessa della lama la strategia non è applicabile if TOOLS[Cutting.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL then Cutting.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for saw blade thickness' - Cutting.bCanApply = false + Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end @@ -206,7 +211,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, -- se tasca più stretta della lama la strategia non è applicabile if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then Cutting.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for saw blade diameter' - Cutting.bCanApply = false + Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) return Cutting, EdgeToMachine.dElevation end @@ -247,7 +252,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, end else Cutting.dDepthToMachine = TOOLS[Cutting.nToolIndex].dMaxDepth - 1 - dResidualDepth = abs( EdgeToMachine.dElevation) - Cutting.dDepthToMachine + Cutting.dResidualDepth = abs( EdgeToMachine.dElevation) - Cutting.dDepthToMachine if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then Cutting.dRadialOffset = EdgeToMachine.dElevation - Cutting.dDepthToMachine else @@ -291,6 +296,14 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, Cutting.HorizontalSteps.nCount = 1 Cutting.HorizontalSteps.dStepLength = 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 @@ -309,7 +322,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, -- EgtOutLog( sDamageNextPieceMessage) -- end - return Cutting, dResidualDepth + return Cutting end @@ -344,7 +357,7 @@ end function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine, Part) local Mortising = {} - Mortising.bCanApply = true + Mortising.bIsApplicable = true Mortising.dDepthToMachine = 0 Mortising.sMessage = '' Mortising.idProc = Proc.id @@ -404,7 +417,7 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi Mortising.nType = MCH_OY.MORTISING if not TOOLS[Mortising.nToolIndex].sName then Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - chainsaw not found' - Mortising.bCanApply = false + Mortising.bIsApplicable = false EgtOutLog( Mortising.sMessage) return Mortising, EdgeToMachine.dElevation end @@ -413,7 +426,7 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi -- se tasca meno spessa della sega a catena la strategia non è applicabile if TOOLS[Mortising.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL then Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for chainsaw thickness' - Mortising.bCanApply = false + Mortising.bIsApplicable = false EgtOutLog( Mortising.sMessage) return Mortising, EdgeToMachine.dElevation end @@ -421,7 +434,7 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi -- 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 = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket too narrow for chainsaw width' - Mortising.bCanApply = false + Mortising.bIsApplicable = false EgtOutLog( Mortising.sMessage) return Mortising, EdgeToMachine.dElevation end @@ -584,37 +597,37 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) -- lavorazione di lama - fondo della tasca o fino a massimo materiale se tunnel local Cutting = {} if Proc.Topology.sFamily == 'Tunnel' then - Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], Part) + Cutting = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], Part) else - Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, Part) + Cutting = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, Part) end - if bAddMachining and Cutting.bCanApply then + if bAddMachining and Cutting.bIsApplicable then Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Proc, Cutting) end Blade.AddResult( Cutting) - local dBottomDepthToMachine = dResidualDepth + local dBottomDepthToMachine = Cutting.dResidualDepth -- lato opposto del tunnel if Proc.Topology.sFamily == 'Tunnel' then - Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], Part) - if bAddMachining and Cutting.bCanApply then + Cutting = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], Part) + if bAddMachining and Cutting.bIsApplicable then Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Proc, Cutting) end Blade.AddResult( Cutting) else -- se la lama non è arrivata sul fondo e c'è almeno un lato aperto va lavorato - if dResidualDepth > 10 * GEO.EPS_SMALL then + if Cutting.dResidualDepth > 10 * GEO.EPS_SMALL then -- eventuale lavorazione di lama - lato della tasca da cui inizia la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then - Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], Part) - if bAddMachining and Cutting.bCanApply then + Cutting = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], Part) + if bAddMachining and Cutting.bIsApplicable then Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Proc, Cutting) end Blade.AddResult( Cutting) end -- eventuale lavorazione di lama - lato della tasca in cui finisce la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then - Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], Part) - if bAddMachining and Cutting.bCanApply then + Cutting = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], Part) + if bAddMachining and Cutting.bIsApplicable then Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Proc, Cutting) end Blade.AddResult( Cutting) @@ -634,7 +647,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) local dCompletionPercentage = 0 for i = 1, #Blade.Result do Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result[i].sMessage .. '\n' .. ( Blade.Result[i].sApplyMessage or '') - if Blade.Result[i].bCanApply then + if Blade.Result[i].bIsApplicable then nCanApplyCount = nCanApplyCount + 1 end if Blade.Result[i].bIsApplyOk then @@ -664,6 +677,35 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) return bAreAllApplyOk, Strategy.Result end + + -- sega a catena + if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then + if ( Blade.Result[1].dResidualDepth < GEO.EPS_SMALL) and + ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength > 3 * Blade.Result[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then + + end + + elseif Proc.Topology.sName == 'Groove-3-Through' then + + elseif Proc.Topology.sName == 'Tunnel-4-Through' then + + end + + + + + + + + + + + + + + + + -- sega a catena -- parametri lavorazione con sega a catena - fondo della tasca o tunnel local Mortising = {} @@ -674,7 +716,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) -- si lavora solo quanto non lavorato dalla lama Mortising.MaxElev = dBottomDepthToMachine + BeamData.CUT_EXTRA end - if bAddMachining and Mortising.bCanApply then + if bAddMachining and Mortising.bIsApplicable then Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) end Chainsaw.AddResult( Mortising) @@ -682,7 +724,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) if Proc.Topology.sFamily == 'Tunnel' then if dResidualDepth > 10 * GEO.EPS_SMALL then Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], Part) - if bAddMachining and Mortising.bCanApply then + if bAddMachining and Mortising.bIsApplicable then Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) end Chainsaw.AddResult( Mortising) @@ -693,7 +735,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) -- eventuale lavorazione di sega a catena - lato della tasca da cui inizia la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], Part) - if bAddMachining and Mortising.bCanApply then + if bAddMachining and Mortising.bIsApplicable then Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) end Chainsaw.AddResult( Mortising) @@ -701,7 +743,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) -- eventuale lavorazione di sega a catena - lato della tasca in cui finisce la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], Part) - if bAddMachining and Mortising.bCanApply then + if bAddMachining and Mortising.bIsApplicable then Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Proc, Mortising) end Chainsaw.AddResult( Mortising) @@ -716,7 +758,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) local dCompletionPercentage = 0 for i = 1, #Chainsaw.Result do Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result[i].sMessage .. '\n' .. ( Chainsaw.Result[i].sApplyMessage or '') - if Chainsaw.Result[i].bCanApply then + if Chainsaw.Result[i].bIsApplicable then nCanApplyCount = nCanApplyCount + 1 end if Chainsaw.Result[i].bIsApplyOk then