-- Strategia: STR0010 -- Descrizione -- fresatura perpendicolare -- Feature: cut, longcut, ... -- carico librerie local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base local FaceByMill = require('FACEBYMILL') -- Tabella per definizione modulo local STR0010 = {} local Strategy = {} ------------------------------------------------------------------------------------------------------------- local function GetStrategyCompletionPercentage( Machinings) local dCompletionPercentage = 0 local dCompletionPercentageNumerator = 0 local dCompletionPercentageDenominator = 0 local nWeightsCount = 0 for i = 1, #Machinings do local Machining = Machinings[i] local dWeight = Machining.dResultWeight if not dWeight or ( dWeight < 10 * GEO.EPS_SMALL) then dWeight = 1 else nWeightsCount = nWeightsCount + 1 end -- il peso deve essere settato in tutte le lavorazioni o in nessuna if nWeightsCount ~= 0 and nWeightsCount ~= i then error( 'GetWeightedCompletionPercentage : inconsistent weights') end local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight if Machining.bIsApplicable then dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage end dCompletionPercentageDenominator = dCompletionPercentageDenominator + dWeight end dCompletionPercentage = min( 100 * dCompletionPercentageNumerator / dCompletionPercentageDenominator, 100) return dCompletionPercentage end ------------------------------------------------------------------------------------------------------------- local function CompareEdges( EdgeA, EdgeB) -- prima i lati orientati lungo X if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then return true elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then return false -- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato) else if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then return true elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then return false -- se stessa lunghezza si preferiscono i lati più in basso -- TODO qui dipenderà dalla lama scelta else if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then return true elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then return false -- se stessa Z si preferiscono i lati verso il fronte della trave else if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then return true elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then return false else return false end end end end end ------------------------------------------------------------------------------------------------------------- local function IsTopologyOk( Proc) if Proc.Topology.sFamily == 'Bevel' or Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'VGroove-2-Through' or Proc.Topology.sName == 'Rabbet-2-Through' then return true else return false end end ------------------------------------------------------------------------------------------------------------- -- TODO modificare funzione e verificare pinzaggio con regioni e area outline local function IsPositionOK( Proc, Part) local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN}) -- se impatta su faccia retro o sotto, controllo fattibilità if Proc.AffectedFaces.bBack then if ( bIsFeatureLong and Proc.b3Box:getDimZ() > Part.dHeight / 2) or ( not bIsFeatureLong and Proc.b3Box:getDimZ() > Part.dHeight / 2) then return false end end if Proc.AffectedFaces.bBottom then if ( bIsFeatureLong and Proc.b3Box:getDimY() > Part.dHeight / 2) or ( not bIsFeatureLong and Proc.b3Box:getDimY() > Part.dHeight / 2) then return false end end -- altrimenti fattibile return true end ------------------------------------------------------------------------------------------------------------- -- TODO da sistemare local function GetBottomFaceEdge( Proc, nIndexFace) local Edge = {} -- si lavora la bottom longitudinalmente if Proc.nFct == 1 or Proc.Topology.sFamily == 'DoubleBevel' then local BottomEdgesSorted = {} for i = 1, #Proc.MainFaces.BottomFaces[nIndexFace].Edges do table.insert( BottomEdgesSorted, Proc.MainFaces.BottomFaces[nIndexFace].Edges[i]) end table.sort( BottomEdgesSorted, CompareEdges) Edge = BottomEdgesSorted[1] -- edge in comune tra le due facce elseif Proc.nFct == 2 then if nIndexFace == 1 then Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1] elseif nIndexFace == 2 then Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge end else if nIndexFace == 1 then Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1] elseif nIndexFace == 2 then Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge end end return Edge end ------------------------------------------------------------------------------------------------------------- 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 ------------------------------------------------------------------------------------------------------------- function STR0010.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, CustomParameters, StrategyLib.Config) Strategy.Machinings = {} Strategy.Result = {} -- controllo su topologia if not IsTopologyOk( Proc) then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Strategy ' .. StrategyLib.Config.sStrategyId .. ' not implemented') return false, Strategy.Result end -- controllo dimensioni if not IsPositionOK( Proc, Part) then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position') return false, Strategy.Result end -- volume della feature local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part) -- TODO taglio su eventuali facce di chiusura -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local bIsSplitFeature = false if #FeatureSplittingPoints > 0 then bIsSplitFeature = true 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 -- lavorazione della BottomFace local bAreAllMachiningsAdded = true local Milling = {} local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} local EdgeToMachine = GetBottomFaceEdge( Proc, 1) if EdgeToMachine.bIsOpen then OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA end Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[1], EdgeToMachine, OptionalParametersFaceByMill) if Milling.bIsApplicable then table.insert( Strategy.Machinings, Milling) end -- si lavora seconda BottomFace if Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' then local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] -- se convesso o concavo maggiore di angolo retto if dAngleBetweenFaces >= -91 then Milling = {} OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} EdgeToMachine = GetBottomFaceEdge( Proc, 2) if EdgeToMachine.bIsOpen then OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA end Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill) if Milling.bIsApplicable then table.insert( Strategy.Machinings, Milling) end end end -- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( Strategy.Machinings) Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part) table.sort( Strategy.Machinings, SortMachiningsBySegment) Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings) Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Strategy.Machinings) Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6) if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then Strategy.Result.sStatus = 'Completed' else Strategy.Result.sStatus = 'Not-Completed' end -- aggiunta lavorazioni if #Strategy.Machinings > 0 then if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then -- aggiunge lavorazione for j = 1, #Strategy.Machinings do bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j]) end end else Strategy.Result = FeatureLib.GetStrategyResultNotApplicable() end return bAreAllMachiningsAdded, Strategy.Result end ------------------------------------------------------------------------------------------------------------- return STR0010