-- Strategia: STR0004 -- Descrizione -- motosega per slot -- Feature: tipo lapjoint ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- TODO -- 1 - Inserire antischeggia (fresa o lama) -- 2 - Smusso a V -- 3 - Implementare lavorazione di geometrie inclinate -- 4 - Gestire lavorazioni da sotto (ove possibile, in generale la motosega non lavora da sotto) ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamDataNew') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base local FaceByChainsaw = require( 'FACEBYCHAINSAW') -- 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 -- TODO si può unificare con Sorting generale local function SortMachiningsBySegment( MachiningA, MachiningB) if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then return false elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment 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 local function GetTotalAreaToMachine( Machinings) local dTotalAreaToMachine = 0 for i = 1, #Machinings do local Machining = Machinings[i] dTotalAreaToMachine = dTotalAreaToMachine + Machining.dAreaToMachine end return dTotalAreaToMachine end function STR0004.Make( bAddMachining, Proc, Part, CustomParameters) -- carico parametri da 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, Part, CustomParameters, StrategyLib.Config) Strategy.Result = {} Strategy.Result.sInfo = '' Chainsaw.Result = {} if not IsTopologyOk( Proc) then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology') return false, Strategy.Result end -- calcolo estensione oltre la coda local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0) if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then dExtendAfterTail = 10000 end -- volume della feature local dFeatureVolume = Proc.dVolume -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local bIsSplitFeature = false if #FeatureSplittingPoints > 0 then bIsSplitFeature = true end -- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile -- TODO riuniure a IsTopologyOk? if not Proc.MainFaces or not Proc.MainFaces.LongFaces[1] or not Proc.MainFaces.LongFaces[1].MainEdges then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology') return false, Strategy.Result end -- altezza tasca local dPocketHeight = 0 if Proc.Topology.sFamily == 'Tunnel' then dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength elseif Proc.Topology.sName == 'Groove-3-Through' then local BottomFace = Proc.MainFaces.BottomFaces[1] local frFrame = Frame3d( BottomFace.ptCenter, BottomFace.vtN, BottomFace.MainEdges.LongEdges[1].vtEdge) local b3BottomFace = EgtSurfTmGetFacetBBoxRef( Proc.id, BottomFace.id, GDB_BB.STANDARD, frFrame) dPocketHeight = b3BottomFace:getDimY() else dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength end -- riferimenti locali per leggibilità e performance local LongFace = Proc.MainFaces.LongFaces[1] local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1] local OppositeEdge2 = LongFace.MainEdges.OppositeEdges[2] local SideEdge1 = LongFace.MainEdges.SideEdges[1] local SideEdge2 = LongFace.MainEdges.SideEdges[2] local BottomEdge = LongFace.MainEdges.BottomEdge -- calcolo lavorazioni local Mortising = {} -- parametri comuni a tutte le lavorazioni OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature } -- TODO aggiungere verifica finecorsa e nel caso cambio lato if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then -- si lavora tutto il fondo Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, 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 OptionalParameters.OppositeToolDirectionMode = 'Enabled' local dLengthAlreadyMachined = 0 if Chainsaw.Result.Bottom[1].bIsApplicable then dLengthAlreadyMachined = Chainsaw.Result.Bottom[1].dDepthToMachine end if BottomEdge.bIsStartOpen then Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined) elseif BottomEdge.bIsEndOpen then Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined) end Chainsaw.AddResult( Mortising) end elseif Proc.Topology.sName == 'Groove-3-Through' then -- si lavora tutto il fondo Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, 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 OptionalParameters.dDepthToMachine = SideEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.OppositeToolDirectionMode = 'Enabled' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) 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 OptionalParameters.bExtendWithCornerRadius = true OptionalParameters.dDepthToMachine = SideEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) Chainsaw.AddResult( Mortising) OptionalParameters.dDepthToMachine = SideEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) 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 OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.OppositeToolDirectionMode = 'Enabled' OptionalParameters.bExtendWithCornerRadius = true Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Chainsaw.AddResult( Mortising) -- se dal lato OppositeEdge1 non è applicabile (solitamente per finecorsa) si prova dal lato opposto if not Chainsaw.Result.Opposite[1].bIsApplicable then OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters) Chainsaw.AddResult( Mortising) end -- se lavorando solo da un lato rimane materiale residuo, si lavora da entrambi if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL or ( Chainsaw.Result.Opposite[2] and Chainsaw.Result.Opposite[2].dResidualDepth > 10 * GEO.EPS_SMALL) then Chainsaw.Result.Opposite[1].bIsApplicable = false if Chainsaw.Result.Opposite[2] then Chainsaw.Result.Opposite[2].bIsApplicable = false end OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, 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 if bIsSplitFeature then Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, FeatureSplittingPoints, Part) end -- ordinamento -- TODO aggiungere ordinamento per utensile table.sort( Chainsaw.Result.Sorted, SortMachiningsBySegment) -- calcolo area lavorata local dTotalAreaToMachine = GetTotalAreaToMachine( Chainsaw.Result.Sorted) -- aggiunta lavorazioni local bAreAllMachiningsAdded = true for i = 1, #Chainsaw.Result.Sorted do if Chainsaw.Result.Sorted[i].bIsApplicable then if bAddMachining then local bIsMachiningAdded = MachiningLib.AddMachinings( 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 -- calcolo risultati Strategy.Result.dCompletionPercentage = dTotalAreaToMachine / LongFace.dArea * 100 Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) if #Chainsaw.Result.Sorted > 0 then if Mortising.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' else Strategy.Result.sStatus = 'Not-Completed' end Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Chainsaw.Result.Sorted) Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Chainsaw.Result.Sorted) Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6) else Strategy.Result = FeatureLib.GetStrategyResultNotApplicable() end return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0004