-- Strategia: STR0004 -- Descrizione -- motosega per slot -- Feature: tipo lapjoint -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base local SlotByChainSaw = require( 'SLOTBYCHAINSAW') -- Tabella per definizione modulo local STR0004 = {} local Strategy = {} local Chainsaw = {} 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 CompareMachinings( MachiningA, MachiningB) if MachiningA.nSegment > MachiningB.nSegment then return false elseif MachiningB.nSegment > MachiningA.nSegment then return true else if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then return true elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then return false end end end local function AddResult( Machining, Result) table.insert( Result, {}) if not Result.Bottom then Result.Bottom = {} end if not Result.Side then Result.Side = {} end if not Result.Opposite then Result.Opposite = {} end if Machining.sEdgeType == 'Bottom' then table.insert( Result.Bottom, Machining) elseif Machining.sEdgeType == 'Side' then table.insert( Result.Side, Machining) elseif Machining.sEdgeType == 'Opposite' then table.insert( Result.Opposite, Machining) else error('AddResult : unknown edge type') end return Result end function Chainsaw.AddResult( Mortising) AddResult( Mortising, Chainsaw.Result) end function Chainsaw.AddMachiningAllSteps( Proc, Mortising, AuxiliaryData) local bMachiningAdded = false if not AuxiliaryData then AuxiliaryData = {} end AuxiliaryData.Clones = {} local dOriginalRadialOffsetMortising = Mortising.dRadialOffset for i = Mortising.VerticalSteps.nCount, 1, -1 do AuxiliaryData.Clones[i] = {} AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffsetMortising + Mortising.VerticalSteps.dStep * ( i - 1) end bMachiningAdded = MachiningLib.AddNewMachining( Proc, Mortising, AuxiliaryData) return bMachiningAdded end function STR0004.Make( bAddMachining, Proc, Part, CustomParameters) -- TODO da implementare gestione feature lunghe e spezzatura -- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) local StrategyLib = {} StrategyLib.Config = require( 'STR0004\\STR0004Config') Strategy.sName = StrategyLib.Config.sStrategyId CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) Strategy.Result = {} Strategy.Result.sInfo = '' Chainsaw.Result = {} 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 local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0) if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then dExtendAfterTail = 10000 end -- calcolo lavorazioni local Mortising = {} OptionalParameters = { dExtendAfterTail = dExtendAfterTail} if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then -- si lavora tutto il fondo local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) -- materiale residuo - se possibile si lavora dal lato if ( Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) and #Proc.MainFaces.SideFaces == 1 then if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) elseif Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters) end Chainsaw.AddResult( Mortising) end elseif Proc.Topology.sName == 'Groove-3-Through' then -- si lavora tutto il fondo local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) -- materiale residuo - si lavorano i lati if ( Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) then local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) -- ancora materiale residuo - si lavora da entrambi i lati if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then Chainsaw.Result.Side[1].bIsApplicable = false local OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters) Chainsaw.AddResult( Mortising) -- lavorando dai due lati non c'è materiale residuo - si può disabilitare la lavorazione del fondo if Chainsaw.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL then Chainsaw.Result.Bottom[1].bIsApplicable = false end end end elseif Proc.Topology.sName == 'Tunnel-4-Through' then local OptionalParameters = { dExtendAfterTail = dExtendAfterTail} Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then Chainsaw.Result.Opposite[1].bIsApplicable = false local OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail} SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail} SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters) Chainsaw.AddResult( Mortising) end end -- lavorazioni raggruppate in unica lista Chainsaw.Result.Sorted = {} for i = 1, #Chainsaw.Result.Side do if Chainsaw.Result.Side[i].bIsApplicable then table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Side[i]) end end for i = 1, #Chainsaw.Result.Bottom do if Chainsaw.Result.Bottom[i].bIsApplicable then table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Bottom[i]) end end for i = 1, #Chainsaw.Result.Opposite do if Chainsaw.Result.Opposite[i].bIsApplicable then table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Opposite[i]) end end -- aggiunta eventuali lavorazioni splittate local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) if #vFeatureSplittingPoints > 0 then Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, vFeatureSplittingPoints, Part) end -- ordinamento table.sort( Chainsaw.Result.Sorted, CompareMachinings) -- aggiunta lavorazioni local nIsApplicableCount = 0 local dFinalCompletionPercentage = 100 local bAreAllMachiningsAdded = true for i = 1, #Chainsaw.Result.Sorted do if Chainsaw.Result.Sorted[i].bIsApplicable then nIsApplicableCount = nIsApplicableCount + 1 if bAddMachining then local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Sorted[i]) if not bIsMachiningAdded then bAreAllMachiningsAdded = false end end Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Sorted[i].sMessage end end if nIsApplicableCount > 0 then if Mortising.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' else Strategy.Result.sStatus = 'Not-Completed' -- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante dFinalCompletionPercentage = Mortising.dCompletionPercentage end else Strategy.Result.sStatus = 'Not-Applicable' end Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage) Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Chainsaw') local MRRParametersChainsaw = { dStep = min( TOOLS[Mortising.nToolIndex].dStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength), dSideStep = TOOLS[Mortising.nToolIndex].dThickness, dFeed = TOOLS[Mortising.nToolIndex].Feeds.dFeed} local dMRRChainsaw = MachiningLib.GetToolMRR( MRRParametersChainsaw) Strategy.Result.dMRR = dMRRChainsaw return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0004