Merge branch 'feature/DoubleCut' into develop

This commit is contained in:
luca.mazzoleni
2025-05-04 23:31:53 +02:00
7 changed files with 200 additions and 56 deletions
+5 -1
View File
@@ -566,7 +566,11 @@ if bToProcess then
for i = 1, #RESULT do
local sMsg = ''
if RESULT[i].sType == 'Feature' then
sMsg = RESULT[i].ChosenStrategy.sInfo
if RESULT[i].ChosenStrategy.bIsApplyOk then
sMsg = RESULT[i].ChosenStrategy.sInfo
else
sMsg = RESULT[i].ChosenStrategy.sApplyInfo
end
elseif RESULT[i].sType == 'Part' then
sMsg = RESULT[i].sMsg
end
+2
View File
@@ -61,6 +61,7 @@ local function GetStrategies_Egalware( Proc)
---------------------------------------------------------------------
-- Feature : Double Cut (1-11)
elseif ID.IsDoubleCut( Proc) then
Strategies = { { sStrategyId = 'STR0005'}}
---------------------------------------------------------------------
-- Feature : Ridge or Valley Cut (0-12)
elseif ID.IsDoubleLongitudinalCut( Proc) then
@@ -361,6 +362,7 @@ local function GetStrategies_Essetre( Proc)
---------------------------------------------------------------------
-- Feature : Double Cut (1-11)
elseif ID.IsDoubleCut( Proc) then
Strategies = { { sStrategyId = 'STR0005'}}
---------------------------------------------------------------------
-- Feature : Ridge or Valley Cut (0-12)
elseif ID.IsDoubleLongitudinalCut( Proc) then
+14 -1
View File
@@ -1036,7 +1036,6 @@ local function OrderFeatures( vProc)
end
-------------------------------------------------------------------------------------------------------------
-- TODO gestire Proc che non hanno una ChosenStrategy, perchè sono specchiate, multi (si legge il risultato da un'altra feature?) o non è stata trovata una strategia
local function AddFeatureResultToGlobalList( Proc, OptionalParameters)
local sStrategyId
local sStatus
@@ -1085,6 +1084,9 @@ local function AddFeatureResultToGlobalList( Proc, OptionalParameters)
RESULT[#RESULT].AvailableStrategies = BeamLib.TableCopyDeep( Proc.AvailableStrategies)
end
-- si segna nella Proc la sua posizione nel RESULT
Proc.nIndexInResult = #RESULT
return RESULT
end
@@ -1587,6 +1589,17 @@ function BeamExec.ProcessMachinings( PARTS)
bIsCombinationMachinable = bIsCombinationMachinable and bAllStrategiesApplied
end
-- cancellazione entità create ma non usate
-- TODO funzione?
local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id)
local idCreatedEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL)
while idCreatedEntity do
if EgtGetLevel( idCreatedEntity) == GDB_LV.TEMP then
EgtErase( idCreatedEntity)
end
idCreatedEntity = EgtGetNext( idCreatedEntity)
end
-- ordinamento lavorazioni
-- TODO completare ordinamento. Mancano le dipendenze.
-- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze
+6
View File
@@ -870,7 +870,13 @@ function MachiningLib.AddOperations( vProc, Part, sRotation)
bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false)
-- update risultati
-- TODO è corretto mettere non applicabile?????
RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sStatus = 'Not-Applicable'
RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sApplyInfo = sErr
RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.nApplyError = nErr
end
RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.bIsApplyOk = bIsApplyOk
-- TODO è giusto inserire queste info alla fine della lavorazione? oppure conviene creare un record in MACHININGS apposito per la disposizione?
-- se era taglio di separazione, aggiungo nuova fase
+1 -1
View File
@@ -26,7 +26,7 @@
"nGrp": "1",
"TopologyList" : [
{ "sName": "Feature",
"StrategyList" : [ ]
"StrategyList" : [ { "sStrategyID": "STR0005" } ]
}
]
},
+162 -48
View File
@@ -18,7 +18,6 @@ local DiceCut = require( 'DiceCut')
local FaceByBlade = require('FACEBYBLADE')
-- tabella per definizione modulo
local Machinings = {}
local FeatureInfo = {}
-------------------------------------------------------------------------------------------------------------
@@ -135,7 +134,10 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
local nChosenToolIndex
local sChosenBladeType
-- parametri opzionali
-- parametri opzionali e default
if not OptionalParameters then
OptionalParameters = {}
end
local dMinNzTopBladeIfEqual = OptionalParameters.dMinNzTopBlade or sin(-5)
local dMaxNyTopBlade = OptionalParameters.dMaxNyTopBlade or sin(1)
local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART
@@ -235,21 +237,28 @@ end
local function CutWholeWaste( Proc, Part, OptionalParameters)
local Machinings = {}
local Cutting = {}
local Result = {}
local EdgeToMachine = {}
local nToolIndex
local sChosenBladeType = ''
local dDepthToMachine = 0
local dCompletionPercentage = 0
-- parametri opzionali e default
if not OptionalParameters then
OptionalParameters = {}
end
local nToolIndex = OptionalParameters.nToolIndex
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
-- lato da lavorare in base al tipo di lama
local EdgeToMachineTopBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Top')
local EdgeToMachineBottomBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Bottom')
local EdgeToMachineTopBladeDownUp = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'TopDownUp')
-- scelta lama da sopra o da sotto
if OptionalParameters.nToolIndex then
if nToolIndex then
nToolIndex = OptionalParameters.nToolIndex
else
local OptionalParametersGetBestBlade = { dElevationTop = EdgeToMachineTopBlade.dElevation + BeamData.CUT_EXTRA,
@@ -262,7 +271,6 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
-- utensile non trovato
if not nToolIndex then
Result = FeatureLib.GetStrategyResultNotApplicable( 'Blade not found')
return Machinings, Result
end
@@ -280,7 +288,8 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
-- TODO qui gestire il caso in cui si può tagliare da due lati (inizialmente solo se vtN:Y è ~= 0?). Andranno ricercati gli utensili di nuovo con l'elevazione a metà??
if dResidualDepth < 10 * GEO.EPS_SMALL then
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = OptionalParameters.dExtendAfterTail}
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = dExtendAfterTail}
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade)
end
if Cutting.bIsApplicable then
@@ -309,59 +318,22 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
end
function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
Machinings = {}
local function CutWithDicing( Proc, Part, OptionalParameters)
local Machinings = {}
local Result = {}
-- disambiguazione feature vs id trimesh
local Proc = {}
if type( ProcOrId) == "table" then
Proc = ProcOrId
elseif type( ProcOrId) == "number" then
Proc = FeatureLib.GetProcFromTrimesh( ProcOrId, Part)
else
error( 'BLADETOWASTE : Only feature or trimesh supported')
end
-- controlli preventivi
if Proc.nFct > 2 then
error( 'BladeToWaste : max 2 faces supported')
elseif Proc.nFct == 2 then
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
error( 'BladeToWaste : angle between faces must be concave and >= 90deg')
end
end
-- parametri opzionali e default
if not OptionalParameters then
OptionalParameters = {}
end
local nToolIndex = OptionalParameters.nToolIndex
local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0
local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local b3BoxDicing = OptionalParameters.b3BoxDicing
local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries
if bSaveAddedGeometries == nil then
bSaveAddedGeometries = true
end
-- dimensioni feature
FeatureInfo.dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
FeatureInfo.dFeatureMaxDimension = max( Proc.b3Box:getDimX(), Proc.b3Box:getDimY())
FeatureInfo.bIsFeatureSmall = FeatureInfo.dFeatureVolume < dMaxWasteVolume + 10 * GEO.EPS_SMALL
and FeatureInfo.dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL
-- si taglia tutto lo scarto in una sola lavorazione
-- TODO qui si deve entrare anche se lo spessore lama è maggiore dell'elevazione delle faccia
if Proc.nFct == 1 and FeatureInfo.bIsFeatureSmall then
Machinings, Result = CutWholeWaste( Proc, Part, OptionalParameters)
if Result.sStatus == 'Completed' then
return Machinings, Result
end
end
-- TODO la lavorazione con cubetti va messa in una funzione
-- lavorazione con cubetti
-- scelta faccia da lavorare
-- se due facce, la faccia principale Face1 è la più grande
local Face1 = Proc.Faces[1]
@@ -376,11 +348,13 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
-- scelta lama da sopra o da sotto
local sChosenBladeType = ''
if not nToolIndex then
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Face1, OptionalParameters)
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Face1)
end
-- se non trovata lama la lavorazione non è fattibile
if not nToolIndex then
Result = FeatureLib.GetStrategyResultNotApplicable( 'Blade not found')
return Machinings, Result
end
@@ -400,6 +374,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension
OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced
OptionalParametersDiceCut.dMinNzDownUp = dMinNzDownUp
OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing
local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut)
-- se nessun cubetto trovato, si richiama il taglio singolo
@@ -415,7 +390,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local bAreOrthogonalCutsInverted = false
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
SetDiceFaceInfo( Proc, vCuts[i][j])
SetDiceFaceInfo( Proc, vCuts[i][j], bSaveAddedGeometries)
if ( i % 2) == 1 then
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
if ( Face1.vtN:getY() > 0.766 and vtO:getY() < -0.05) or
@@ -560,6 +535,145 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
return Machinings, Result
end
local function MakeOneFace( ProcOrId, Part, OptionalParameters)
local Machinings = {}
local Result = {}
-- disambiguazione feature vs id trimesh
local Proc = {}
if type( ProcOrId) == "table" then
Proc = ProcOrId
elseif type( ProcOrId) == "number" then
Proc = FeatureLib.GetProcFromTrimesh( ProcOrId, Part)
else
error( 'BLADETOWASTE : Only feature or trimesh supported')
end
-- parametri opzionali e default
if not OptionalParameters then
OptionalParameters = {}
end
local bForceDicing = OptionalParameters.bForceDicing or false
-- si taglia tutto lo scarto in una sola lavorazione
-- TODO qui si deve entrare anche se lo spessore lama è maggiore dell'elevazione delle faccia
if FeatureInfo.bIsFeatureSmall and not bForceDicing then
Machinings, Result = CutWholeWaste( Proc, Part, OptionalParameters)
end
-- se non completata con taglio singolo, lavorazione con cubetti
if not Result.sStatus or Result.sStatus ~= 'Completed' then
Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters)
end
return Machinings, Result
end
function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local Machinings = {}
local Result = {}
-- disambiguazione feature vs id trimesh
local Proc = {}
if type( ProcOrId) == "table" then
Proc = ProcOrId
elseif type( ProcOrId) == "number" then
Proc = FeatureLib.GetProcFromTrimesh( ProcOrId, Part)
else
error( 'BLADETOWASTE : Only feature or trimesh supported')
end
-- controlli preventivi
if Proc.nFct > 2 then
error( 'BladeToWaste : max 2 faces supported')
end
-- parametri opzionali e default
-- quelli non censiti sono gestiti direttamente nelle funzioni sotto e devono quindi solo transitare
if not OptionalParameters then
OptionalParameters = {}
end
local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0
local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0
local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries
if bSaveAddedGeometries == nil then
bSaveAddedGeometries = true
end
-- dimensioni feature
FeatureInfo.dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
FeatureInfo.dFeatureMaxDimension = max( Proc.b3Box:getDimX(), Proc.b3Box:getDimY())
FeatureInfo.bIsFeatureSmall = FeatureInfo.dFeatureVolume < dMaxWasteVolume + 10 * GEO.EPS_SMALL
and FeatureInfo.dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL
-- calcolo lavorazioni
if Proc.nFct == 1 then
Machinings, Result = MakeOneFace( Proc, Part, OptionalParameters)
elseif Proc.nFct == 2 then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2]
-- feature convessa: lavorata come 2 facce singole con prolungamento
if dAngleBetweenFaces > 10 * GEO.EPS_SMALL then
-- si creano superfici singole per le facce, estese fino al box della parte
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local idFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT)
local idFace2 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT)
if not bSaveAddedGeometries then
EgtSetLevel( idFace1, GDB_LV.TEMP)
EgtSetLevel( idFace2, GDB_LV.TEMP)
end
-- lavorazione facce
local Machinings1, Result1 = MakeOneFace( idFace1, Part, OptionalParameters)
local Machinings2, Result2 = MakeOneFace( idFace2, Part, OptionalParameters)
-- tutte le lavorazioni raggruppatee e calcolo area lavorata
local dAreaToMachineTotal = 0
for i = 1, #Machinings1 do
if Machinings1[i].bIsApplicable then
table.insert( Machinings, Machinings1[i])
dAreaToMachineTotal = dAreaToMachineTotal + Machinings1[i].dAreaToMachine
end
end
for i = 1, #Machinings2 do
if Machinings2[i].bIsApplicable then
table.insert( Machinings, Machinings2[i])
dAreaToMachineTotal = dAreaToMachineTotal + Machinings2[i].dAreaToMachine
end
end
-- calcolo risultati
Result.nQuality = FeatureLib.GetStrategyQuality( Machinings)
Result.dCompletionPercentage = dAreaToMachineTotal / ( Proc.Faces[1].dArea + Proc.Faces[2].dArea) * 100
Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage)
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
if Result1.sStatus == 'Completed' and Result2.sStatus == 'Completed' then
Result.sStatus = 'Completed'
elseif Result1.sStatus == 'Completed' or Result2.sStatus == 'Completed' then
Result.sStatus = 'Not-Completed'
else
Result.sStatus = 'Not-Applicable'
Result = FeatureLib.GetStrategyResultNotApplicable()
end
-- feature concava >= 90deg: lavorata con cubetti
elseif dAngleBetweenFaces >= -91 then
Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters)
-- feature concava < 90deg: lavorata come 2 facce singole con accorciamento
else
-- TODO da fare
end
end
return Machinings, Result
end
-------------------------------------------------------------------------------------------------------------
return BLADETOWASTE
+10 -5
View File
@@ -26,8 +26,8 @@ local function GetLeadInOutType( Machining)
else
sLeadInOutType = 'Tangent'
end
elseif abs( Machining.vtEdgeDirection:getZ()) < 0.7 then
sLeadInOutType = 'Tangent'
elseif abs( Machining.vtEdgeDirection:getZ()) > 0.7 then
sLeadInOutType = 'Perpendicular'
else
-- TODO qui attacco tangenziale speciale tutto da un lato
sLeadInOutType = 'Tangent'
@@ -42,7 +42,7 @@ local function GetLeadInOutType( Machining)
sLeadInOutType = 'Tangent'
end
elseif abs( Machining.vtEdgeDirection:getZ()) > 0.7 then
sLeadInOutType = 'Tangent'
sLeadInOutType = 'Perpendicular'
else
-- TODO qui attacco tangenziale speciale tutto da un lato
sLeadInOutType = 'Tangent'
@@ -96,8 +96,13 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, Part)
LeadIn.dPerpDistance = 1
LeadOut.dPerpDistance = 1
else
LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2
LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2
if abs( Machining.vtEdgeDirection:getZ()) > 0.707 then
LeadIn.dPerpDistance = 1
LeadOut.dPerpDistance = 1
else
LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2
LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2
end
end
end
LeadIn.dElevation = 0