Files
databeamnew/Strategies/Standard/STR0015/STR0015.lua
T
2026-02-02 16:41:14 +01:00

881 lines
41 KiB
Lua

-- Strategia: STR0015
-- Descrizione
-- Fresatura di contorno
-- Feature tipo Profilo arcuato, Convesso, Concavo, Arco
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
local FaceData = require( 'FaceData')
local ID = require( 'Identity')
-- strategie di base
local BladeToWaste = require('BLADETOWASTE')
local FaceByBlade = require('FACEBYBLADE')
local FaceByMill = require('FACEBYMILL')
-- Tabella per definizione modulo
local STR0015 = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function GetEdgeToMachine( Proc, idFace, vtEdge)
local Edge
local dBestEdgeAngle = 999
for i = 1, #Proc.Faces[idFace].Edges do
local dAngle = abs( GetAngle( Proc.Faces[idFace].Edges[i].vtN, vtEdge) or 999)
if dAngle < dBestEdgeAngle then
dBestEdgeAngle = dAngle
Edge = Proc.Faces[idFace].Edges[i]
end
end
return Edge
end
-- TODO funzione recuperata da beam vecchio, verificare se possibile migliorare
---------------------------------------------------------------------
local function GetSawCutData( Proc, AuxId, vtNF, vtN)
local ptStart, vtNP
if ID.IsHeadConcaveProfile( Proc) or ID.IsHeadConvexProfile( Proc) or ID.IsHeadProfile( Proc) or ID.IsFrontProfile( Proc) then
vtNP = Vector3d( vtN)
-- comincio con la normale a 45deg
for i = 1, 3 do
if vtNP[i] > GEO.EPS_SMALL then
vtNP[i] = 1
elseif vtNP[i] < -GEO.EPS_SMALL then
vtNP[i] = -1
end
end
vtNP:normalize()
-- assegno un punto di passaggio
ptStart = EgtMP( AuxId, GDB_ID.ROOT)
local frOCS = Frame3d( ptStart, vtNP) ;
local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS)
ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0)
elseif ID.IsHeadCamberedProfile( Proc) then
vtNP = Vector3d( vtNF)
-- comincio con la normale a 45deg
for i = 1, 3 do
if vtNP[i] > GEO.EPS_SMALL then
vtNP[i] = 1
elseif vtNP[i] < -GEO.EPS_SMALL then
vtNP[i] = -1
end
end
vtNP:normalize()
-- assegno un punto di passaggio
ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0
-- determino asse di rotazione
local vtRot = - Y_AX()
if vtNF:getX() < 0 then vtRot = - vtRot end
if vtNF:getZ() < -0.1 then
vtRot = - vtRot
elseif vtNF:getY() < -0.1 then
vtRot:rotate( X_AX(), 90)
elseif vtNF:getY() > 0.1 then
vtRot:rotate( X_AX(), -90)
end
-- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave)
vtNP[2] = 0 vtNP[3] = 0
local dRot = 45
for i = 1, 4 do
local vtNP2 = Vector3d( vtNP)
vtNP2:rotate( vtRot, dRot)
local frRef = Frame3d( ptStart, vtNP2)
local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef)
if b3Box:getMax():getZ() < -3 then
vtNP = Vector3d( vtNP2)
end
dRot = dRot / 2
end
end
-- restituisco i dati del piano
return ptStart, vtNP
end
-------------------------------------------------------------------------------------------------------------
local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries)
local Machining = {}
local Result = {}
-- ====== Taglio di sgrossatura generale su tutto il profilo ======
local vtNF = EgtSurfTmFacetNormVersor( Proc.id, Proc.nFct-1, GDB_ID.ROOT)
local nMidFacet = Proc.nFct // 2 -- faccia a metà circa
local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT)
local idAddGroup
if bSaveAddedGeometries then
idAddGroup = BeamLib.GetAddGroup( Part.id)
else
idAddGroup = Part.idTempGroup
end
-- aggiungo piano di sgrossatura e lo lavoro
local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN)
local AddId = EgtSurfTmPlaneInBBox( idAddGroup, ptStart, vtNP, Part.b3Part, GDB_RT.GLOB)
-- se la faccia è stata creata
if AddId then
-- creo piano di taglio sulla testa del tenone
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
bReduceBladePath = Strategy.Parameters.bReduceBladePath
}
Machining, Result = BladeToWaste.Make( AddId, Part, OptionalParameters)
-- se non ci sono lavorazioni, provo con fresa
if not Machining or #Machining == 0 then
Machining.bCuttingWithMill = true
-- === ricerca utensile per svuotare taglio iniziale, se taglio non possibile ===
if not( Proc.AffectedFaces.bLeft) or Strategy.bCanMoveAfterSplit then
ToolSearchParameters = {}
-- TODO SISTEMARE!!! qui la svuotatura non deve limitare l'elevazione se aperta da tutti i lati. In futuro si deve passare 0 come elevazione
ToolSearchParameters.dElevation = EgtSurfTmFacetElevationInBBox( AddId, 0, Part.b3Part, true, GDB_ID.ROOT)
ToolSearchParameters.vtToolDirection = vtNP
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Machining.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- TODO anche il test sul ResidualDepth va tolto
if Machining.ToolInfo.nToolIndex and ( Machining.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL) then
Machining.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Machining.ToolInfo.nToolIndex
Result.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
Result.sStatus = 'Completed'
Machining.Steps = {}
Machining.LeadIn = {}
Machining.nType = MCH_MY.POCKETING
Machining.nSubType = MCH_POCK_SUB.SPIRALIN
Machining.LeadIn.nType = MCH_POCK_LI.ZIGZAG
Machining.Steps.dStep = TOOLS[Machining.ToolInfo.nToolIndex].dStep
Machining.Steps.dSideStep = TOOLS[Machining.ToolInfo.nToolIndex].dSideStep
Machining.nToolIndex = Machining.ToolInfo.nToolIndex
Machining.LeadIn.dTangentDistance = TOOLS[Machining.ToolInfo.nToolIndex].dDiameter/2
Machining.LeadIn.dElevation = TOOLS[Machining.ToolInfo.nToolIndex].dDiameter/2
Machining.sDepth = 0
Machining.Geometry = {{ AddId, 0}}
Machining.vtToolDirection = vtNF
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Machining.sStage = 'AfterTail'
end
-- tempo di svuotatura
Result.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
end
end
end
end
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
local function GetEdgeWithCornerStrategy( Proc, Part)
local Machining = {}
local Result = { dCompletionPercentage = 100}
local nFirstFacet = 0 -- faccia iniziale
local nLastFacet = Proc.nFct - 1 -- faccia finale
-- verifico se necessari ripassi agli estremi negli angoli
local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT)
local bFirstTrim = ( dFirstAng and dFirstAng < -30)
local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT)
local bLastTrim = ( dLastAng and dLastAng < -30)
local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa
local vtN = EgtSurfTmFacetNormVersor( Proc.id, nMidFacet, GDB_ID.ROOT)
-- se non ci sono angoli da pulire si esce subito
if Strategy.Parameters.sConcaveFaceStrategy == 'NONE' or ( not bFirstTrim and not bLastTrim) then
return nil, nil
end
local FacesToGet = {}
if bFirstTrim then
table.insert( FacesToGet, nFirstFacet)
table.insert( FacesToGet, nFirstFacet+1)
end
if bLastTrim then
table.insert( FacesToGet, nLastFacet - 1)
table.insert( FacesToGet, nLastFacet)
end
-- ricavo info facce da lavorare
Proc.Faces = FaceData.GetFacesInfo( Proc, Part, FacesToGet)
-- direzioni di lavorazione
local vtCutDir1
-- se è diretta verso alto o basso
if abs( vtN:getZ()) > abs( vtN:getY()) then
if vtN:getZ() > 0 then
vtCutDir1 = Z_AX()
else
vtCutDir1 = -Z_AX()
end
-- altrimenti è di fianco
else
if vtN:getY() > 0 then
vtCutDir1 = Y_AX()
else
vtCutDir1 = -Y_AX()
end
end
local vtCutDir2
if vtN:getX() > 0 then
vtCutDir2 = X_AX()
else
vtCutDir2 = -X_AX()
end
local nMachiningsToAdd
-- AUTO = preferisce lama. Se non è possibile prende fresa
-- BLADE_FORCED = solo lama, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento)
-- MILL_FORCED = solo fresa, altriemnti non applica nulla (potrebbe essere necessario un ribaltamento)
if Strategy.Parameters.sConcaveFaceStrategy == 'AUTO' or Strategy.Parameters.sConcaveFaceStrategy == 'BLADE_FORCED' then
nMachiningsToAdd = 0
-- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra?
-- lavorazione faccia 1 spigolo finale
if bLastTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
local EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet+1, vtCutDir1)
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet+1], EdgeToMachine)
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Cutting.sStage = 'AfterTail'
end
if Cutting.bIsApplicable then
table.insert( Machining, Cutting)
end
end
-- lavorazione faccia 1 spigolo iniziale
if bFirstTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1)
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine)
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Cutting.sStage = 'AfterTail'
end
if Cutting.bIsApplicable then
table.insert( Machining, Cutting)
end
end
-- lavorazione faccia 2 spigolo finale
if bLastTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2)
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine)
if Cutting.bIsApplicable then
table.insert( Machining, Cutting)
end
end
-- lavorazione faccia 2 spigolo iniziale
if bFirstTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+1, vtCutDir2)
local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[nFirstFacet+1], EdgeToMachine)
if Cutting.bIsApplicable then
table.insert( Machining, Cutting)
end
end
end
-- se non ci sono lavorazioni provo a pulire spigoli con fresa, a patto che non sia stato forzato con lama
if ( not nMachiningsToAdd or ( #Machining < nMachiningsToAdd)) and Strategy.Parameters.sConcaveFaceStrategy ~= 'BLADE_FORCED' then
Machining = {}
nMachiningsToAdd = 0
-- TODO c'è una funzione che ritorni l'edge di connessione tra una faccia e un'altra?
-- lavorazione faccia 1 spigolo iniziale
if bFirstTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
local EdgeToMachine = GetEdgeToMachine( Proc, nFirstFacet+2, vtCutDir1)
local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nFirstFacet+2], EdgeToMachine)
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Milling.sStage = 'AfterTail'
end
if Milling.bIsApplicable then
table.insert( Machining, Milling)
end
end
-- lavorazione faccia 2 spigolo finale
if bLastTrim then
nMachiningsToAdd = nMachiningsToAdd + 1
EdgeToMachine = GetEdgeToMachine( Proc, nLastFacet, vtCutDir2)
local Milling = FaceByMill.Make( Proc, Part, Proc.Faces[nLastFacet], EdgeToMachine)
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Milling.sStage = 'AfterTail'
end
if Milling.bIsApplicable then
table.insert( Machining, Milling)
end
end
end
if nMachiningsToAdd and ( #Machining < nMachiningsToAdd) then
Result = { dCompletionPercentage = ( #Machining / nMachiningsToAdd)}
end
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
local function GetChamferStrategy( Proc, Part)
local Machining = {}
local Result = {}
local ToolSearchParameters = {}
local dExtraDepth = 2
local vtExtr = EgtCurveExtrusion( Proc.idAddAuxGeom, GDB_RT.GLOB)
local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL
local bToolInvert = ( vtExtr:getZ() < -0.1)
if Strategy.Parameters.dDepthChamfer > 100 * GEO.EPS_SMALL then
-- controllo conformità affondamento smussi
Strategy.Parameters.dDepthChamfer = EgtClamp( Strategy.Parameters.dDepthChamfer, 0.1, 5)
-- si prapara tabella con parametri di base comuni a tutte le lavorazioni
local BasicMach = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
BasicMach.Geometry = {{ Proc.idAddAuxGeom, -1}}
BasicMach.nType = MCH_MY.MILLING
BasicMach.sDepth = Strategy.Parameters.dDepthChamfer + dExtraDepth
-- LeadIn / LeadOut
BasicMach.LeadIn.nType = MCH_MILL_LI.NONE
BasicMach.LeadOut.nType = MCH_MILL_LI.NONE
BasicMach.LeadIn.dStartAddLength = 5
BasicMach.LeadOut.dEndAddLength = 5
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
BasicMach.sStage = 'AfterTail'
end
BasicMach.ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
BasicMach.ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
BasicMach.dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
BasicMach.vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
BasicMach.dLengthOnX = Proc.b3Box:getDimX()
-- parametri di ricerca utensile comuni a tutte le lavorazioni
ToolSearchParameters.sMillShape = 'VMILL'
ToolSearchParameters.dElevation = Strategy.Parameters.dDepthChamfer
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'MillingSmooth')
-- se lavorazione orizzontale
if bIsHorizontal then
local Milling = {}
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- se trovato utensile adatto
if Milling.ToolInfo.nToolIndex then
Milling.vtToolDirection = ToolSearchParameters.vtToolDirection
Milling.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dRadialOffset = dExtraDepth * cos( TOOLS[Milling.nToolIndex].dSideAngle)
Milling.bInvert = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, false, true)
Milling.nWorkside = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
Milling = BeamLib.MergeTables( BasicMach, Milling)
table.insert( Machining, Milling)
local Milling2 = BeamLib.TableCopyDeep( Milling)
Milling2.bToolInvert = true
Milling2.bInvert = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, true, false)
Milling2.nWorkside = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
table.insert( Machining, Milling2)
end
-- se lavorazione verticale
else
-- si cerca utensile 1
local Milling = {}
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
Milling.vtToolDirection = ToolSearchParameters.vtToolDirection
-- si cerca utensile 2
local Milling2 = {}
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr)
Milling2.ToolInfo = {}
Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
Milling2.vtToolDirection = ToolSearchParameters.vtToolDirection
Milling2.bToolInvert = true
-- se trovato utensile 1 adatto
if Milling.ToolInfo.nToolIndex then
Milling.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dRadialOffset = dExtraDepth * cos( TOOLS[Milling.nToolIndex].dSideAngle)
Milling.bInvert = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, false, true)
Milling.nWorkside = EgtIf( TOOLS[Milling.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
Milling = BeamLib.MergeTables( BasicMach, Milling)
table.insert( Machining, Milling)
end
-- se trovato utensile 2 adatto
if Milling2.ToolInfo.nToolIndex then
Milling2.nToolIndex = Milling2.ToolInfo.nToolIndex
Milling2.dRadialOffset = dExtraDepth * cos( TOOLS[Milling2.nToolIndex].dSideAngle)
Milling2.bToolInvert = true
Milling2.bInvert = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, true, false)
Milling2.nWorkside = EgtIf( TOOLS[Milling2.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
Milling2 = BeamLib.MergeTables( BasicMach, Milling2)
table.insert( Machining, Milling2)
end
end
end
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
local function GetArcStrategy( Proc, Part)
local Machining = {}
local Result = { dCompletionPercentage = 100}
local ToolSearchParameters = {}
-- recupero i dati della curva e del profilo
local dDepth = abs( EgtCurveThickness( Proc.idAddAuxGeom))
local vtExtr = EgtCurveExtrusion( Proc.idAddAuxGeom, GDB_RT.GLOB)
local bToolInvert = ( vtExtr:getZ() < -0.1)
local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL
local bIsFeatureDown = Proc.AffectedFaces.bBottom and not Proc.AffectedFaces.bTop
local bIsFeatureBack = Proc.AffectedFaces.bBack and not Proc.AffectedFaces.bFront
local bForceStrip = Strategy.Parameters.bForceStrip
local dDimStrip = EgtIf( Strategy.Parameters.dStripWidth < 100 * GEO.EPS_SMALL, nil, Strategy.Parameters.dStripWidth)
local sMaxDepth = dDepth * 2
local bExecStrip = false
-- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato
if ID.IsRoundArch( Proc) and ( bIsFeatureDown or bIsFeatureBack or bForceStrip) then
if bIsFeatureDown or bIsFeatureBack then
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5)
else
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP_SMALL or 5, 1)
end
bExecStrip = true
end
if not bExecStrip then
dDimStrip = 0
end
-- la passata di finitura c'è sempre
local nPassages = 1
-- si verifica se fare passaggio di sgrossatura con fresa
if not bExecStrip and Strategy.Parameters.dOverMaterial > 100 * GEO.EPS_SMALL then
nPassages = 2
end
-- ciclo su numero passate (2 in caso di sgrossatura + finitura)
for nCycle = nPassages, 1, -1 do
local nMaxDiamMill = EgtIf( nCycle == 1, Strategy.Parameters.dMaxCornerRadius * 2, nil)
local sTypeTool = EgtIf( nCycle == 1 and nPassages == 2, 'MillingFinish', 'Milling')
-- se lavorazione orizzontale
if bIsHorizontal then
local bDouble
local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dElevation = EgtIf( bExecStrip, ( dDepth - dDimStrip) / 2, dDepth + BeamData.MILL_OVERLAP)
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, sTypeTool)
ToolSearchParameters.dMaxToolDiameter = nMaxDiamMill
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- se posso lavorare in una passata, ma utensile trovato non completa la lavorazione,
-- allora provo a cercare utensile con massimo materiale sufficiente per fare le due passate, magari trova un utensile più prestante
if Milling.ToolInfo.nToolIndex then
if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL and not bExecStrip then
bDouble = true
ToolSearchParameters.dElevation = ( dDepth + BeamData.MILL_OVERLAP) / 2
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
end
Milling.vtToolDirection = ToolSearchParameters.vtToolDirection
if nCycle == 2 then
Milling.dRadialOffset = Strategy.Parameters.dOverMaterial
end
-- se non completo
if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL then
sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth
-- si salva percentuala lavorata
Result.dCompletionPercentage = 100 - ceil( ( Milling.ToolInfo.dResidualDepth / ToolSearchParameters.dElevation) * 100)
end
if bDouble or bExecStrip then
if bDouble then
Milling.sDepth = min( sMaxDepth, ( dDepth + BeamData.MILL_OVERLAP) / 2)
else
Milling.sDepth = min( sMaxDepth, ( dDepth - dDimStrip) / 2)
end
table.insert( Machining, Milling)
local Milling2 = BeamLib.TableCopyDeep( Milling)
Milling2.bOtherDirection = true
table.insert( Machining, Milling2)
else
Milling.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP)
table.insert( Machining, Milling)
end
end
-- se lavorazione verticale
else
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, sTypeTool)
ToolSearchParameters.dMaxToolDiameter = nMaxDiamMill
-- si cerca utensile 1
local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if nCycle == 2 then
Milling.dRadialOffset = Strategy.Parameters.dOverMaterial
end
Milling.vtToolDirection = ToolSearchParameters.vtToolDirection
Milling.bOtherDirection = bToolInvert
-- si cerca utensile 2
local Milling2 = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr)
Milling2.ToolInfo = {}
Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if nCycle == 2 then
Milling2.dRadialOffset = Strategy.Parameters.dOverMaterial
end
Milling2.vtToolDirection = ToolSearchParameters.vtToolDirection
Milling2.bOtherDirection = bToolInvert
-- se serve codolo
if bExecStrip then
local sDepthMachined = 0
-- se a disposizione entrambi gli utensili
if Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
local dExtraDepth = ( dDepth - dDimStrip - ( Milling.ToolInfo.dResidualDepth + Milling2.ToolInfo.dResidualDepth)) / 2
Milling.sDepth = dDepth - Milling.ToolInfo.dResidualDepth - dExtraDepth
Milling2.sDepth = dDepth - Milling2.ToolInfo.dResidualDepth - dExtraDepth
sDepthMachined = Milling.sDepth + Milling2.sDepth
table.insert( Machining, Milling)
table.insert( Machining, Milling2)
-- se disponibile solo primo utensile
elseif Milling.ToolInfo.nToolIndex then
sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth
Milling.sDepth = min( sMaxDepth, dDepth - dDimStrip)
table.insert( Machining, Milling)
sDepthMachined = Milling.sDepth
-- se disponibile solo secondo utensile
elseif Milling2.ToolInfo.nToolIndex then
sMaxDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth
Milling2.sDepth = min( sMaxDepth, dDepth - dDimStrip)
table.insert( Machining, Milling2)
sDepthMachined = Milling2.sDepth
-- nessun utensile disponibile
else
-- non si fa nulla
end
Result.dCompletionPercentage = min( ( sDepthMachined * 100) / ( dDepth - dDimStrip), 100)
-- altrimenti senza codolo
else
local sDepthMachined = 0
local dExtraDepth = ( dDepth - BeamData.MILL_OVERLAP - ( Milling.ToolInfo.dResidualDepth + Milling2.ToolInfo.dResidualDepth)) / 2
-- se utensile 1 esegue completamente (con almeno 1mm extra)
if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 1000 * GEO.EPS_SMALL then
sMaxDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth
Milling.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP)
table.insert( Machining, Milling)
sDepthMachined = Milling.sDepth
-- se utensile 2 esegue completamente (con almeno 1mm extra)
elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 1000 * GEO.EPS_SMALL then
sMaxDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth
Milling2.sDepth = min( sMaxDepth, dDepth + BeamData.MILL_OVERLAP)
table.insert( Machining, Milling2)
sDepthMachined = Milling2.sDepth
-- se possono lavorare entrambi
elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
Milling.sDepth = dDepth - Milling.ToolInfo.dResidualDepth - dExtraDepth
Milling2.sDepth = dDepth - Milling2.ToolInfo.dResidualDepth - dExtraDepth
table.insert( Machining, Milling)
table.insert( Machining, Milling2)
sDepthMachined = Milling.sDepth + Milling2.sDepth
-- se utensile 1 non completo
elseif Milling.ToolInfo.nToolIndex then
Milling.sDepth = ToolSearchParameters.dElevation - Milling.ToolInfo.dResidualDepth
table.insert( Machining, Milling)
sDepthMachined = Milling.sDepth
-- se utensile 2 non completo
elseif Milling2.ToolInfo.nToolIndex then
Milling2.sDepth = ToolSearchParameters.dElevation - Milling2.ToolInfo.dResidualDepth
table.insert( Machining, Milling2)
sDepthMachined = Milling2.sDepth
end
Result.dCompletionPercentage = min( ( sDepthMachined * 100) / ( dDepth - dDimStrip), 100)
end
end
end
Machining.bIsApplicable = #Machining > 0
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
local function GetFeatureResult( Proc)
local Result = { sStatus = 'Completed', dCompletionPercentage = 100, sInfo = ''}
local dPercentageChamfer = 10
local dPercentageEdgeCorner = 10
local dPercentageProfile = 80
-- se non ci sono lavorazioni di smusso
if not Strategy.Chamfer.Machinings or #Strategy.Chamfer.Machinings < 2 then
-- se esclusivo, non applicabile
if Strategy.Parameters.bOnlyChamfer then
Result = FeatureLib.GetStrategyResultNotApplicable( 'Not possible to machine chamfer only, tool not found!')
Result.dCompletionPercentage = 0
-- se non esclusivo, non completo
elseif Strategy.Parameters.dDepthChamfer > 100 * GEO.EPS_SMALL then
Result.dCompletionPercentage = Result.dCompletionPercentage - dPercentageChamfer -- gli smussi incidono per il 10%
dPercentageChamfer = 0
Result.sInfo = '- Chamfer not executed, tool not found!\n'
end
end
-- se richieste anche le altre lavorazioni
if not Strategy.Parameters.bOnlyChamfer then
-- per tutti tranne che per feature RoundArc
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
-- se sgrossatura da eseguire
if Strategy.Parameters.bExecRough then
if not Strategy.RoughCut.Machinings or #Strategy.RoughCut.Machinings == 0 then
Result.dCompletionPercentage = Result.dCompletionPercentage -- non incide sulla percentuale lavorata, solo messaggio che manca
Result.sInfo = Result.sInfo .. '- Roughing not executed\n'
end
end
-- se lavorazioni corner
if Strategy.EdgeWithCorner.Machinings and #Strategy.EdgeWithCorner.Machinings == 0 then
Result.dCompletionPercentage = Result.dCompletionPercentage - dPercentageEdgeCorner -- la pulizia dei corner incide per il 10%
dPercentageEdgeCorner = 0
Result.sInfo = Result.sInfo .. '- Corner not executed, material left\n'
end
end
-- lavorazione del profilo
if not Strategy.Profile.Machinings or #Strategy.Profile.Machinings == 0 then
Result.sInfo = Result.sInfo .. '- Profile not executed, tool not found!\n'
else
local dTotalPercentage = dPercentageProfile + dPercentageEdgeCorner + dPercentageChamfer
Result.dCompletionPercentage = Result.dCompletionPercentage - ( ( ( 100 - Strategy.Profile.Result.dCompletionPercentage) * dTotalPercentage) / 100)
end
end
-- si setta lo stato in base alla percentuale di completamento
if Result.dCompletionPercentage == 100 then
Result.sStatus = "Completed"
elseif Result.dCompletionPercentage == 0 then
Result.sStatus = "Not-Applicable"
else
Result.sStatus = "Not-Completed"
local dPercentageLeft = ceil( 100 - Result.dCompletionPercentage)
Result.sInfo = Result.sInfo .. '- Not Complete : left ' .. tostring( dPercentageLeft) .. '%\n'
end
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage)
Result.dMRR = 1
-- se tutte le lavorazioni sono state eseguite, è la massima qualità che si possa ottenere, altrimenti qualità più bassa
if Result.sInfo == '' then
Result.dQuality = FeatureLib.GetStrategyQuality( 'BEST')
else
Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL')
end
return Result
end
-------------------------------------------------------------------------------------------------------------
function STR0015.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 = STRATEGIES_CONFIG[CustomParameters.sStrategyId]
Strategy.sName = StrategyLib.Config.sStrategyId
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config)
Strategy.Chamfer = {}
Strategy.Chamfer.Machinings = {}
Strategy.Chamfer.Result = {}
Strategy.Result = {}
local bAreAllMachiningsAdded = true
-- verifico se la lavorazione può essere spostata dopo taglio di coda
local dLengthOnX = Proc.b3Box:getDimX()
Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
-- recupero e verifico l'entità curva
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i')
if idAux then idAux = idAux + Proc.id end
if not idAux or ( EgtGetType( idAux) & GDB_FY.GEO_CURVE) == 0 then
local sErr = 'Error on process ' .. tostring( Proc.id) .. ' missing profile geometry'
EgtOutLog( sErr)
return false, sErr
end
Proc.idAddAuxGeom = idAux
-- lavorazione smussi
Strategy.Chamfer.Machinings, Strategy.Chamfer.Result = GetChamferStrategy( Proc, Part)
-- se non bisogna fare solo gli smussi, si calcolano le altre lavorazioni
if not Strategy.Parameters.bOnlyChamfer then
-- per tutti tranne che per feature RoundArc
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
-- lavorazione taglio per sgrossare
if Strategy.Parameters.bExecRough then
Strategy.RoughCut = {}
Strategy.RoughCut.Machinings = {}
Strategy.RoughCut.Result = {}
Strategy.RoughCut.Machinings, Strategy.RoughCut.Result = GetRoughStrategy( Proc, Part, bAddMachining)
end
-- lavorazione degli estremi con angoli interni
Strategy.EdgeWithCorner = {}
Strategy.EdgeWithCorner.Machinings = {}
Strategy.EdgeWithCorner.Result = {}
Strategy.EdgeWithCorner.Machinings, Strategy.EdgeWithCorner.Result = GetEdgeWithCornerStrategy( Proc, Part)
end
-- lavorazione profilo (a meno che non si facciano solo smussi)
Strategy.Profile = {}
Strategy.Profile.Machinings = {}
Strategy.Profile.Result = {}
Strategy.Profile.Machinings, Strategy.Profile.Result = GetArcStrategy( Proc, Part)
end
Strategy.Result = GetFeatureResult( Proc)
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
-- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
-- lavorazione degli smussi
if Strategy.Chamfer.Machinings then
for i = 1, #Strategy.Chamfer.Machinings do
local MachiningToSplit = {}
table.insert( MachiningToSplit, Strategy.Chamfer.Machinings[i])
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
-- aggiunge lavorazione
for j = 1, #MachiningResult do
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j])
end
end
end
-- per tutti tranne che per feature RoundArc
if not ID.IsRoundArch( Proc) and not ID.IsFreeContour( Proc) then
-- lavorazione di sgrezzatura di lama
if Strategy.Parameters.bExecRough and Strategy.RoughCut.Machinings then
-- se cutting da fare come svuotatura
if Strategy.RoughCut.Machinings.bCuttingWithMill then
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.RoughCut.Machinings)
-- taglio di lama
else
for i = 1, #Strategy.RoughCut.Machinings do
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Strategy.RoughCut.Machinings[i].sStage = 'AfterTail'
end
local bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Strategy.RoughCut.Machinings[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
end
end
-- lavorazione degli angoli interni
if Strategy.EdgeWithCorner.Machinings then
for i = 1, #Strategy.EdgeWithCorner.Machinings do
local bIsMachiningAdded = MachiningLib.AddMachinings( Proc, Strategy.EdgeWithCorner.Machinings[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
end
end
-- lavorazione del profilo
if Strategy.Profile.Machinings then
for i = 1, #Strategy.Profile.Machinings do
Strategy.Profile.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
Strategy.Profile.Machinings[i].nToolIndex = Strategy.Profile.Machinings[i].ToolInfo.nToolIndex
Strategy.Profile.Machinings[i].nType = MCH_MY.MILLING
Strategy.Profile.Machinings[i].Steps = MachiningLib.GetMachiningSteps( false, tonumber( Strategy.Profile.Machinings[i].sDepth), TOOLS[Strategy.Profile.Machinings[i].nToolIndex].dStep)
Strategy.Profile.Machinings[i].Steps.nStepType = MCH_MILL_ST.ONEWAY
-- LeadIn / LeadOut
Strategy.Profile.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
Strategy.Profile.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
Strategy.Profile.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadIn.dPerpDistance = 0
Strategy.Profile.Machinings[i].LeadIn.dStartAddLength = 0
Strategy.Profile.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadOut.dPerpDistance = 0
Strategy.Profile.Machinings[i].LeadOut.dEndAddLength = 0
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Strategy.Profile.Machinings[i].sStage = 'AfterTail'
end
-- preparo attacco/uscita in caso di spezzatura arco
Strategy.Profile.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadIn)
Strategy.Profile.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadOut)
Strategy.Profile.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Profile.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Profile.Machinings[i].LeadInForSplit.dTangentDistance = 0
Strategy.Profile.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadOutForSplit.dTangentDistance = 0
Strategy.Profile.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
-- sistemo il lato e la direzione di lavoro
if Strategy.Profile.Machinings[i].bOtherDirection then
Strategy.Profile.Machinings[i].bToolInvert = true
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
else
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
end
Strategy.Profile.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
Strategy.Profile.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
local MachiningToSplit = {}
table.insert( MachiningToSplit, Strategy.Profile.Machinings[i])
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
-- aggiunge lavorazione
for j = 1, #MachiningResult do
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j])
end
end
end
else
bAreAllMachiningsAdded = false
end
return bAreAllMachiningsAdded, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
return STR0015