diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 87ce699..de77e84 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -221,9 +221,11 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Dovetail Mortise elseif ID.IsDovetailMortise( Proc) then + Strategies = { { sStrategyId = 'STR0007'}} --------------------------------------------------------------------- -- Feature : Dovetail Mortise Front elseif ID.IsFrontDovetailMortise( Proc) then + Strategies = { { sStrategyId = 'STR0007'}} --------------------------------------------------------------------- -- Feature : Marking elseif ID.IsMarking( Proc) then @@ -481,9 +483,11 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Dovetail Mortise elseif ID.IsDovetailMortise( Proc) then + Strategies = { { sStrategyId = 'STR0007'}} --------------------------------------------------------------------- -- Feature : Dovetail Mortise Front elseif ID.IsFrontDovetailMortise( Proc) then + Strategies = { { sStrategyId = 'STR0007'}} --------------------------------------------------------------------- -- Feature : Marking elseif ID.IsMarking( Proc) then diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 48d6738..0247dd0 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -233,6 +233,9 @@ function FeatureLib.GetAdditionalInfo( Proc, Part) -- se tenone o tenone a coda di rondine elseif ID.IsTenon( Proc) or ID.IsDovetailTenon( Proc) then Proc.FeatureInfo = FeatureLib.GetTenonData( Proc) + -- se mortasa a coda di rondine o mortasa frontale a coda di rondine + elseif ID.IsDovetailMortise( Proc) or ID.IsFrontDovetailMortise( Proc) then + Proc.FeatureInfo = FeatureLib.GetDTMortiseData( Proc) end return Proc @@ -269,14 +272,13 @@ function FeatureLib.GetTenonData( Proc) 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 vtN = EgtCurveExtrusion( idAux, GDB_RT.GLOB) local ptBC = EgtGP( idAux, GDB_RT.GLOB) -- determino altezza del tenone - local frTen = Frame3d( ptBC, vtExtr) + local frTen = Frame3d( ptBC, vtN) 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 @@ -308,7 +310,7 @@ function FeatureLib.GetTenonData( Proc) FeatureExtraInfo.dTenonLength = dTenH FeatureExtraInfo.dTenonMaxDist = dMaxDist - FeatureExtraInfo.vtTenonN = vtExtr + FeatureExtraInfo.vtTenonN = vtN FeatureExtraInfo.ptTenonCenter = ptC FeatureExtraInfo.idAddAuxGeom = idAux @@ -316,6 +318,53 @@ function FeatureLib.GetTenonData( Proc) end +------------------------------------------------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function FeatureLib.GetDTMortiseData( Proc) + local FeatureExtraInfo = {} + + local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i') + if idAux then idAux = idAux + Proc.id end + local vtMortiseN = EgtCurveExtrusion( idAux, GDB_RT.GLOB) + -- ne determino l'asse + local vtAx = EgtEV( idAux, GDB_RT.GLOB) - EgtSV( idAux, GDB_RT.GLOB) + vtAx:normalize() + -- determino l'altezza della mortasa (0=faccia di fondo) + local rFrameDtMortise, dMortiseLength, dMortiseWidth = EgtSurfTmFacetMinAreaRectangle( Proc.id, 0, GDB_RT.GLOB) + if abs( rFrameDtMortise:getVersY() * vtAx) > abs( rFrameDtMortise:getVersX() * vtAx) then + rFrameDtMortise:rotate( rFrameDtMortise:getOrigin(), rFrameDtMortise:getVersZ(), 90) + dMortiseLength, dMortiseWidth = dMortiseWidth, dMortiseLength + end + local b3DtMortise = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, rFrameDtMortise) + local dMortiseDepth = b3DtMortise:getDimZ() + + -- recupero il raggio minimo della mortasa + local dMortiseMinRadius = 1000 + local nSt, nEnd = EgtCurveDomain( idAux) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( idAux, i) + if dRad > 0 and dRad < dMortiseMinRadius then + dMortiseMinRadius = dRad + end + end + + -- distanza massima all'imbocco ortogonale all'asse + local vtDiff = EgtEP( idAux, GDB_RT.GLOB) - EgtSP( idAux, GDB_RT.GLOB) + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dMortiseMaxDist = min( vtOrtDiff:len(), dMortiseWidth) + + FeatureExtraInfo.bIsFrontMortise = Proc.nPrc == 56 + FeatureExtraInfo.dMortiseLength = dMortiseLength + FeatureExtraInfo.dMortiseWidth = dMortiseWidth + FeatureExtraInfo.dMortiseMaxDist = dMortiseMaxDist + FeatureExtraInfo.dMortiseDepth = dMortiseDepth + FeatureExtraInfo.dMortiseMinRadius = dMortiseMinRadius + FeatureExtraInfo.vtMortiseN = vtMortiseN + FeatureExtraInfo.idAddAuxGeom = idAux + + return FeatureExtraInfo +end + ------------------------------------------------------------------------------------------------------------- -- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato function FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage) diff --git a/Strategies/Standard/STR0007/STR0007.lua b/Strategies/Standard/STR0007/STR0007.lua new file mode 100644 index 0000000..0df5707 --- /dev/null +++ b/Strategies/Standard/STR0007/STR0007.lua @@ -0,0 +1,453 @@ +-- Strategia: STR0007 +-- Descrizione +-- Mortasa a coda di rondine e mortasa frontale a coda di rondine +-- Feature: 55/56,0 + +-- 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') + +-- Tabella per definizione modulo +local STR0007 = {} +local Strategy = {} + +------------------------------------------------------------------------------------------------------------- +function GetMortiseStrategy( Proc, Part) + local Machining = {} + Machining.Milling = {} + Machining.Cutting = {} + Machining.Pocketing = {} + local Result = {} + Result.Milling = {} + Result.Cutting = {} + Result.Pocketing = {} + local ToolSearchParameters = {} + + -- in caso sia una mortasa frontale, bisogna lavorare il taglio + if Proc.FeatureInfo.bIsFrontMortise then + -- scelta automatica lavorazione. Non viene mai scelta la motosega + if Strategy.Parameters.sCuttingStrategy == 'AUTO' then + -- creo piano di taglio sulla testa del tenone + local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, + dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + } + Machining.Cutting, Result.Cutting = BladeToWaste.Make( Strategy.idMortiseCutPlane, Part, OptionalParameters) + -- se presente almeno una lavorazione e completo, il taglio è applicabile + if #Machining.Cutting > 0 and Result.Cutting and Result.Cutting.sStatus == 'Completed' then + Machining.Cutting.bIsApplicable = true + end + -- se non possibile di lama si prova con fresa + if not Machining.Cutting or Result.Cutting.sStatus ~= 'Completed' then + Machining.bCuttingWithMill = true + end + -- lavorazione forzata con utensile lama + elseif Strategy.Parameters.sCuttingStrategy == 'BLADE_FORCED' then + local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, + dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + } + Machining.Cutting, Result.Cutting = BladeToWaste.Make( Strategy.idMortiseCutPlane, Part, OptionalParameters) + -- se presente almeno una lavorazione e completo, il taglio è applicabile + if #Machining.Cutting > 0 and Result.Cutting.sStatus == 'Completed' then + Machining.Cutting.bIsApplicable = true + else + Machining.Cutting.bIsApplicable = false + end + -- lavorazione forzata con utensile fresa + elseif Strategy.Parameters.sCuttingStrategy == 'MILL_FORCED' then + Machining.bCuttingWithMill = true + -- lavorazione forzata con utensile motosega + elseif Strategy.Parameters.sCuttingStrategy == 'CHAINSAW_FORCED' then + -- DA FARE!! + end + + -- === ricerca utensile per svuotare taglio iniziale, se taglio non possibile === + if Machining.bCuttingWithMill and ( not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit) then + ToolSearchParameters = {} + ToolSearchParameters.dElevation = 0 + ToolSearchParameters.vtToolDirection = Proc.vtTenonN + Machining.Cutting.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) + if Machining.Cutting.ToolInfo.nToolIndex then + Machining.Cutting.bIsApplicable = true + local ParametersMRR = {} + ParametersMRR.nToolIndex = Machining.Cutting.ToolInfo.nToolIndex + Result.Cutting.dMRR = MachiningLib.GetToolMRR( ParametersMRR) + Result.Cutting.sStatus = 'Completed' + end + end + end + + -- === ricerca utensile per lavorare tenone coda di rondine === + Machining.Milling.bIsApplicable = false + -- se tenone in testa oppure se di coda ma è possibile lavorare dopo separazione + if not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit then + ToolSearchParameters.dElevation = Proc.FeatureInfo.dMortiseDepth + ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtMortiseN + ToolSearchParameters.sMillShape = 'DOVETAIL' + Machining.Milling.ToolInfo = {} + Machining.Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) + if Machining.Milling.ToolInfo.nToolIndex then + Machining.Milling.bIsApplicable = true + + -- calcolo numero passate necessarie + if Proc.FeatureInfo.dMortiseMaxDist > TOOLS[Machining.Milling.ToolInfo.nToolIndex].dDiameter * 1.5 then + Machining.nMillingPathsNeeded = ceil( ( Proc.FeatureInfo.dMortiseMaxDist / 2) / ( TOOLS[Machining.Milling.ToolInfo.nToolIndex].dSideStep * 1.5)) + else + Machining.nMillingPathsNeeded = 1 + end + + local ParametersMRR = {} + ParametersMRR.nToolIndex = Machining.Milling.ToolInfo.nToolIndex + Result.Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) + -- l'utensile a coda di rondine deve per forza riuscire a lavorare tutto, altrimenti errore + if Machining.Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then + Result.Milling.sStatus = 'Completed' + else + Machining.Milling.bIsApplicable = false + end + end + end + + return Machining, Result +end + +------------------------------------------------------------------------------------------------------------- +function GetFeatureRotationIndex( Proc) + local nVoteIndex + + -- se fatto con testa sopra + if TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bTop then + if Proc.FeatureInfo.vtMortiseN:getZ() < 0 then + nVoteIndex = 2 + elseif Proc.FeatureInfo.vtMortiseN:getZ() > abs( Proc.FeatureInfo.vtMortiseN:getY()) then + nVoteIndex = 4 + else + nVoteIndex = 3 + end + -- se fatto con testa sotto + elseif TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bBottom then + if Proc.FeatureInfo.vtMortiseN:getZ() > 0 then + nVoteIndex = 2 + elseif Proc.FeatureInfo.vtMortiseN:getZ() < - abs( Proc.FeatureInfo.vtMortiseN:getY()) then + nVoteIndex = 4 + else + nVoteIndex = 3 + end + end + + return nVoteIndex +end + +------------------------------------------------------------------------------------------------------------- +function GetMortiseMachiningResult( Proc, Result) + local TotalResult = {} + -- setto il risultato in base agli utensili trovati + + -- lavorazione mortasa frontale completa + if Strategy.Machining.Milling.bIsApplicable and Strategy.Machining.Cutting.bIsApplicable and Proc.FeatureInfo.bIsFrontMortise then + TotalResult.sStatus = Result.Milling.sStatus + TotalResult.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) + TotalResult.dMRR = ( Result.Milling.dMRR + Result.Cutting.dMRR) / 2 + TotalResult.nQuality = FeatureLib.GetFeatureQuality( EgtIf( Strategy.Machining.bCuttingWithMill, 'Mill,Mill', 'Mill,Blade')) + TotalResult.nFeatureRotationIndex = GetFeatureRotationIndex( Proc) + TotalResult.sInfo = '' + -- lavorazione mortasa completa + elseif Strategy.Machining.Milling.bIsApplicable and not( Proc.FeatureInfo.bIsFrontMortise) then + TotalResult.sStatus = Result.Milling.sStatus + TotalResult.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) + TotalResult.dMRR = Result.Milling.dMRR + TotalResult.nQuality = FeatureLib.GetFeatureQuality( 'Mill') + TotalResult.nFeatureRotationIndex = GetFeatureRotationIndex( Proc) + TotalResult.sInfo = '' + -- lavorazione incompleta + elseif Strategy.Machining.Cutting.bIsApplicable then + TotalResult.sStatus = 'Not-Completed' + TotalResult.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 50) + TotalResult.dMRR = Result.Cutting.dMRR + TotalResult.nQuality = FeatureLib.GetFeatureQuality( EgtIf( Strategy.Machining.bCuttingWithMill, 'Mill', 'Blade')) + TotalResult.sInfo = 'Tenon not completed' + -- strategia non applicabile, manca il taglio di lama sulla lunghezza del tenone + else + TotalResult.sStatus = 'Not-Applicable' + TotalResult.nCompletionIndex = 0 + TotalResult.dMRR = 0 + TotalResult.nQuality = 0 + TotalResult.sInfo = 'Error on Tenon cutting' + end + return TotalResult +end + +--------------------------------------------------------------------- +local function CalcTopPath( nProcId, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- copio la curva di base + local NewAuxId = EgtCopyGlob( AuxId, nAddGrpId) + if not NewAuxId then return end + -- ne allungo gli estremi + EgtAddCurveCompoLineTg( NewAuxId, 100, false) + EgtAddCurveCompoLineTg( NewAuxId, 100, true) + EgtMergeCurvesInCurveCompo( NewAuxId) + -- eseguo traslazione e offset per portarla sul top + local vtMove = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) * ( dAltMort - 10 * GEO.EPS_SMALL) + EgtMove( NewAuxId, vtMove, GDB_RT.GLOB) + local dOffset = dAltMort * tan( dSideAng) + if not EgtOffsetCurve( NewAuxId, dOffset) then return end + -- la limito entro la trave + local refBox = Frame3d( b3Solid:getMin()) + local vtBoxDiag = b3Solid:getMax() - b3Solid:getMin() + local nCount + NewAuxId, nCount = EgtTrimFlatCurveWithBox( NewAuxId, refBox, vtBoxDiag, true, true, GDB_RT.GLOB) + -- se divisa in più parti, le unisco congiungendole con segmenti + if nCount > 1 then + if EgtGetType( NewAuxId) ~= GDB_TY.CRV_COMPO then + NewAuxId = EgtCurveCompo( nAddGrpId, NewAuxId) + end + for i = 2, nCount do + local CrvId = NewAuxId + i - 1 + local ptStart = EgtSP( CrvId) + EgtAddCurveCompoLine( NewAuxId, ptStart) + EgtAddCurveCompoCurve( NewAuxId, CrvId) + end + end + return NewAuxId +end + +------------------------------------------------------------------------------------------------------------- +function ApplyMortiseAntiSplint( Proc, Part) + -- se il percorso non è chiuso, aggiungo percorso e lavorazione antischeggia + if not EgtCurveIsClosed( Proc.FeatureInfo.idAddAuxGeom) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + -- calcolo il percorso top mortise + local dSideAng = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dSideAngle + local dToolDiam = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter + local vtExtr = Proc.FeatureInfo.vtMortiseN + local nAuxId1 = CalcTopPath( Proc.id, Proc.FeatureInfo.idAddAuxGeom, nAddGrpId, Proc.FeatureInfo.dMortiseDepth, dSideAng, Part.b3Part) + -- se esiste il percorso + if nAuxId1 then + -- creo percorso sulla parte alta della mortasa + local dToolRadDelta = Proc.FeatureInfo.dMortiseDepth * tan( dSideAng) + local dTopDiam = dToolDiam + 2 * dToolRadDelta + -- recupero punto iniziale e finale del percorso + local ptStart = EgtSP( nAuxId1, GDB_RT.GLOB) + local ptEnd = EgtEP( nAuxId1, GDB_RT.GLOB) + if ptStart and ptEnd then + local nId1 + + -- direzione del segmento + local vtDir = ptEnd - ptStart ; + local dLen = vtDir:len() + vtDir:normalize() + -- direzioni tangenti iniziale e finale + local vtStart = EgtSV( nAuxId1, GDB_RT.GLOB) + local vtEnd = EgtEV( nAuxId1, GDB_RT.GLOB) + -- angoli + local dAngStart = acos( vtStart * vtDir) + local dAngEnd = acos( vtEnd * vtDir) + local dMaxAng = min( 30, dAngStart, dAngEnd) + if dLen < dTopDiam then + dMaxAng = min( dMaxAng, asin( dLen / dTopDiam)) + end + local vtTg = vtDir ; vtTg:rotate( vtExtr, -dMaxAng) + -- creo l'arco + nId1 = EgtArc2PV( nAddGrpId, ptStart, ptEnd, vtTg, GDB_RT.GLOB) + + if not nId1 then + local sErr = 'Wrong geometry : Error on DtMortise ' + EgtOutLog( sErr) + return false, sErr + end + EgtModifyCurveExtrusion( nId1, vtExtr, GDB_RT.GLOB) + + local Machining = {} + Machining.nToolIndex = Strategy.Machining.Milling.ToolInfo.nToolIndex + Machining.nType = MCH_MY.MILLING + Machining.vtToolDirection = Proc.FeatureInfo.vtMortiseN + + -- LeadIn / LeadOut + Machining.LeadIn = {} + Machining.LeadOut = {} + Machining.LeadIn.nType = MCH_MILL_LI.TANGENT + Machining.LeadOut.nType = MCH_MILL_LI.TANGENT + Machining.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Machining.LeadIn.dPerpDistance = 0 + Machining.LeadOut.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Machining.LeadOut.dPerpDistance = 0 + + Machining.dRadialOffset = dToolRadDelta - 1 + Machining.sDepth = Proc.FeatureInfo.dMortiseDepth - Strategy.Parameters.dOverMatOnLength + Machining.Geometry = {{ nId1, -1}} + Machining.bInvert = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, false, true) + Machining.nWorkside = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + Machining.sUserNotes = EgtSetVal( 'MaxElev', EgtNumToString( Proc.FeatureInfo.dMortiseDepth, 1)) .. '; VMRS=0;' + + if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then + Machining.sStage = 'AfterTail' + end + MachiningLib.AddMachinings( Proc, Machining) + + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.id) + EgtOutLog( sErr) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.id) + EgtOutLog( sErr) + return false, sErr + end + end +end + + +------------------------------------------------------------------------------------------------------------- +function STR0007.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( 'STR0007\\STR0007Config') + Strategy.sName = StrategyLib.Config.sStrategyId + Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, CustomParameters, StrategyLib.Config) + Strategy.Machining = {} + Strategy.Result = {} + + local bAreAllMachiningsAdded = true + local Results = {} + + -- controllo conformità offset mortasa + Strategy.Parameters.dOverMatOnRadius = EgtClamp( Strategy.Parameters.dOverMatOnRadius, -5, 5) + Strategy.Parameters.dOverMatOnLength = EgtClamp( Strategy.Parameters.dOverMatOnLength, -2, 2) + + -- calcolo se la lavorazione della mortasa può essere spostata dopo taglio di coda + local dLengthOnX = Proc.b3Box:getDimX() + Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part) + + -- se mortasa frontale, verifico che esista faccia di taglio + if Proc.FeatureInfo.bIsFrontMortise then + -- verifico esista la faccia di taglio + local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.id, 1, GDB_ID.ROOT) + if ptCutC and vtCutN and AreSameVectorApprox( Strategy.FeatureInfo.vtMortiseN, vtCutN) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + Strategy.idMortiseCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, Part.b3Part, GDB_RT.GLOB) + end + end + + Strategy.Machining, Results = GetMortiseStrategy( Proc, Part) + + Strategy.Result = GetMortiseMachiningResult( Proc, Results) + + + -- applicazione delle lavorazioni + if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then + -- taglio in lunghezza sul tenone + if Strategy.Machining.Cutting.bIsApplicable then + OptionalParameters = {} + + -- se cutting da fare come svuotatura + if Strategy.Machining.bCuttingWithMill then + Strategy.Machining.Cutting.Steps = {} + Strategy.Machining.Cutting.LeadIn = {} + Strategy.Machining.Cutting.nType = MCH_OY.POCKETING + Strategy.Machining.Cutting.nSubType = MCH_POCK_SUB.SPIRALIN + Strategy.Machining.Cutting.LeadIn.nType = MCH_POCK_LI.ZIGZAG + Strategy.Machining.Cutting.Steps.dStep = TOOLS[Strategy.Machining.Cutting.ToolInfo.nToolIndex].dStep + Strategy.Machining.Cutting.Steps.dSideStep = TOOLS[Strategy.Machining.Cutting.ToolInfo.nToolIndex].dSideStep + Strategy.Machining.Cutting.nToolIndex = Strategy.Machining.Cutting.ToolInfo.nToolIndex + Strategy.Machining.Cutting.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Cutting.ToolInfo.nToolIndex].dDiameter/2 + Strategy.Machining.Cutting.LeadIn.dElevation = TOOLS[Strategy.Machining.Cutting.ToolInfo.nToolIndex].dDiameter/2 + Strategy.Machining.Cutting.sDepth = 0 + Strategy.Machining.Cutting.Geometry = {{ Strategy.idMortiseCutPlane, 0}} + Strategy.Machining.Cutting.vtToolDirection = Proc.FeatureInfo.vtMortiseN + if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then + Strategy.Machining.Cutting.sStage = 'AfterTail' + end + bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining.Cutting) + + -- taglio di lama + else + for i = 1, #Strategy.Machining.Cutting do + if Strategy.Machining.Cutting.bIsApplicable then + if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then + Strategy.Machining.Cutting[i].sStage = 'AfterTail' + end + local bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining.Cutting[i]) + if not bIsMachiningAdded then + bAreAllMachiningsAdded = false + end + end + end + end + end + + -- se richiesta passata antischeggia + if Strategy.Parameters.bAntiSplint then + ApplyMortiseAntiSplint( Proc, Part) + end + + -- passaggio sul profilo + if Strategy.Machining.Milling.bIsApplicable then + local AuxiliaryData = {} + -- se molti passaggi richiesti, si fa svuotatura + -- TODO in attesa delle svuotature, si fanno passaggi senza limiti sul numero massimo. Poi togliere il FALSE nella condizione. + if false and Strategy.Machining.nMillingPathsNeeded > Strategy.Parameters.nMaxMillingPaths then + -- TODO. SERVONO NUOVE SVUOTATURE!!!! + else + -- aggiungo geometria + Strategy.Machining.Milling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, -1}} + Strategy.Machining.Milling.nToolIndex = Strategy.Machining.Milling.ToolInfo.nToolIndex + Strategy.Machining.Milling.nType = MCH_MY.MILLING + Strategy.Machining.Milling.vtToolDirection = Proc.FeatureInfo.vtMortiseN + Strategy.Machining.Milling.sDepth = Strategy.Parameters.dOverMatOnLength + + -- LeadIn / LeadOut + Strategy.Machining.Milling.LeadIn = {} + Strategy.Machining.Milling.LeadOut = {} + Strategy.Machining.Milling.LeadIn.nType = MCH_MILL_LI.TANGENT + Strategy.Machining.Milling.LeadOut.nType = MCH_MILL_LI.TANGENT + Strategy.Machining.Milling.LeadIn.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Strategy.Machining.Milling.LeadIn.dPerpDistance = 0 + Strategy.Machining.Milling.LeadOut.dTangentDistance = TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC + Strategy.Machining.Milling.LeadOut.dPerpDistance = 0 + + if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then + Strategy.Machining.Milling.sStage = 'AfterTail' + end + + -- sistemo il lato e la direzione di lavoro + Strategy.Machining.Milling.bInvert = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, false, true) + Strategy.Machining.Milling.nWorkside = EgtIf( TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + + Strategy.Machining.Milling.sUserNotes = EgtSetVal( 'MaxElev', EgtNumToString( Proc.FeatureInfo.dMortiseDepth, 1)) .. ';' + + -- TODO calcolare SCC + + -- passate con sovramateriale + AuxiliaryData.Clones = {} + for i = Strategy.Machining.nMillingPathsNeeded, 1, -1 do + -- il primo è il passaggio più esterno + local nIndexClones = Strategy.Machining.nMillingPathsNeeded - i + 1 + -- cambia solo sovrmateriale radiale + AuxiliaryData.Clones[nIndexClones] = {} + -- ultima passata con sovramateriale impostato + if i == 1 then + AuxiliaryData.Clones[nIndexClones].dRadialOffset = Strategy.Parameters.dOverMatOnRadius + else + -- suddivido step in base al numero passate da fare + local dRealSideStep = floor( ( Proc.FeatureInfo.dMortiseMaxDist - TOOLS[Strategy.Machining.Milling.ToolInfo.nToolIndex].dDiameter) / Strategy.Machining.nMillingPathsNeeded) + AuxiliaryData.Clones[nIndexClones].dRadialOffset = ( i - 1) * dRealSideStep + end + end + + -- aggiunge lavorazione + bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining.Milling, AuxiliaryData) + end + end + end + return bAreAllMachiningsAdded, Strategy.Result +end + +------------------------------------------------------------------------------------------------------------- + + return STR0007 \ No newline at end of file diff --git a/Strategies/Standard/STR0007/STR0007Config.lua b/Strategies/Standard/STR0007/STR0007Config.lua new file mode 100644 index 0000000..065ebb8 --- /dev/null +++ b/Strategies/Standard/STR0007/STR0007Config.lua @@ -0,0 +1,21 @@ +-- Parametri configurabili da cliente per strategia: STR0001 + +local STR0007Data = { + sStrategyId = 'STR0007', + Parameters = { + { sName = 'dOverMatOnLength', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza mortasa', sType = 'd'}, + { sName = 'dOverMatOnRadius', sNameNge = 'OVM_RADIUS', sValue = '0', sDescription = 'Sovramateriale larghezza mortasa', 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'}, + { sName = 'bAntiSplint', sNameNge = 'ANTI_SPLINT', sValue = 'true', sDescription = 'Attiva passaggio antischeggia', sType = 'b'}, + { sName = 'dMaxWasteLength', sNameNge = 'MAX_WASTE_LENGTH', sValue = '300', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'}, + { sName = 'dMaxWasteVolume', sNameNge = 'MAX_WASTE_VOLUME', sValue = '6000000', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'}, + { sName = 'sCuttingStrategy', sNameNge = 'EXEC_CUT_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 STR0007Data \ No newline at end of file