713 lines
30 KiB
Lua
713 lines
30 KiB
Lua
-- 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 |