-- 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( 'BeamDataNew') 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-4-Blind' or Proc.Topology.sName == 'Tunnel-4-Through') then return true -- canale ammesso solo se lati paralleli a 2 a 2 elseif Proc.Topology.sName == 'Groove-3-Through' and ( AreOppositeVectorApprox( Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].vtN, Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[2].vtN)) then return true else return false end 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) local bAreAllMachiningsAdded = true for i = 1, #Machinings do if Machinings[i].bIsApplicable then local bIsMachiningAdded bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Machinings[i]) if not bIsMachiningAdded then bAreAllMachiningsAdded = false end Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Machinings[i].sMessage end end return bAreAllMachiningsAdded end function Blade.AddResult( Cutting) AddResult( Cutting, Blade.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 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 = STRATEGIES_CONFIG[CustomParameters.sStrategyId] Strategy.sName = StrategyLib.Config.sStrategyId Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config) Strategy.Result = {} Strategy.Result.sInfo = '' Blade.Result = {} Chainsaw.Result = {} -- 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 if not IsTopologyOk( Proc) then local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented' EgtOutLog( sErr) Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology') return false, Strategy.Result end -- se canale e lati non a 90deg la strategia non è applicabile -- TODO questo è temporaneo finchè non si gestiscono correttamente i lati obliqui per le groove-3-through -- la dPocketHeight è già gestita, ma va allungato il percorso dove c'è l'angolo > 90 if Proc.Topology.sName == 'Groove-3-Through' then local BottomFace = Proc.MainFaces.BottomFaces[1] if abs( BottomFace.Edges[1].vtEdge * BottomFace.Edges[2].vtEdge) > 10 * GEO.EPS_SMALL then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology') return false, Strategy.Result end 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 -- 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 -- 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 -- TODO funzione separata -- TODO è meglio cercare la lama qui e passarla alla FACEBYBLADE, la scelta è più precisa -- lama - calcolo lavorazioni local Cutting = {} -- parametri comuni a tutte le lavorazioni cutting local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature } -- primo lato del tunnel o lato di fondo if Proc.Topology.sFamily == 'Tunnel' then OptionalParameters.OppositeToolDirectionMode = 'Enabled' Cutting = FaceByBlade.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) else Cutting = FaceByBlade.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters) end Blade.AddResult( Cutting) -- lato opposto del tunnel if Proc.Topology.sFamily == 'Tunnel' then OptionalParameters.OppositeToolDirectionMode = 'Enabled' Cutting = FaceByBlade.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters) Blade.AddResult( Cutting) -- per tutte le altre topologie lavorazione lati aggiuntivi 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 BottomEdge.bIsStartOpen then OptionalParameters.OppositeToolDirectionMode = 'Enabled' Cutting = FaceByBlade.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) Cutting.dAreaToMachine = Cutting.dDepthToMachine * ( Cutting.dEdgeLength - Blade.Result.Bottom[1].dDepthToMachine) Blade.AddResult( Cutting) end -- eventuale lavorazione di lama - lato della tasca in cui finisce la lavorazione if BottomEdge.bIsEndOpen then OptionalParameters.OppositeToolDirectionMode = 'Enabled' Cutting = FaceByBlade.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Cutting.dAreaToMachine = Cutting.dDepthToMachine * ( Cutting.dEdgeLength - Blade.Result.Bottom[1].dDepthToMachine) 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, escluse le lavorazioni non applicabili Blade.Result.Sorted = MergeResults( Blade.Result) -- lama - calcolo area lavorata local dAreaToMachineBlade = GetTotalAreaToMachine( Blade.Result.Sorted) -- 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 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 bAreAllMachiningsAdded = true if bAddMachining then bAreAllMachiningsAdded = AddMachinings( Proc, Blade.Result.Sorted) end -- calcolo risultati Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Blade.Result.Sorted) Strategy.Result.dCompletionPercentage = dAreaToMachineBlade / LongFace.dArea * 100 Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Blade.Result.Sorted) Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6) if #Blade.Result.Sorted > 0 then if not Strategy.Parameters.bNotCompleteWithBladeRadius and Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' else Strategy.Result.sStatus = 'Not-Completed' end -- non ha senso che STR0003 lama+catena sia applicabile se la lama non può lavorare, in quel caso deve essere scelta la STR0004 solo catena else Strategy.Result = FeatureLib.GetStrategyResultNotApplicable() Strategy.Parameters.bFinishWithChainSaw = false end return bAreAllMachiningsAdded, Strategy.Result end -- TODO funzione separata -- sega a catena - calcolo lavorazioni local Mortising = {} -- parametri comuni a tutte le lavorazioni mortising OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, bIsSplitFeature = bIsSplitFeature } 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 ( BottomEdge.dLength > 3 * Blade.Result.Bottom[1].dToolMarkLength - 10 * GEO.EPS_SMALL) then if not BottomEdge.bIsStartOpen then OptionalParameters.sSideToMachine = 'Start' OptionalParameters.dLengthToMachine = Blade.Result.Bottom[1].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * Mortising.dEdgeLength Chainsaw.AddResult( Mortising) end if not BottomEdge.bIsEndOpen then OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Bottom[1].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * Mortising.dEdgeLength Chainsaw.AddResult( Mortising) end -- reset parametri opzionali OptionalParameters.sSideToMachine = nil OptionalParameters.dLengthToMachine = nil -- si lavora tutto il fondo else OptionalParameters.dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters.dMaxElev = nil 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 ( BottomEdge.bIsStartOpen and SideEdge1.dLength > 3 * Blade.Result.Side[1].dToolMarkLength - 10 * GEO.EPS_SMALL) then OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Side[1].dToolMarkLength OptionalParameters.OppositeToolDirectionMode = 'Enabled' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) elseif ( BottomEdge.bIsEndOpen and SideEdge2.dLength > 3 * Blade.Result.Side[1].dToolMarkLength - 10 * GEO.EPS_SMALL) then OptionalParameters.sSideToMachine = 'Start' OptionalParameters.dLengthToMachine = Blade.Result.Side[2].dToolMarkLength OptionalParameters.OppositeToolDirectionMode = 'Enabled' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) 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 BottomEdge.bIsStartOpen then OptionalParameters.dMaxElev = dBladeResidualDepth + 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) elseif BottomEdge.bIsEndOpen then OptionalParameters.dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA OptionalParameters.OppositeToolDirectionMode = 'Enabled' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine) 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 OptionalParameters.dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters.dMaxElev = nil -- ancora materiale residuo - si lavorano i lati if Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then OptionalParameters.bExtendWithCornerRadius = true -- si lavora solamente l'impronta lama sul fondo if ( Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL and SideEdge1.dLength > 3 * Blade.Result.Side[1].dToolMarkLength - 10 * GEO.EPS_SMALL) and ( Blade.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL and SideEdge2.dLength > 3 * Blade.Result.Side[2].dToolMarkLength - 10 * GEO.EPS_SMALL) then OptionalParameters.dDepthToMachine = SideEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Side[1].dToolMarkLength 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.dDepthToMachine = SideEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Side[1].dToolMarkLength 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 OptionalParameters.sSideToMachine = 'Start' OptionalParameters.dLengthToMachine = Blade.Result.Side[2].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = 0 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 OptionalParameters.dDepthToMachine = SideEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.dMaxElev = Blade.Result.Side[1].dResidualDepth + 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.dDepthToMachine = SideEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA 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 OptionalParameters.dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) Mortising.dAreaToMachine = 0 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 OptionalParameters.OppositeToolDirectionMode = 'Enabled' OptionalParameters.bExtendWithCornerRadius = true -- si lavora solamente l'impronta lama sul lato opposto if ( Blade.Result.Opposite[1].dResidualDepth < 10 * GEO.EPS_SMALL and OppositeEdge1.dLength > 3 * Blade.Result.Opposite[1].dToolMarkLength - 10 * GEO.EPS_SMALL) and ( Blade.Result.Opposite[2].dResidualDepth < 10 * GEO.EPS_SMALL and OppositeEdge2.dLength > 3 * Blade.Result.Opposite[2].dToolMarkLength - 10 * GEO.EPS_SMALL) then OptionalParameters.dLengthToMachine = max( Blade.Result.Opposite[1].dToolMarkLength, Blade.Result.Opposite[2].dToolMarkLength ) OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.sSideToMachine = 'Start' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * Mortising.dEdgeLength Chainsaw.AddResult( Mortising) OptionalParameters.sSideToMachine = 'End' Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Mortising.dAreaToMachine = 0 Chainsaw.AddResult( Mortising) -- 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].dResidualDepth > 10 * GEO.EPS_SMALL then Chainsaw.Result.Opposite[1].bIsApplicable = false Chainsaw.Result.Opposite[2].bIsApplicable = false OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.sSideToMachine = 'Start' OptionalParameters.dLengthToMachine = Blade.Result.Opposite[1].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * Mortising.dEdgeLength Chainsaw.AddResult( Mortising) OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Opposite[1].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Mortising.dAreaToMachine = 0 Chainsaw.AddResult( Mortising) OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.sSideToMachine = 'Start' OptionalParameters.dLengthToMachine = Blade.Result.Opposite[2].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters) Mortising.dAreaToMachine = Mortising.dDepthToMachine * Mortising.dEdgeLength Chainsaw.AddResult( Mortising) OptionalParameters.sSideToMachine = 'End' OptionalParameters.dLengthToMachine = Blade.Result.Opposite[2].dToolMarkLength Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters) Mortising.dAreaToMachine = 0 Chainsaw.AddResult( Mortising) end -- si lavora tutto il lato else OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation + BeamData.CUT_EXTRA OptionalParameters.dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Chainsaw.AddResult( Mortising) if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then Chainsaw.Result.Opposite[1].bIsApplicable = false OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Chainsaw.AddResult( Mortising) OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN OptionalParameters.dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters) Chainsaw.AddResult( Mortising) end end end -- sega a catena - lavorazioni raggruppate in unica lista Chainsaw.Result.Sorted = MergeResults( Chainsaw.Result) -- sega a catena - calcolo area lavorata local dAreaToMachineChainsaw = GetTotalAreaToMachine( Chainsaw.Result.Sorted) -- 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 bAreAllMachiningsAdded = true if bAddMachining then bAreAllMachiningsAdded = AddMachinings( Proc, Result) end -- calcolo risultati Strategy.Result.dCompletionPercentage = max( dAreaToMachineBlade, dAreaToMachineChainsaw) / LongFace.dArea * 100 Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) if #Result > 0 then if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' else Strategy.Result.sStatus = 'Not-Completed' end Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Result) Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Result) Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6) else Strategy.Result = FeatureLib.GetStrategyResultNotApplicable() end return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0003