-- Strategia: STR0003 -- Descrizione -- Lama + motosega per slot -- Feature: tipo lapjoint ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- TODO -- 1 - Gestire lavorazioni da sotto -- 2 - Inserire antischeggia (fresa o lama) -- 3 - Smusso a V -- 4 - Implementare lavorazione di geometrie inclinate ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base local FaceByBlade = require( 'FACEBYBLADE') local FaceByChainsaw = require( 'FACEBYCHAINSAW') -- Tabella per definizione modulo local STR0003 = {} local Strategy = {} local Blade = {} local Chainsaw = {} Blade.Result = {} 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 -- TODO si può unificare con eguale funzione in STR0004 local function SortMachiningsBySegment( MachiningA, MachiningB) if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then return false elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then return true else if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then return true elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then return false 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 end local function SortMachiningsByTool( MachiningA, MachiningB) if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then return true elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then return false else 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 end local function MergeResults( Result) local SortedResult = {} for i = 1, #Result.Side do if Result.Side[i].bIsApplicable then table.insert( SortedResult, Result.Side[i]) end end for i = 1, #Result.Bottom do if Result.Bottom[i].bIsApplicable then table.insert( SortedResult, Result.Bottom[i]) end end for i = 1, #Result.Opposite do if Result.Opposite[i].bIsApplicable then table.insert( SortedResult, Result.Opposite[i]) end end return SortedResult 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 local function AddMachinings( Proc, Machinings, bAddMachining) local nIsApplicableCount = 0 local bAreAllMachiningsAdded = true for i = 1, #Machinings do if Machinings[i].bIsApplicable then nIsApplicableCount = nIsApplicableCount + 1 if bAddMachining then local bIsMachiningAdded bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Machinings[i]) if not bIsMachiningAdded then bAreAllMachiningsAdded = false end end Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Machinings[i].sMessage end end return bAreAllMachiningsAdded, nIsApplicableCount end function Blade.AddResult( Cutting) AddResult( Cutting, Blade.Result) end function Chainsaw.AddResult( Mortising) AddResult( Mortising, Chainsaw.Result) end function STR0003.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 = require( 'STR0003\\STR0003Config') Strategy.sName = StrategyLib.Config.sStrategyId Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, CustomParameters, StrategyLib.Config) Strategy.Result = {} Strategy.Result.sInfo = '' Blade.Result = {} 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) -- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama 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 -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local bIsSplitFeature = false if #FeatureSplittingPoints > 0 then bIsSplitFeature = true end -- altezza tasca local dPocketHeight = 0 if Proc.Topology.sFamily == 'Tunnel' then dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength else dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength end -- lama - calcolo lavorazioni local Cutting = {} local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature, dMinNzDownUp = 0} if Proc.Topology.sFamily == 'Tunnel' then OptionalParameters.bOppositeToolDirection = true Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) else Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) end Blade.AddResult( Cutting) -- lato opposto del tunnel if Proc.Topology.sFamily == 'Tunnel' then OptionalParameters.bOppositeToolDirection = true Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters) Blade.AddResult( Cutting) else -- se la lama non è arrivata sul fondo e c'è almeno un lato aperto va lavorato if Blade.Result.Bottom[1].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 OptionalParameters.bOppositeToolDirection = true Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) 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 OptionalParameters.bOppositeToolDirection = true Cutting = FaceByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters) Blade.AddResult( Cutting) end -- la lama è arrivata sul fondo e tasca passante, non servono ulteriori lavorazioni elseif #( Proc.MainFaces.SideFaces) == 0 then Strategy.Parameters.bFinishWithChainSaw = false Strategy.Parameters.bNotCompleteWithBladeRadius = false end end -- lama - lavorazioni raggruppate in unica lista Blade.Result.Sorted = MergeResults( Blade.Result) -- lama - aggiunta eventuali lavorazioni splittate if bIsSplitFeature then Blade.Result.Sorted = MachiningLib.GetSplitMachinings( Blade.Result.Sorted, FeatureSplittingPoints, Part) end -- lama - nessuna lavorazione successiva - aggiunta lavorazioni e calcolo risultati -- TODO bisogna uscire se la lama non può fare alcuna lavorazione; non ha senso che STR0003 lama+catena sia scelta se la lama non può lavorare, in quel caso deve essere scelta la STR0004 solo catena if not Strategy.Parameters.bFinishWithChainSaw then -- ordinamento if Strategy.Parameters.bSortBySegment then table.sort( Blade.Result.Sorted, SortMachiningsBySegment) else table.sort( Blade.Result.Sorted, SortMachiningsByTool) end -- aggiunta lavorazioni local nIsApplicableCount = 0 local bAreAllMachiningsAdded = true local dFinalCompletionPercentage = 100 bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Blade.Result.Sorted, bAddMachining) if nIsApplicableCount > 0 then -- TODO sistemare il calcolo completamento - implementare calcolo area lavorata if not Strategy.Parameters.bNotCompleteWithBladeRadius and Cutting.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 = Cutting.dCompletionPercentage end else Strategy.Result.sStatus = 'Not-Applicable' Strategy.Parameters.bFinishWithChainSaw = false end Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage) Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') local MRRParametersBlade = { 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} local dMRRBlade = MachiningLib.GetToolMRR( MRRParametersBlade) Strategy.Result.dMRR = dMRRBlade return bAreAllMachiningsAdded, Strategy.Result end -- sega a catena - calcolo lavorazioni -- TODO riordinare le righe troppo lunghe local Mortising = {} OptionalParameters = {} if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then -- si lavora solamente l'impronta lama sui lati chiusi if ( Blade.Result.Bottom[1].dResidualDepth < 10 * GEO.EPS_SMALL) and ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength > 3 * Blade.Result.Bottom[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) end if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) end -- si lavora tutto il fondo else local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) end -- ancora materiale residuo - se possibile si lavora dal lato if Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL and #Proc.MainFaces.SideFaces == 1 then -- si lavora solamente l'impronta lama sul fondo if ( #Blade.Result.Side > 0) and Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL then if ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) elseif ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters) end -- si lavora tutto il lato else local dBladeResidualDepth if #Blade.Result.Side > 0 then dBladeResidualDepth = Blade.Result.Side[1].dResidualDepth else dBladeResidualDepth = Blade.Result.Bottom[1].dResidualDepth end if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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 = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters) end end Chainsaw.AddResult( Mortising) end elseif Proc.Topology.sName == 'Groove-3-Through' then if Blade.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then -- si lavora tutto il fondo local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) -- ancora materiale residuo - si lavorano i lati if Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then -- si lavora solamente l'impronta lama sul fondo if ( Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and ( Blade.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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 local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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ò eliminare la lavorazione del fondo if Chainsaw.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL then Chainsaw.Result.Bottom[1].bIsApplicable = false end end -- si lavora tutto il lato else local OptionalParameters = { dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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, dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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 end end elseif Proc.Topology.sName == 'Tunnel-4-Through' then -- si lavora solamente l'impronta lama sul lato opposto if ( Blade.Result.Opposite[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength > 3 * Blade.Result.Opposite[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and ( Blade.Result.Opposite[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2].dLength > 3 * Blade.Result.Opposite[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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 or Chainsaw.Result.Opposite[2].dResidualDepth > 10 * GEO.EPS_SMALL then Chainsaw.Result.Opposite[1].bIsApplicable = false Chainsaw.Result.Opposite[2].bIsApplicable = false local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters) Chainsaw.AddResult( Mortising) end else local OptionalParameters = { dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.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, dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters = {} OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bOppositeToolDirection = true, bIsSplitFeature = bIsSplitFeature} Mortising = FaceByChainsaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters) Chainsaw.AddResult( Mortising) end end end -- sega a catena - lavorazioni raggruppate in unica lista Chainsaw.Result.Sorted = MergeResults( Chainsaw.Result) -- sega a catena - aggiunta eventuali lavorazioni splittate if bIsSplitFeature then Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, FeatureSplittingPoints, Part) end -- tutte le lavorazioni di tutti gli utensili in unica lista local Result = {} for i = 1, #Blade.Result.Sorted do table.insert( Result, Blade.Result.Sorted[i]) end for i = 1, #Chainsaw.Result.Sorted do table.insert( Result, Chainsaw.Result.Sorted[i]) end -- ordinamento if Strategy.Parameters.bSortBySegment then table.sort( Result, SortMachiningsBySegment) else table.sort( Result, SortMachiningsByTool) end -- aggiunta lavorazioni per tutti gli utensili local nIsApplicableCount = 0 local bAreAllMachiningsAdded = true local dFinalCompletionPercentage = 100 bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Result, bAddMachining) 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 -- calcolo risultati Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage) Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Chainsaw') local MRRParametersBlade = { 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} 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 dMRRBlade = MachiningLib.GetToolMRR( MRRParametersBlade) local dMRRChainsaw = MachiningLib.GetToolMRR( MRRParametersChainsaw) Strategy.Result.dMRR = ( dMRRBlade + dMRRChainsaw) / 2 return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0003