-- Strategia: STR0002 -- Descrizione -- Svuotatura tasca -- Feature tipo LapJpint -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureData = require( 'FeatureData') -- Tabella per definizione modulo local STR0002 = {} local Strategy = {} ------------------------------------------------------------------------------------------------------------- local function IsTopologyOk( Proc) if Proc.Topology.sName == 'Pocket-5-Blind' or Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Tunnel-4-Through' or Proc.Topology.sName == 'Groove-3-Through' then return true else return false end end ------------------------------------------------------------------------------------------------------------- local function CalcMachinedPercentage( Proc, Machining) local dPercentage local dBottomElevation = Proc.MainFaces.BottomFace.dElevation local dBottomPrercentage = ( dBottomElevation - Machining[1].ToolInfo.dResidualDepth) / dBottomElevation local dBottomPrercentageLeft = 1 - dBottomPrercentage if Machining.sTypeMachining == 'None' then dPercentage = 0 elseif Machining.sTypeMachining == 'Bottom' then dPercentage = dBottomPrercentage elseif Proc.MainFaces.TunnelAddedFaces then local TunnelAddedFacesElevation = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation local dSide1Prercentage = ( ( TunnelAddedFacesElevation * 2) - Machining[2].ToolInfo.dResidualDepth) / ( TunnelAddedFacesElevation * 2) local dSide2Prercentage = ( ( TunnelAddedFacesElevation * 2) - Machining[3].ToolInfo.dResidualDepth) / ( TunnelAddedFacesElevation * 2) if Machining.sTypeMachining == 'Side1' then dPercentage = dSide1Prercentage elseif Machining.sTypeMachining == 'Side2' then dPercentage = dSide2Prercentage elseif Machining.sTypeMachining == 'Bottom-Side1-Side2' then dPercentage = dBottomPrercentage + ( dBottomPrercentageLeft * ( dSide1Prercentage + dSide2Prercentage)) * 100 elseif Machining.sTypeMachining == 'Bottom-Side1' then dPercentage = dBottomPrercentage + ( dBottomPrercentageLeft * dSide1Prercentage) * 100 elseif Machining.sTypeMachining == 'Bottom-Side2' then dPercentage = dBottomPrercentage + ( dBottomPrercentageLeft * dSide2Prercentage) * 100 elseif Machining.sTypeMachining == 'Side1-Side2' then dPercentage = dSide1Prercentage + dSide2Prercentage end end return dPercentage * 100 end ------------------------------------------------------------------------------------------------------------- local function GetBestPocketingStrategy( Proc) -- imposto paraemtri di ricerca utensile in base a topologia local Machining = {} local Milling = {} local ToolSearchParameters = {} ToolSearchParameters.sMillShape = 'STANDARD' Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Mill') -- imposto dati per cercare la fresa migliore if Proc.Topology.sName == 'Pocket-5-Blind' then ToolSearchParameters.sType = 'MILL_STD' ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, Proc.MainFaces.BottomFace.dHeight, Proc.MainFaces.BottomFace.dWidth) elseif Proc.Topology.sName == 'Tunnel-4-Through' then ToolSearchParameters.sType = 'MILL_STD' ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dHeight, Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dWidth) -- cerco fresa che può anche non lavorare di testa elseif Proc.Topology.sName == 'Groove-4-Blind' then ToolSearchParameters.sType = 'MILL_NOTIP' ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, Proc.MainFaces.BottomFace.dWidth) elseif Proc.Topology.sName == 'Groove-3-Through' then ToolSearchParameters.sType = 'MILL_NOTIP' ToolSearchParameters.dMaxToolDiameter = Proc.MainFaces.BottomFace.dHeight end -- ===== RICERCA UTENSILE ===== -- cerco utensile per lavorare faccia Bottom Milling.bIsApplicable = false if Proc.Topology.sName ~= 'Tunnel-4-Through' then ToolSearchParameters.dElevation = Proc.MainFaces.BottomFace.dElevation ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFace.vtN Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) if Milling.ToolInfo.nToolIndex then Milling.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) end end table.insert( Machining, Milling) -- cerco utensile per lavorare di fianco 1 Milling = {} Milling.bIsApplicable = false if Proc.Topology.sName ~= 'Pocket-5-Blind' then if Proc.Topology.sName == 'Groove-4-Blind' then ToolSearchParameters.dElevation = Proc.MainFaces.SideFaces[1].dElevation ToolSearchParameters.vtToolDirection = Proc.MainFaces.SideFaces[1].vtN else ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP ToolSearchParameters.vtToolDirection = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN end Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) if Milling.ToolInfo.nToolIndex then Milling.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) end end table.insert( Machining, Milling) -- cerco utensile per lavorare di fianco 2 Milling = {} Milling.bIsApplicable = false if Proc.Topology.sName == 'Tunnel-4-Through' or Proc.Topology.sName == 'Groove-3-Through' then ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP ToolSearchParameters.vtToolDirection = -Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN Milling.ToolInfo = {} Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) if Milling.ToolInfo.nToolIndex then Milling.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) end end table.insert( Machining, Milling) -- ===== SCELTA LAVORAZIONI ===== -- se lavorazione della faccia bottom è completa, non controllo le altre if Machining[1].bIsApplicable then Machining.sTypeMachining = 'Bottom' -- se completo if Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100) else Strategy.Result.sStatus = 'Not-Completed' Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( Machining[1].ToolInfo.dResidualDepth) .. 'mm' local dCompletionPercentage = min( 100, ( ( Proc.MainFaces.BottomFace.dElevation - Machining[1].ToolInfo.dResidualDepth) / Proc.MainFaces.BottomFace.dElevation) * 100) Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dCompletionPercentage) end -- se tasca, esco subito. Non ci sono altre possibilità if Proc.Topology.sName == 'Pocket-5-Blind' then Strategy.Result.dMRR = Machining[1].dMRR return Machining end end -- se bottom completa tutto if Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then Machining.sTypeMachining = 'Bottom' Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100) Strategy.Result.dMRR = Machining[1].dMRR return Machining -- se la 2 completa tutto elseif Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then Machining.sTypeMachining = 'Side1' Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100) Strategy.Result.dMRR = Machining[2].dMRR return Machining -- se la 3 completa tutto elseif Machining[3].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then Machining.sTypeMachining = 'Side2' Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100) Strategy.Result.dMRR = Machining[3].dMRR return Machining -- se 2+3 completa tutto elseif Machining[2].bIsApplicable and Machining[3].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP/2 and Machining[3].ToolInfo.dResidualDepth < Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP/2 then Machining.sTypeMachining = 'Side1-Side2' Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100) Strategy.Result.dMRR = ( Machining[2].dMRR + Machining[3].dMRR) / 2 return Machining end Strategy.Result.sStatus = 'Not-Completed' if Machining[1].bIsApplicable then if Machining[2].bIsApplicable then if Machining[3].bIsApplicable then Machining.sTypeMachining = 'Bottom-Side1-Side2' Strategy.Result.dMRR = ( Machining[1].dMRR + Machining[2].dMRR + Machining[3].dMRR) / 3 else Machining.sTypeMachining = 'Bottom-Side1' Strategy.Result.dMRR = ( Machining[1].dMRR + Machining[2].dMRR) / 2 end else if Machining[3].bIsApplicable then Machining.sTypeMachining = 'Bottom-Side2' Strategy.Result.dMRR = ( Machining[1].dMRR + Machining[3].dMRR) / 2 else Machining.sTypeMachining = 'Bottom' Strategy.Result.dMRR = Machining[1].dMRR end end else if Machining[2].bIsApplicable then if Machining[3].bIsApplicable then Machining.sTypeMachining = 'Side1-Side2' Strategy.Result.dMRR = ( Machining[2].dMRR + Machining[3].dMRR) / 2 else Machining.sTypeMachining = 'Side1' Strategy.Result.dMRR = Machining[2].dMRR end else if Machining[3].bIsApplicable then Machining.sTypeMachining = 'Side2' Strategy.Result.dMRR = Machining[3].dMRR else Machining.sTypeMachining = 'None' Strategy.Result.dMRR = 0 end end end local dMachinedPrercentage = CalcMachinedPercentage( Proc, Machining) Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dMachinedPrercentage) Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100-dMachinedPrercentage) .. '%' -- se non ho trovato neanche una lavorazione if Machining.sTypeMachining == 'None' then Strategy.Result.sStatus = 'Not-Applicable' Strategy.Result.nCompletionIndex = 0 Strategy.Result.dMRR = 0 Strategy.Result.nQuality = 0 Strategy.Result.sInfo = 'Mill not found' end return Machining end ------------------------------------------------------------------------------------------------------------- function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) -- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) local StrategyLib = {} StrategyLib.Config = require( 'STR0002\\STR0002Config') Strategy.sName = StrategyLib.Config.sStrategyId CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) Strategy.Machining = {} Strategy.Result = {} if not IsTopologyOk( Proc) then local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.Config.sStrategyId .. ' not implemented' EgtOutLog( sErr) Strategy.Result.sStatus = 'Not-Applicable' Strategy.Result.nCompletionIndex = 0 Strategy.Result.dMRR = 0 Strategy.Result.nQuality = 0 Strategy.Result.sInfo = sErr return false, Strategy.Result end local bApplyMachiningOK = true local ToolInfo = {} local Pocketing = {} Pocketing.Steps = {} Pocketing.LeadIn = {} Strategy.Machining = GetBestPocketingStrategy( Proc) if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then -- le lunghezza richiede spezzatura if ( Proc.b3Box:getDimX() > BeamData.LONGCUT_MAXLEN) or ( Proc.b3Box:getDimX() > 0.7 * Part.b3Solid:getDimX() and Proc.b3Box:getDimX() > BeamData.LONGCUT_ENDLEN) then -- recupero gruppo per geometria aggiuntiva local nAddGrpId = BeamLib.GetAddGroup( Part.idPart) local vAddId = {} local bStartLeft, bStartRight -- se feature inizia al di sotto del limite sinistro if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN then bStartLeft = true end -- se feature inizia al di sotto del limite destro if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN then bStartRight = true end -- salvo valori local dNewMinX = Proc.b3Box:getMin():getX() local dNewMaxX = Proc.b3Box:getMax():getX() local dNewRest = Proc.b3Box:getDimX() -- creo primo spezzone sulla sinistra if bStartLeft then local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL dNewMinX = max( ( Proc.b3Box:getMin():getX() + TOOLS[ToolInfo.nToolIndex].dDiameter * 2), Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN) local ptOn = Point3d( dNewMinX, 0, 0) dNewRest = abs( dNewMaxX - dNewMinX) -- taglio della superficie lato sinistro EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) -- eseguo inserimento table.insert( vAddId, AddId) end -- creo spezzone sulla destra if bStartRight then local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL dNewMaxX = min( ( Proc.b3Box:getMax():getX() - TOOLS[ToolInfo.nToolIndex].dDiameter * 2), Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN) local ptOn = Point3d( dNewMaxX, 0, 0) dNewRest = abs( dNewMaxX - dNewMinX) -- taglio della superficie lato destro EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) -- eseguo inserimento table.insert( vAddId, EgtIf( BeamData.RIGHT_LOAD, 2, 1),AddId) end -- lavoro il restante local nSplitParts = max( ceil( dNewRest / BeamData.LONGCUT_MAXLEN + 10 * GEO.EPS_SMALL), 2) local dSplitPartsLen = dNewRest / nSplitParts for i = 1, nSplitParts do local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL local ptOn -- eseguo trim sinistro if i ~= 1 or bStartLeft then ptOn = Point3d( dNewMinX, 0, 0) -- taglio della superficie lato sinistro EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) end -- eseguo trim destro dNewMaxX = dNewMinX + dSplitPartsLen if i ~= nSplitParts or bStartRight then ptOn = Point3d( dNewMaxX, 0, 0) -- taglio della superficie lato destro EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) end -- il nuovo minimo è il punto massimo del precedente dNewMinX = dNewMaxX -- eseguo inserimento in modo da ordinare da X- a X+ table.insert( vAddId, EgtIf( BeamData.RIGHT_LOAD, 1+i, EgtIf( bStartLeft, 1, 2)), AddId) end -- si applicano le lavorazioni for i = 1, #vAddId do Pocketing.nToolIndex = ToolInfo.nToolIndex Pocketing.nType = MCH_OY.POCKETING Pocketing.Steps.dStep = TOOLS[ToolInfo.nToolIndex].dStep Pocketing.dDepth = min( 0, -ToolInfo.dResidualDepth) Pocketing.Steps.dSideStep = TOOLS[ToolInfo.nToolIndex].dSideStep Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG Pocketing.LeadIn.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter/2 Pocketing.LeadIn.dElevation = TOOLS[ToolInfo.nToolIndex].dDiameter/2 -- TODO settare parametro per indicare qual è lo spezzone che deve essere fatto dopo il taglio di separazione for j=1, Proc.nFct do local vtNSplitFace _, vtNSplitFace = EgtSurfTmFacetCenter( vAddId[i], j - 1, GDB_ID.ROOT) if vtNSplitFace and AreSameVectorExact( vtNSplitFace, Proc.MainFaces.BottomFace.vtN) then Pocketing.idFaceToMachine = j - 1 Pocketing.idProc = vAddId[i] bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing) break end end end else Pocketing.nToolIndex = Strategy.Machining[1].ToolInfo.nToolIndex Pocketing.nType = MCH_OY.POCKETING Pocketing.Steps.dStep = TOOLS[Strategy.Machining[1].ToolInfo.nToolIndex].dStep Pocketing.dDepth = min( 0, -Strategy.Machining[1].ToolInfo.dResidualDepth) Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[1].ToolInfo.nToolIndex].dSideStep Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining[1].ToolInfo.nToolIndex].dDiameter/2 Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining[1].ToolInfo.nToolIndex].dDiameter/2 Pocketing.idFaceToMachine = Proc.MainFaces.BottomFace.id Pocketing.idProc = Proc.id bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing) end else bApplyMachiningOK = false end return bApplyMachiningOK, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0002