From 2256c15015fe6f7d1a597ed299983bc850a9ab69 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Thu, 27 Feb 2025 14:36:11 +0100 Subject: [PATCH] Prima versione strategia tenone, non funzionante --- LuaLibs/BasicCustomerStrategies.lua | 2 + LuaLibs/FeatureLib.lua | 56 +++++ Strategies/Standard/STR0001/STR0001Config.lua | 2 +- Strategies/Standard/STR0006/STR0006.lua | 231 ++++++++++++++++++ Strategies/Standard/STR0006/STR0006Config.lua | 17 ++ 5 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 Strategies/Standard/STR0006/STR0006.lua create mode 100644 Strategies/Standard/STR0006/STR0006Config.lua diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 6af277e..87ce699 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -201,6 +201,7 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Tenon elseif ID.IsTenon( Proc) then + Strategies = { { sStrategyId = 'STR0006'}} --------------------------------------------------------------------- -- Feature : Mortise elseif ID.IsMortise( Proc) then @@ -460,6 +461,7 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Tenon elseif ID.IsTenon( Proc) then + Strategies = { { sStrategyId = 'STR0006'}} --------------------------------------------------------------------- -- Feature : Mortise elseif ID.IsMortise( Proc) then diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index fce3fcf..2209caa 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -217,6 +217,8 @@ function FeatureLib.GetAdditionalInfo( Proc, Part) Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureLib.GetDrillingData( Proc) elseif ID.IsDovetailTenon( Proc) then Proc.dDTLength, Proc.dDTMaxDist, Proc.vtDTNormal, Proc.ptDTCenter, Proc.idAddAuxGeom = FeatureLib.GetDoveTailTenonData( Proc) + elseif ID.IsTenon( Proc) then + Proc.dTLength, Proc.dTMaxDist, Proc.vtTNormal, Proc.ptTCenter, Proc.idAddAuxGeom = FeatureLib.GetTenonData( Proc) end return Proc @@ -243,6 +245,60 @@ function FeatureLib.GetDrillingData( Proc) return dDiam, dLen, nFcs, nFce end +------------------------------------------------------------------------------------------------------------- +-- Recupero dati tenone +function FeatureLib.GetTenonData( Proc) + -- recupero e verifico l'entità curva + local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i') + if idAux then idAux = idAux + Proc.id end + -- recupero i dati della curva + local vtExtr = EgtCurveExtrusion( idAux, GDB_RT.GLOB) + local ptBC = EgtGP( idAux, GDB_RT.GLOB) + -- determino altezza del tenone + local frTen = Frame3d( ptBC, vtExtr) + local b3Ten = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dTenH + -- calcolo distanza massima della curva dal punto più lontano della base tenone (facet 0) + local dMaxDist + for i = 0, Proc.nFct - 1 do + local ptFC, vtFN = EgtSurfTmFacetCenter( Proc.id, i, GDB_ID.ROOT) + if not AreSameVectorApprox( vtFN, vtN) or abs( ( ptFC - ptBC) * vtN) > 100 * GEO.EPS_SMALL then + break + end + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.id, i, EgtGetParent( Proc.id)) + if nLoopId then + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( idAux, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if not dMaxDist or dDist > dMaxDist then + dMaxDist = dDist + end + end + for j = 1, nLoopCnt do + EgtErase( nLoopId + j - 1) + end + end + end + if not dMaxDist then + local b3TenAux = EgtGetBBoxRef( idAux, GDB_BB.STANDARD, frTen) + dMaxDist = 2 * ( b3Ten:getRadius() - b3TenAux:getRadius()) + end + + Proc.dTLength = dTenH + Proc.dTMaxDist = dMaxDist + Proc.vtTNormal = vtExtr + Proc.ptTCenter = ptC + Proc.idAddAuxGeom = idAux + + return Proc.dTLength, Proc.dTMaxDist, Proc.vtTNormal, Proc.ptTCenter, Proc.idAddAuxGeom + +end + ------------------------------------------------------------------------------------------------------------- -- Recupero dati tenone a coda di rondine function FeatureLib.GetDoveTailTenonData( Proc) diff --git a/Strategies/Standard/STR0001/STR0001Config.lua b/Strategies/Standard/STR0001/STR0001Config.lua index bdcb533..a66d6b7 100644 --- a/Strategies/Standard/STR0001/STR0001Config.lua +++ b/Strategies/Standard/STR0001/STR0001Config.lua @@ -3,7 +3,7 @@ local STR0001Data = { sStrategyId = 'STR0001', Parameters = { - { sName = 'dOverMatOnLenght', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'}, + { sName = 'dOverMatOnLength', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'}, { sName = 'dOverMatOnRadius', sNameNge = 'OVM_RADIUS', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'}, { sName = 'nMaxMillingPaths', sNameNge = 'MAX_PATHS', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'}, { sName = 'bUseDTToolOnPocketing', sNameNge = 'ALLOW_DT_POCKET', sValue = 'true', sDescription = 'Utilizza utensile a coda di rondine per fare svuotatura', sType = 'b'} diff --git a/Strategies/Standard/STR0006/STR0006.lua b/Strategies/Standard/STR0006/STR0006.lua new file mode 100644 index 0000000..ebcc5e3 --- /dev/null +++ b/Strategies/Standard/STR0006/STR0006.lua @@ -0,0 +1,231 @@ +-- Strategia: STR0006 +-- Descrizione +-- Lama + fresa CodaDiRondine per tenone +-- Feature: 55,1 + +-- carico librerie +local BeamLib = require( 'BeamLib') +local BeamData = require( 'BeamData') +local MachiningLib = require( 'MachiningLib') +local FeatureLib = require( 'FeatureLib') +-- strategie di base +local BladeToWaste = require( 'BLADETOWASTE') +local FaceByBlade = require('FACEBYBLADE') + +-- Tabella per definizione modulo +local STR0006 = {} +local Strategy = {} + + +------------------------------------------------------------------------------------------------------------- +function STR0006.Make( bAddMachining, Proc, Part, CustomParameters) + -- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) + local StrategyLib = {} + StrategyLib.Config = require( 'STR0006\\STR0006Config') + Strategy.sName = StrategyLib.Config.sStrategyId + CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters) + Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) + Strategy.Machining = {} + Strategy.Result = {} + + + local bAreAllMachiningsAdded = true + local ToolSearchParameters = {} + local Milling = {} + local Cutting = {} + local bCuttingWithMill = false + local nMillingPathsNeeded = 0 + + + -- calcolo se la lavorazione del tenone può essere spostata dopo taglio di coda + local dLengthOnX = Proc.b3Box:getDimX() + local bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) + + + -- scelta automatica lavorazione. Non viene mai scelta la motosega + if Strategy.Parameters.sCuttingStrategy == 'AUTO' then + --Cutting.Result, dCompletionPercentage = BladeToWaste.Make( Proc, Part, OptionalParameters) + -- se non possibile di lama si prova con fresa + if not Cutting.Result then + bCuttingWithMill = true + end + -- lavorazione forzata con utensile lama + elseif Strategy.Parameters.sCuttingStrategy == 'BLADE_FORCED' then + --Cutting.Result, dCompletionPercentage = BladeToWaste.Make( Proc, Part, OptionalParameters) + -- lavorazione forzata con utensile fresa + elseif Strategy.Parameters.sCuttingStrategy == 'MILL_FORCED' then + bCuttingWithMill = true + -- lavorazione forzata con utensile motosega + elseif Strategy.Parameters.sCuttingStrategy == 'CHAINSAW_FORCED' then + -- DA FARE!! + end + + -- TODO = Verificare se il taglio può essere fatto prima (con pezzo a caduta). Deve dagliare in un colpo, altrimenti a cubetti non si può fare prima di separare. + + -- === ricerca utensile per lavorare tenone === + Milling.bIsApplicable = false + -- se tenone in testa oppure se di coda ma è possibile lavorare dopo separazione + if not( Proc.AffectedFaces.bLeft) or bCanMoveAfterSplit then + ToolSearchParameters.dElevation = Proc.dTLength + ToolSearchParameters.vtToolDirection = Proc.vtTNormal + Milling.ToolInfo = {} + Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Mill') + if Milling.ToolInfo.nToolIndex then + Milling.bIsApplicable = true + -- calcolo passate necessarie + nMillingPathsNeeded = ceil( Proc.dTMaxDist / TOOLS[Milling.ToolInfo.nToolIndex].dSideStep) + local ParametersMRR = {} + ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex + Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) + end + + -- se cutting da fare come svuotatura, copio i dati dell'utensile scelto per lavorare il tenone + if bCuttingWithMill and Milling.bIsApplicable then + Cutting.bIsApplicable = true + Cutting.ToolInfo = Milling.ToolInfo + Cutting.dMRR = Milling.dMRR + end + end + + -- setto il risultato in base agli utensili trovati + -- lavorazione completa + if Milling.bIsApplicable and Cutting.bIsApplicable then + Strategy.Result.sStatus = 'Completed' + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) + Strategy.Result.dMRR = ( Milling.dMRR + Cutting.dMRR) / 2 + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( EgtIf( bCuttingWithMill, 'Mill,Mill', 'Mill,Blade')) + -- lavorazione incompleta + elseif Cutting.bIsApplicable then + Strategy.Result.sStatus = 'Not-Completed' + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 50) + Strategy.Result.dMRR = ( Milling.dMRR + Cutting.dMRR) / 2 + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( EgtIf( bCuttingWithMill, 'Mill', 'Blade')) + Strategy.Result.sInfo = 'Tenon not completed' + -- strategia non applicabile, manca il taglio di lama sulla lunghezza del tenone + else + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.nCompletionIndex = 0 + Strategy.Result.dMRR = 0 + Strategy.Result.nQuality = 0 + Strategy.Result.sInfo = 'Error on Tenon cutting' + end + + -- applicazione delle lavorazioni + if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then + -- creo piano di taglio sulla testa del tenone + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local idTenonCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.ptTCenter, Proc.vtTNormal, Part.b3Part, GDB_RT.GLOB) + if idTenonCutPlane then + EgtSetName( idTenonCutPlane, 'AddCut_' .. tostring( Proc.id)) + EgtSetInfo( idTenonCutPlane, 'TASKID', Proc.idTask) + end + + -- taglio in lunghezza sul tenone + if Cutting.bIsApplicable then + OptionalParameters = {} + local AuxiliaryData = {} + + -- se cutting da fare come svuotatura + if bCuttingWithMill then + Cutting.Steps = {} + Cutting.LeadIn = {} + Cutting.nType = MCH_OY.POCKETING + Cutting.nSubType = MCH_POCK_SUB.SPIRALIN + Cutting.LeadIn.nType = MCH_POCK_LI.ZIGZAG + Cutting.Steps.dStep = TOOLS[Cutting.ToolInfo.nToolIndex].dStep + Cutting.Steps.dSideStep = TOOLS[Cutting.ToolInfo.nToolIndex].dSideStep + Cutting.nToolIndex = Cutting.ToolInfo.nToolIndex + Cutting.LeadIn.dTangentDistance = TOOLS[Cutting.ToolInfo.nToolIndex].dDiameter/2 + Cutting.LeadIn.dElevation = TOOLS[Cutting.ToolInfo.nToolIndex].dDiameter/2 + Cutting.sDepth = -Cutting.ToolInfo.dResidualDepth + Cutting.Geometry = {{ idTenonCutPlane, 0}} + Cutting.vtToolDirection = Proc.vtTNormal + if Proc.AffectedFaces.bLeft and bCanMoveAfterSplit then + Cutting.sStage = 'AfterTail' + end + bAreAllMachiningsAdded = MachiningLib.AddNewMachining( Proc, Cutting) + + -- taglio di lama + else + OptionalParameters.nToolIndex = Cutting.ToolInfo.nToolIndex + OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK + OptionalParameters.sDepth = 0 + + -- TODO gestire lavorazione a cubetti + + -- TODO + -- Su faccia appena creata NON sono stati calcolati gli edges. + -- La FaceByBlade si aspetta di lavorare 1 faccia di una trimesh. Fare altra funzione? + + --local nFaceType, vEdges = EgtSurfTmGetFacetOutlineInfo( AddId, 0, GDB_ID.ROOT) + --local EdgeToMachine = GetEdgeToMachine( vEdges, -Y_AX()) + -- approccio e retrazione + --OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine) + --Cutting = FaceByBlade.Make( Proc, Part, AddId, EdgeToMachine, OptionalParameters) + if Proc.AffectedFaces.bLeft and bCanMoveAfterSplit then + Cutting.sStage = 'AfterTail' + end + MachiningLib.AddNewMachining( Proc, Cutting, AuxiliaryData) + end + end + + -- passaggio sul profilo + if Milling.bIsApplicable then + local AuxiliaryData = {} + -- se molti passaggi richiesti, si fa svuotatura + if nMillingPathsNeeded <= Strategy.Parameters.nMaxMillingPaths then + else + -- aggiungo geometria + Milling.Geometry = {{ Proc.idAddAuxGeom, -1}} + Milling.nToolIndex = Milling.ToolInfo.nToolIndex + Milling.nType = MCH_MY.MILLING + Milling.vtToolDirection = Proc.vtTNormal + Milling.sDepth = 0 + + -- LeadIn / LeadOut + Milling.LeadIn = {} + Milling.LeadOut = {} + Milling.LeadIn.nType = MCH_MILL_LI.LINEAR + Milling.LeadOut.nType = MCH_MILL_LI.LINEAR + Milling.LeadIn.dTangentDistance = TOOLS[Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Milling.LeadIn.dPerpDistance = 0 + Milling.LeadOut.dTangentDistance = TOOLS[Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Milling.LeadOut.dPerpDistance = 0 + + if Proc.AffectedFaces.bLeft and bCanMoveAfterSplit then + Milling.sStage = 'AfterTail' + end + + -- sistemo il lato e la direzione di lavoro + Milling.bInvert = EgtIf( TOOLS[Milling.ToolInfo.nToolIndex].bIsCCW, false, true) + Milling.nWorkside = EgtIf( TOOLS[Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + + Milling.sUserNotes = EgtSetVal( 'MaxElev', EgtNumToString( Proc.dTLength, 1)) .. ';' + + -- TODO calcolare SCC + + -- passate con sovramateriale + AuxiliaryData.Clones = {} + for i = nMillingPathsNeeded, 1, -1 do + -- il primo è il passaggio più esterno + local nIndexClones = nMillingPathsNeeded - i + 1 + -- suddivido step in base al numero passate da fare + local dRealSideStep = floor( Proc.dTMaxDist / nMillingPathsNeeded) + -- cambia solo sovrmateriale radiale + AuxiliaryData.Clones[nIndexClones] = {} + AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * dRealSideStep + end + + -- aggiunge lavorazione + bAreAllMachiningsAdded = MachiningLib.AddNewMachining( Proc, Milling, AuxiliaryData) + end + end + end + + return bAreAllMachiningsAdded, Strategy.Result +end + +------------------------------------------------------------------------------------------------------------- + + return STR0006 \ No newline at end of file diff --git a/Strategies/Standard/STR0006/STR0006Config.lua b/Strategies/Standard/STR0006/STR0006Config.lua new file mode 100644 index 0000000..c7a4f53 --- /dev/null +++ b/Strategies/Standard/STR0006/STR0006Config.lua @@ -0,0 +1,17 @@ +-- Parametri configurabili da cliente per strategia: STR0001 + +local STR0006Data = { + sStrategyId = 'STR0006', + Parameters = { + { sName = 'dOverMatOnLength', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'}, + { sName = 'dOverMatOnRadius', sNameNge = 'OVM_RADIUS', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'}, + { sName = 'nMaxMillingPaths', sNameNge = 'MAX_PATHS', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'}, + { sName = 'sCuttingStrategy', sNameNge = 'EXEC_TENON_SURF', sValue = 'AUTO', sType = 'combo', sMinUserLevel = '1', + Choices = { { sValue = 'AUTO', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}, + { sValue = 'BLADE_FORCED', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}, + { sValue = 'MILL_FORCED', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}, + { sValue = 'CHAINSAW_FORCED', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}} + } +} + +return STR0006Data \ No newline at end of file