-- Strategia: SPLITCUT -- Descrizione -- Taglio di separazione -- Feature: SplitCut -- 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') -- Tabella per definizione modulo local SPLITCUT = {} local Strategy = {} ------------------------------------------------------------------------------------------------------------- local function LoadStrategyParameters( CustomParameters) local StrategyLib = {} StrategyLib.Config = require( 'SPLITCUT\\SPLITCUTConfig') Strategy.sName = StrategyLib.Config.sStrategyId CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) Strategy.Result = {} Strategy.Machining = {} Strategy.Result.sInfo = '' return Strategy end ------------------------------------------------------------------------------------------------------------- local function CalculateLeadInOut( Machining, EdgeToMachine) local LeadIn = {} local LeadOut = {} LeadIn.dStartAddLength = 0 LeadOut.dEndAddLength = 0 LeadIn.nType = MCH_MILL_LI.LINEAR LeadOut.nType = MCH_MILL_LI.LINEAR LeadIn.dTangentDistance = 0 LeadOut.dTangentDistance = 0 -- elevazione sempre in negativo if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev else LeadIn.dPerpDistance = BeamData.CUT_SIC LeadOut.dPerpDistance = BeamData.CUT_SIC end LeadIn.dElevation = 0 LeadOut.dElevation = 0 LeadIn.dCompLength = 0 LeadOut.dCompLength = 0 LeadIn.dStartAddLength = BeamData.CUT_EXTRA LeadOut.dEndAddLength = BeamData.CUT_EXTRA return LeadIn, LeadOut end ------------------------------------------------------------------------------------------------------------- local function MakeChamfer() -- TODO funzionalità da aggiungere end ------------------------------------------------------------------------------------------------------------- local function GetEdgeToMachine( Proc, vtEdge) local Edge for i = 1, #Proc.Faces[1].Edges do if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then Edge = Proc.Faces[1].Edges[i] end end return Edge end ------------------------------------------------------------------------------------------------------------- local function GetSplitStrategy( Proc, Part) -- se non sono stati caricati i parametri, si ricaricano if not Strategy.Parameters then Strategy = LoadStrategyParameters() end -- separazione solo se esiste grezzo successivo con pezzi o scaricabile local nNextRawId = EgtGetNextRawPart( Part.idRaw) Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw)) -- imposto paraemtri di ricerca utensile in base a topologia local Machining = {} -- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None Machining.sTypeMachining = 'None' local Splitting = {} local ToolSearchParameters = {} ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN -- ===== RICERCA UTENSILE ===== -- cerco lama sopra Splitting.bIsApplicable = false ToolSearchParameters.bAllowTopHead = true ToolSearchParameters.bAllowBottomHead = false Splitting.ToolInfo = {} Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) if Splitting.ToolInfo.nToolIndex then Splitting.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR) end table.insert( Machining, Splitting) -- cerco lama sotto Splitting = {} Splitting.bIsApplicable = false ToolSearchParameters.bAllowTopHead = false ToolSearchParameters.bAllowBottomHead = true Splitting.ToolInfo = {} Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) if Splitting.ToolInfo.nToolIndex then Splitting.bIsApplicable = true local ParametersMRR = {} ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR) end table.insert( Machining, Splitting) -- cerco motosega Splitting = {} Splitting.bIsApplicable = false table.insert( Machining, Splitting) -- cerco fresa Splitting = {} Splitting.bIsApplicable = false table.insert( Machining, Splitting) -- ===== SCELTA LAVORAZIONI ===== -- forzature da parametri if Strategy.Parameters.bForceChainSaw then Machining[1].bIsApplicable = false Machining[2].bIsApplicable = false end -- setto valori di default. Impossibile che taglio di separazione sia incompleto Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) Strategy.Result.dMRR = 1 -- correzioni sul massimo materiale lama, considerando ingombri vari local dMaxMatBladeSideSingle local dMaxMatBladeSideDouble local dMaxMatBladeHorizontalSingle local dMaxMatBladeHorizontalDouble if Machining[1].bIsApplicable then local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2 local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead -- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni. if Part.dHeight < BeamData.MIN_DIM_HBEAM then dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT) dMaxMatBladeSideSingle = dMaxMat dMaxMatBladeSideDouble = dMaxMat * 2 else if BeamData.GetMaxMatReductionBladeCut then dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())), TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial) dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX()) else dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM) dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2 end end -- se taglio orizzontale if BeamData.GetMaxMatReductionBladeCut then dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX())) else dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial end end if Machining[2].bIsApplicable then if BeamData.GetMaxMatReductionBladeCut then local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2 dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX())) else dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial end end -- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos) -- BladeSideSingle (taglio di lama singolo di fianco) if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') Machining.sTypeMachining = 'BladeSideSingle' Machining[2].bIsApplicable = false Machining[3].bIsApplicable = false Machining[4].bIsApplicable = false return Machining -- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos) -- BladeSideDouble (taglio di lama doppio di fianco) elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') Strategy.Result.dMRR = Strategy.Result.dMRR/2 Machining.sTypeMachining = 'BladeSideDouble' Machining[2].bIsApplicable = false Machining[3].bIsApplicable = false Machining[4].bIsApplicable = false return Machining -- BladeHorizontalSingle (taglio di lama singolo orizzontale) elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') Machining.sTypeMachining = 'BladeHorizontalSingle' Machining[2].bIsApplicable = false Machining[3].bIsApplicable = false Machining[4].bIsApplicable = false return Machining -- BladeHorizontalDouble (taglio di lama doppio orizzontale) elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and ( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') Strategy.Result.dMRR = Strategy.Result.dMRR/2 Machining.sTypeMachining = 'BladeHorizontalDouble' Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble Machining[3].bIsApplicable = false Machining[4].bIsApplicable = false return Machining -- TODO : casi con motosega da completare -- ChainSawHorizontal (motosega) -- ChainSawSideSingle (motosega) -- ChainSawSideDouble (motosega) -- ChainSawPlusBlade (motosega più lama orizzontale) -- Mill (svuotatura) end -- se non ho trovato neanche una lavorazione completa, non posso separare if Machining.sTypeMachining == 'None' then Strategy.Result.sStatus = 'Not-Applicable' Strategy.Result.nCompletionIndex = 0 Strategy.Result.dMRR = 0 Strategy.Result.nQuality = 0 Strategy.Result.sInfo = 'Split not possible' end return Machining end ------------------------------------------------------------------------------------------------------------- function SPLITCUT.Make( bAddMachining, Proc, Part, CustomParameters) Strategy = LoadStrategyParameters( CustomParameters) local bAreAllMachiningsAdded = true local Splitting = {} local AuxiliaryData = {} Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part) if bAddMachining then -- inserimento smussi su spigoli del taglio if Strategy.Parameters.bMakeChamfer then MakeChamfer() end local OptionalParameters = {} -- applico le lavorazioni ---------------------------------------------------------------------------------- if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then OptionalParameters = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK OptionalParameters.sDepth = 0 -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'Split;' else OptionalParameters.sUserNotes = 'Cut;' end AuxiliaryData.bAddNewPhase = true local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then OptionalParameters = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex -- Taglio lato frontale OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK OptionalParameters.sDepth = 0 OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2 -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'PreSplit;' else OptionalParameters.sUserNotes = 'PreCut;' end local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) -- Taglio lato dietro OptionalParameters = {} Splitting = {} AuxiliaryData = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT OptionalParameters.sDepth = 0 OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2 -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'Split;' else OptionalParameters.sUserNotes = 'Cut;' end AuxiliaryData.bAddNewPhase = true EdgeToMachine = GetEdgeToMachine( Proc, Y_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then OptionalParameters = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN OptionalParameters.sDepth = 0 OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'Split;' else OptionalParameters.sUserNotes = 'Cut;' end AuxiliaryData.bAddNewPhase = true local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then OptionalParameters = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex -- Taglio lato frontale OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN OptionalParameters.sDepth = 0 local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2 OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'PreSplit;' else OptionalParameters.sUserNotes = 'PreCut;' end local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) -- Taglio lato dietro OptionalParameters = {} Splitting = {} AuxiliaryData = {} OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP OptionalParameters.sDepth = 0 OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat -- TODO gestire lavorazione a cubetti if Strategy.bSplit then OptionalParameters.sUserNotes = 'Split;' else OptionalParameters.sUserNotes = 'Cut;' end AuxiliaryData.bAddNewPhase = true EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX()) -- approccio e retrazione OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine) Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters) MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData) ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then ; -- TODO ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then ; -- TODO ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then ; -- TODO ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then ; -- TODO ---------------------------------------------------------------------------------- elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then ; -- TODO ---------------------------------------------------------------------------------- end return bAreAllMachiningsAdded, Strategy.Result else return nil, Strategy.Result end end ------------------------------------------------------------------------------------------------------------- return SPLITCUT