588 lines
30 KiB
Lua
588 lines
30 KiB
Lua
-- Strategia: STR0002
|
|
-- Descrizione
|
|
-- Svuotatura tasca
|
|
-- Feature tipo LapJoint
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- TODO
|
|
-- 1 - Inserire antischeggia (fresa o lama)
|
|
-- 2 - Modalità svuotatura con fresa grande e spigoli con fresa piccola
|
|
-- 3 - Smusso a V
|
|
-- 4 - Finitura con motosega (se la fresa non completa)
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
-- carico librerie
|
|
local BeamLib = require( 'BeamLib')
|
|
local BeamData = require( 'BeamData')
|
|
local MachiningLib = require( 'MachiningLib')
|
|
local FeatureLib = require( 'FeatureLib')
|
|
|
|
-- Tabella per definizione modulo
|
|
local STR0002 = {}
|
|
local Strategy = {}
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function IsTopologyOk( Proc)
|
|
if Proc.Topology.sName == 'Pocket-5-Blind' or
|
|
Proc.Topology.sName == 'Tunnel-4-Through' or
|
|
Proc.Topology.sName == 'Groove-4-Blind' or
|
|
Proc.Topology.sName == 'Groove-3-Through' or
|
|
Proc.Topology.sName == 'Groove-3-Blind' or
|
|
Proc.Topology.sName == 'Bevel-3-Blind' or
|
|
Proc.Topology.sName == 'Rabbet-2-Through' or
|
|
Proc.Topology.sName == 'DoubleBevel-2-Through' or
|
|
Proc.Topology.sName == 'VGroove-2-Through' or
|
|
Proc.Topology.sName == 'Cut-1-Through' or
|
|
Proc.Topology.sName == 'Bevel-1-Through' then
|
|
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function GetSCC( Proc, Pocketing)
|
|
local nSCC
|
|
|
|
if Pocketing.vtToolDirection:getY() > 0 then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
|
|
return nSCC
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CalcMachinedPercentage( Proc, Machining)
|
|
-- se non ci sono lavorazioni esco subito
|
|
if Machining.sTypeMachining == 'None' then
|
|
return 0
|
|
end
|
|
|
|
local dTotalPercentage = 0
|
|
local dPercentageBottom = 0
|
|
|
|
if Machining[1].bIsApplicable then
|
|
dTotalPercentage = ( Machining[1].dElevation - Machining[1].ToolInfo.dResidualDepth) / Machining[1].dElevation
|
|
dPercentageBottom = dTotalPercentage
|
|
end
|
|
if Machining[2].bIsApplicable then
|
|
local dAbsPercentage = ( Machining[2].dElevation - Machining[2].ToolInfo.dResidualDepth) / Machining[2].dElevation
|
|
dTotalPercentage = dTotalPercentage + ( 1 - dTotalPercentage) * dAbsPercentage
|
|
end
|
|
if Machining[3].bIsApplicable then
|
|
local dAbsPercentage
|
|
if Machining[3].bMachAppliedToTunnelFace then
|
|
dAbsPercentage = ( Machining[3].dElevation - Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation) / Machining[3].dElevation
|
|
else
|
|
dAbsPercentage = ( Machining[3].dElevation - Machining[3].ToolInfo.dResidualDepth) / Machining[3].dElevation
|
|
end
|
|
dTotalPercentage = dTotalPercentage + ( 1 - dPercentageBottom) * dAbsPercentage
|
|
end
|
|
if Machining[4].bIsApplicable then
|
|
local dAbsPercentage
|
|
if Machining[3].bMachAppliedToTunnelFace then
|
|
dAbsPercentage = ( Machining[4].dElevation - Machining[4].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation) / Machining[4].dElevation
|
|
else
|
|
dAbsPercentage = ( Machining[4].dElevation - Machining[4].ToolInfo.dResidualDepth) / Machining[4].dElevation
|
|
end
|
|
dTotalPercentage = dTotalPercentage + ( 1 - dPercentageBottom) * dAbsPercentage
|
|
end
|
|
|
|
return dTotalPercentage * 100
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- TODO vedere se sostituire GetFeatureQuality con valore da utensile; MillOnAggregate che qualità ha? da gestire in info utensile
|
|
-- TODO va gestita meglio la decisione delle facce da lavorare
|
|
local function GetBestPocketingStrategy( Proc)
|
|
-- imposto parametri 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 = FeatureLib.GetFeatureQuality( 'Mill')
|
|
|
|
-- caso speciale Tunnel che non ha faccia bottom
|
|
if Proc.Topology.sName == 'Tunnel-4-Through' then
|
|
local dFaceHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
|
|
local dFaceWidth = Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength
|
|
ToolSearchParameters.sType = 'MILL_STD'
|
|
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceHeight, dFaceWidth)
|
|
-- imposto dati per cercare la fresa migliore
|
|
elseif Proc.Topology.sName == 'Pocket-5-Blind' then
|
|
local dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
|
|
local dFaceHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
|
ToolSearchParameters.sType = 'MILL_STD'
|
|
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceHeight, dFaceWidth)
|
|
-- cerco fresa che può anche non lavorare di testa
|
|
elseif Proc.Topology.sName == 'Groove-4-Blind' then
|
|
local dFaceWidth = Proc.MainFaces.BottomFaces[2].MainEdges.BottomEdge.dLength
|
|
ToolSearchParameters.sType = 'MILL_NOTIP'
|
|
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceWidth)
|
|
elseif Proc.Topology.sName == 'Groove-3-Through' or Proc.Topology.sName == 'Bevel-3-Blind' then
|
|
local dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
|
ToolSearchParameters.sType = 'MILL_NOTIP'
|
|
ToolSearchParameters.dMaxToolDiameter = dFaceWidth
|
|
elseif Proc.Topology.sName == 'Groove-3-Blind' then
|
|
ToolSearchParameters.sType = 'MILL_NOTIP'
|
|
ToolSearchParameters.dMaxToolDiameter = Strategy.Parameters.dMaxCornerRadius * 2
|
|
elseif Proc.Topology.sName == 'Rabbet-2-Through'
|
|
or Proc.Topology.sName == 'DoubleBevel-2-Through'
|
|
or Proc.Topology.sName == 'VGroove-2-Through'
|
|
or Proc.Topology.sName == 'Cut-1-Through'
|
|
or Proc.Topology.sName == 'Bevel-1-Through' then
|
|
|
|
ToolSearchParameters.sType = 'MILL_NOTIP'
|
|
ToolSearchParameters.dMaxToolDiameter = 9999
|
|
else
|
|
return nil
|
|
end
|
|
|
|
-- ===== RICERCA UTENSILE =====
|
|
-- cerco utensile per lavorare faccia Bottom
|
|
Milling.bIsApplicable = false
|
|
if Proc.Topology.sName ~= 'Tunnel-4-Through' then
|
|
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id
|
|
Milling.idProc = Proc.id
|
|
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN
|
|
Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
|
|
Milling.ToolInfo = {}
|
|
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
|
if Milling.ToolInfo.nToolIndex then
|
|
-- se utensile scelto è su aggregato, ricalcolo la qualità
|
|
if TOOLS[Milling.ToolInfo.nToolIndex].SetupInfo.bToolOnAggregate then
|
|
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'MillOnAggregate')
|
|
end
|
|
Milling.bIsApplicable = true
|
|
local ParametersMRR = {}
|
|
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
|
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
|
end
|
|
end
|
|
table.insert( Machining, Milling)
|
|
|
|
-- caso speciale 'Rabbet-2-Through' seconda faccia principale
|
|
Milling = {}
|
|
Milling.bIsApplicable = false
|
|
if Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
|
|
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
|
|
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
|
|
Milling.idProc = Proc.id
|
|
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
|
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 ~= 'DoubleBevel-2-Through'
|
|
and Proc.Topology.sName ~= 'Pocket-5-Blind' then
|
|
|
|
if Proc.Topology.sName == 'Groove-4-Blind' then
|
|
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
|
|
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
|
|
Milling.idProc = Proc.id
|
|
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
|
|
elseif Proc.Topology.sName == 'Groove-3-Blind' or Proc.Topology.sName == 'Bevel-3-Blind' then
|
|
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
|
|
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
|
|
Milling.idProc = Proc.id
|
|
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation
|
|
elseif Proc.MainFaces.TunnelAddedFaces then -- 'Tunnel-4-Through', 'Groove-3-Through', 'Rabbet-2-Through', 'VGroove-2-Through'
|
|
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
|
|
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
|
|
ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
|
|
Milling.vtFaceNormal = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].id
|
|
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
|
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
|
Milling.bMachAppliedToTunnelFace = true
|
|
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 ~= 'DoubleBevel-2-Through'
|
|
and Proc.Topology.sName ~= 'Pocket-5-Blind'
|
|
and Proc.Topology.sName ~= 'Groove-4-Blind'
|
|
and Proc.Topology.sName ~= 'Bevel-3-Blind' then
|
|
|
|
if Proc.MainFaces.TunnelAddedFaces then -- Tunnel-4-Through, Groove-3-Through, Rabbet-2-Through, VGroove-2-Through
|
|
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
|
|
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
|
|
ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
|
ToolSearchParameters.vtToolDirection = -Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
|
|
Milling.vtFaceNormal = -Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].id
|
|
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
|
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
|
Milling.bToolInvert = true
|
|
Milling.bMachAppliedToTunnelFace = true
|
|
elseif #Proc.MainFaces.SideFaces > 0 then -- 'Groove-3-Blind'
|
|
ToolSearchParameters.dElevation = Proc.MainFaces.SideFaces[1].dElevation
|
|
ToolSearchParameters.vtToolDirection = Proc.MainFaces.SideFaces[1].vtN
|
|
Milling.vtFaceNormal = Proc.MainFaces.SideFaces[1].vtN
|
|
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
|
|
Milling.idProc = Proc.id
|
|
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
|
|
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)
|
|
|
|
-- ===== SCELTA LAVORAZIONI =====
|
|
-- 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 = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.dMRR = Machining[1].dMRR
|
|
Machining[1].ToolInfo.dResidualDepth = 0
|
|
Machining[3].bIsApplicable = false
|
|
Machining[4].bIsApplicable = false
|
|
-- caso speciale in cui si devono lavorare due facce
|
|
if ( Proc.nFct == 2 and Proc.AdjacencyMatrix[1][2] >= -89.9)
|
|
and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
|
|
|
Machining.sTypeMachining = 'Bottom2'
|
|
Strategy.Result.sStatus = 'Completed'
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.dMRR = Machining[2].dMRR
|
|
Machining[2].ToolInfo.dResidualDepth = 0
|
|
else
|
|
Machining[2].bIsApplicable = false
|
|
end
|
|
return Machining
|
|
-- caso speciale 'Rabbet-2-Through' che ha la seconda faccia come se fosse una seconda bottom
|
|
elseif ( Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' )
|
|
and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
|
Machining.sTypeMachining = 'Bottom2'
|
|
Strategy.Result.sStatus = 'Completed'
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.dMRR = Machining[2].dMRR
|
|
Machining[2].ToolInfo.dResidualDepth = 0
|
|
Machining[1].bIsApplicable = false
|
|
Machining[3].bIsApplicable = false
|
|
Machining[4].bIsApplicable = false
|
|
return Machining
|
|
-- se la 3 completa tutto
|
|
elseif Machining[3].bIsApplicable and Machining[3].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
|
Machining.sTypeMachining = 'Side1'
|
|
-- TODO setto non completo perchè è rimasto il raggio sullo spigolo. E' giusto considerare non completo?
|
|
if Proc.Topology.sName == 'Groove-3-Through' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
|
|
Strategy.Result.sStatus = 'Not-Completed'
|
|
else
|
|
Strategy.Result.sStatus = 'Completed'
|
|
end
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'RadiusOnCornerLeft')
|
|
Strategy.Result.dMRR = Machining[3].dMRR
|
|
if Proc.MainFaces.TunnelAddedFaces then
|
|
Machining[3].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
|
|
else
|
|
Machining[3].ToolInfo.dResidualDepth = 0
|
|
end
|
|
Machining[1].bIsApplicable = false
|
|
Machining[2].bIsApplicable = false
|
|
Machining[4].bIsApplicable = false
|
|
return Machining
|
|
-- se la 4 completa tutto
|
|
elseif Machining[4].bIsApplicable and Machining[4].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
|
Machining.sTypeMachining = 'Side2'
|
|
-- TODO setto non completo perchè è rimasto il raggio sullo spigolo. E' giusto considerare non completo?
|
|
if Proc.Topology.sName == 'Groove-3-Through' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
|
|
Strategy.Result.sStatus = 'Not-Completed'
|
|
else
|
|
Strategy.Result.sStatus = 'Completed'
|
|
end
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'RadiusOnCornerLeft')
|
|
Strategy.Result.dMRR = Machining[4].dMRR
|
|
if Proc.MainFaces.TunnelAddedFaces then
|
|
Machining[4].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
|
|
else
|
|
Machining[4].ToolInfo.dResidualDepth = 0
|
|
end
|
|
Machining[1].bIsApplicable = false
|
|
Machining[2].bIsApplicable = false
|
|
Machining[3].bIsApplicable = false
|
|
return Machining
|
|
-- se tunnel 3+4 completa tutto
|
|
elseif Proc.MainFaces.TunnelAddedFaces and Machining[3].bIsApplicable and Machining[4].bIsApplicable and
|
|
Machining[3].ToolInfo.dResidualDepth + Machining[4].ToolInfo.dResidualDepth < (Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP then
|
|
Machining.sTypeMachining = 'Side1-Side2'
|
|
-- TODO setto non completo perchè è rimasto il raggio sullo spigolo. E' giusto considerare non completo?
|
|
if Proc.Topology.sName == 'Groove-3-Through' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
|
|
Strategy.Result.sStatus = 'Not-Completed'
|
|
else
|
|
Strategy.Result.sStatus = 'Completed'
|
|
end
|
|
Machining[3].ToolInfo.dResidualDepth = Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation
|
|
Machining[4].ToolInfo.dResidualDepth = -Machining[3].ToolInfo.dResidualDepth - BeamData.MILL_OVERLAP
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
|
|
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'RadiusOnCornerLeft')
|
|
Strategy.Result.dMRR = ( Machining[3].dMRR + Machining[4].dMRR) / 2
|
|
Machining[1].bIsApplicable = false
|
|
Machining[2].bIsApplicable = false
|
|
return Machining
|
|
end
|
|
|
|
Strategy.Result.sStatus = 'Not-Completed'
|
|
Strategy.Result.dMRR = 0
|
|
if Machining[1].bIsApplicable then
|
|
Machining.sTypeMachining = 'Bottom'
|
|
Strategy.Result.dMRR = Machining[1].dMRR
|
|
end
|
|
if Machining[2].bIsApplicable then
|
|
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Bottom2', Machining.sTypeMachining .. '-Bottom2')
|
|
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[2].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
|
|
end
|
|
if Machining[3].bIsApplicable then
|
|
if Proc.MainFaces.TunnelAddedFaces then
|
|
Machining[3].ToolInfo.dResidualDepth = Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP
|
|
end
|
|
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Side1', Machining.sTypeMachining .. '-Side1')
|
|
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[3].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
|
|
end
|
|
if Machining[4].bIsApplicable then
|
|
if Proc.MainFaces.TunnelAddedFaces then
|
|
Machining[4].ToolInfo.dResidualDepth = Machining[4].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP
|
|
end
|
|
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Side2', Machining.sTypeMachining .. '-Side2')
|
|
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[4].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
|
|
end
|
|
|
|
local dMachinedPrercentage = CalcMachinedPercentage( Proc, Machining)
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
|
|
Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
|
|
|
|
-- se non ho trovato neanche una lavorazione
|
|
if Machining.sTypeMachining == 'None' then
|
|
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Mill not found')
|
|
end
|
|
|
|
return Machining
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function GetSplitSurfaces( Proc, Part, bAddMachining)
|
|
local vAddId = {}
|
|
local vAddIdTunnel = {}
|
|
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
|
local nOriginalTmIdTunnel = GDB_ID.NULL
|
|
if Proc.MainFaces.TunnelAddedFaces then
|
|
nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
|
end
|
|
|
|
-- recupero punti di spezzatura - da destra a sinistra
|
|
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
|
|
|
if #FeatureSplittingPoints == 0 then
|
|
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
|
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
|
if not bAddMachining then
|
|
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
|
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
|
end
|
|
table.insert( vAddId, nAddId)
|
|
table.insert( vAddIdTunnel, nAddIdTunnel)
|
|
else
|
|
for i = 1, #FeatureSplittingPoints do
|
|
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
|
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
|
if i == 1 then
|
|
-- prima superficie, va tagliata solo a sinistra
|
|
local ptSplit = FeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
|
|
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
|
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
|
else
|
|
-- taglio della superficie corrente - lato sinistro
|
|
local ptSplit = FeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
|
|
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
|
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
|
|
-- taglio della superficie corrente - lato destro
|
|
ptSplit = FeatureSplittingPoints[i - 1] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
|
|
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
|
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
|
end
|
|
if not bAddMachining then
|
|
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
|
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
|
end
|
|
table.insert( vAddId, nAddId)
|
|
table.insert( vAddIdTunnel, nAddIdTunnel)
|
|
end
|
|
-- taglio ultima superficie, va tagliata solo a destra
|
|
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
|
|
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
|
|
local ptSplit = FeatureSplittingPoints[#FeatureSplittingPoints] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
|
|
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
|
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
|
|
if not bAddMachining then
|
|
EgtSetLevel( nAddId, GDB_LV.TEMP)
|
|
EgtSetLevel( nAddIdTunnel, GDB_LV.TEMP)
|
|
end
|
|
table.insert( vAddId, nAddId)
|
|
table.insert( vAddIdTunnel, nAddIdTunnel)
|
|
end
|
|
|
|
return vAddId, vAddIdTunnel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- TODO rimuovere il calcolo MRR dove non serve, è fatto tutto alla fine.
|
|
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 = STRATEGIES_CONFIG[CustomParameters.sStrategyId]
|
|
Strategy.sName = StrategyLib.Config.sStrategyId
|
|
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, CustomParameters, StrategyLib.Config)
|
|
Strategy.Machining = {}
|
|
Strategy.Result = {}
|
|
Strategy.Result.dTimeToMachine = 0
|
|
|
|
if not IsTopologyOk( Proc) then
|
|
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not implemented'
|
|
EgtOutLog( sErr)
|
|
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
|
return false, Strategy.Result
|
|
end
|
|
|
|
local bAreAllMachiningsAdded = true
|
|
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
|
|
local ToolInfo = {}
|
|
local Pocketing = {}
|
|
|
|
Strategy.Machining = GetBestPocketingStrategy( Proc)
|
|
|
|
if Strategy.Result.sStatus ~= 'Not-Applicable' then
|
|
local vAddId = {}
|
|
local vAddIdTunnel = {}
|
|
|
|
-- recupero superficie, se necessario trimmata sugli spezzoni
|
|
vAddId, vAddIdTunnel = GetSplitSurfaces( Proc, Part, bAddMachining)
|
|
|
|
-- si applicano le lavorazioni
|
|
for i = 1, #vAddId do
|
|
for j = 1, #Strategy.Machining do
|
|
if Strategy.Machining[j].bIsApplicable then
|
|
Pocketing = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
|
Pocketing.Steps = {}
|
|
Pocketing.LeadIn = {}
|
|
Pocketing.nType = MCH_MY.POCKETING
|
|
Pocketing.nSubType = EgtIf( Proc.Topology.sName == 'Pocket-5-Blind', MCH_POCK_SUB.SPIRALOUT, MCH_POCK_SUB.SPIRALIN)
|
|
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
|
|
Pocketing.Steps.dStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dStep
|
|
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dSideStep
|
|
Pocketing.nToolIndex = Strategy.Machining[j].ToolInfo.nToolIndex
|
|
Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
|
|
Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
|
|
Pocketing.sDepth = -Strategy.Machining[j].ToolInfo.dResidualDepth
|
|
Pocketing.dResidualDepth = Strategy.Machining[j].ToolInfo.dResidualDepth
|
|
-- il quarto ciclo è la lavorazione opposta sulla faccia Tunnel
|
|
if Strategy.Machining[j].bToolInvert then
|
|
Pocketing.bToolInvert = true
|
|
end
|
|
-- se ho una sola trimesh, sto lavorando la Proc direttamente e non ho spezzato. Applico direttamente alla geometria calcolata prima
|
|
if #vAddId == 1 then
|
|
Pocketing.Geometry = {{ Strategy.Machining[j].idProc, Strategy.Machining[j].idFaceToMachine}}
|
|
Pocketing.vtToolDirection = Proc.Faces[ Strategy.Machining[j].idFaceToMachine + 1].vtN
|
|
if Pocketing.bToolInvert then
|
|
Pocketing.vtToolDirection = -Pocketing.vtToolDirection
|
|
end
|
|
-- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione
|
|
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione
|
|
if Proc.AffectedFaces.bLeft then
|
|
Pocketing.sStage = 'AfterTail'
|
|
end
|
|
|
|
Pocketing.nSCC = GetSCC( Proc, Pocketing)
|
|
Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part)
|
|
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine
|
|
|
|
if bAddMachining then
|
|
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Pocketing)
|
|
end
|
|
else
|
|
-- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione
|
|
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione
|
|
if Proc.AffectedFaces.bLeft and i == #vAddId then
|
|
Pocketing.sStage = 'AfterTail'
|
|
end
|
|
for k = 1, Proc.nFct do
|
|
local vtNSplitFace
|
|
local nIdTm = EgtIf( Strategy.Machining[j].bMachAppliedToTunnelFace, vAddIdTunnel[i], vAddId[i])
|
|
Pocketing.ptCenter, vtNSplitFace = EgtSurfTmFacetCenter( nIdTm, k - 1, GDB_ID.ROOT)
|
|
Pocketing.vtToolDirection = vtNSplitFace
|
|
if Pocketing.bToolInvert then
|
|
Pocketing.vtToolDirection = -Pocketing.vtToolDirection
|
|
end
|
|
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
|
|
Pocketing.Geometry = {{ nIdTm, k - 1}}
|
|
|
|
Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part)
|
|
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine
|
|
|
|
if bAddMachining then
|
|
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Pocketing)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- TODO se incompleta il volume non è corretto, ma conta? L'MRR ha senso nelle incomplete??
|
|
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
|
|
else
|
|
bAreAllMachiningsAdded = false
|
|
end
|
|
|
|
return bAreAllMachiningsAdded, Strategy.Result
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
|
|
return STR0002 |