- in FaceData e FeatureLib modifiche per gestire DoubleBevel

- in STR0010 modifiche per gestire casi non contemplati
This commit is contained in:
luca.mazzoleni
2026-03-03 09:45:11 +01:00
parent 8efb64810a
commit 0db6a74f8c
3 changed files with 124 additions and 74 deletions
+7 -3
View File
@@ -383,10 +383,14 @@ local function GetBottomFaces( Proc)
return { Proc.Faces[1]}
end
-- la faccia di fondo ha sempre Fct - 1 adiacenze
-- la faccia di fondo ha sempre Fct - 1 adiacenze, tranne caso speciale DoubleBevel con facce di chiusura triangolari
local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
if FacesByAdjacencyNumber then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1]
-- caso speciale DoubleBevel
if #BottomFaces == 0 then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct / 2]
end
-- si rimuovono le facce non adatte ad essere lavorate
local nBottomFaces = #BottomFaces
local nCurrentFace = 1
@@ -476,7 +480,7 @@ end
local function GetLongFaces( Proc, MainFaces)
local LongFaces = {}
if Proc.nFct > 5 then
if Proc.nFct > 6 then
error( 'GetLongFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
@@ -584,7 +588,7 @@ end
local function GetSideFaces( Proc, MainFaces)
local SideFaces = {}
if Proc.nFct > 5 then
if Proc.nFct > 6 then
error( 'GetSideFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
+2 -2
View File
@@ -244,7 +244,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 3 then
sFamily = 'Groove'
bIsThrough = false
elseif Proc.nFct == 4 and #vFacesByAdjNumber[2] == 4 and #vTriangularFaces == 2 then
elseif Proc.nFct == 4 and ( ( #vFacesByAdjNumber[2] == 2 and #vTriangularFaces == 2) or ( #vFacesByAdjNumber[3] == 2)) then
sFamily = 'DoubleBevel'
bIsThrough = false
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
@@ -259,7 +259,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then
sFamily = 'Pocket'
bIsThrough = false
elseif Proc.nFct == 6 and #vFacesByAdjNumber[2] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 then
elseif Proc.nFct == 6 and #vFacesByAdjNumber[1] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 then
sFamily = 'DoubleBevel'
bIsThrough = false
end
+115 -69
View File
@@ -34,7 +34,7 @@ local function GetStrategyCompletionPercentage( Machinings)
if nWeightsCount ~= 0 and nWeightsCount ~= i then
error( 'GetWeightedCompletionPercentage : inconsistent weights')
end
local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight
local dWeightedCompletionPercentage = ( Machining.dCompletionPercentage or 0) / 100 * dWeight
if Machining.bIsApplicable then
dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage
end
@@ -47,34 +47,52 @@ local function GetStrategyCompletionPercentage( Machinings)
end
-------------------------------------------------------------------------------------------------------------
local function CompareEdges( EdgeA, EdgeB)
-- prima i lati orientati lungo X
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then
local function CompareEdgesLongestTop( EdgeA, EdgeB)
-- si preferiscono i lati più lunghi
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true
elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
return false
-- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato)
-- se stessa lunghezza si preferiscono i lati più in basso
else
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
return false
-- se stessa lunghezza si preferiscono i lati più in basso
-- TODO qui dipenderà dalla lama scelta
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
return false
end
end
end
end
-------------------------------------------------------------------------------------------------------------
local function CompareEdgesLongestBottom( EdgeA, EdgeB)
-- si preferiscono i lati più lunghi
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
return false
-- se stessa lunghezza si preferiscono i lati più in alto
else
if EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
end
end
@@ -93,7 +111,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- TODO modificare funzione e verificare pinzaggio con regioni e area outline
local function IsPositionOK( Proc, Part)
local function IsPositionOk( Proc, Part)
local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
-- se impatta su faccia retro o sotto, controllo fattibilità
if Proc.AffectedFaces.bBack then
@@ -112,31 +130,24 @@ local function IsPositionOK( Proc, Part)
end
-------------------------------------------------------------------------------------------------------------
-- TODO da sistemare
local function GetBottomFaceEdge( Proc, nIndexFace)
local function GetLongEdgeToMachine( Face, bHeadType)
local Edge = {}
-- si lavora la bottom longitudinalmente
if Proc.nFct == 1 or Proc.Topology.sFamily == 'DoubleBevel' then
local BottomEdgesSorted = {}
for i = 1, #Proc.MainFaces.BottomFaces[nIndexFace].Edges do
table.insert( BottomEdgesSorted, Proc.MainFaces.BottomFaces[nIndexFace].Edges[i])
end
table.sort( BottomEdgesSorted, CompareEdges)
Edge = BottomEdgesSorted[1]
-- edge in comune tra le due facce
elseif Proc.nFct == 2 then
if nIndexFace == 1 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
elseif nIndexFace == 2 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
end
local EdgesSorted = {}
for i = 1, #Face.Edges do
table.insert( EdgesSorted, Face.Edges[i])
end
if bHeadType.bBottom then
table.sort( EdgesSorted, CompareEdgesLongestBottom)
else
if nIndexFace == 1 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
elseif nIndexFace == 2 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
end
table.sort( EdgesSorted, CompareEdgesLongestTop)
end
-- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) si mantiene il lato scelto
Edge = EdgesSorted[1]
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
if ( not EdgeOpposite.bIsOpen) and Edge.bIsOpen then
Edge = EdgeOpposite
end
return Edge
@@ -172,6 +183,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config)
Strategy.Machinings = {}
Strategy.Result = {}
local CalculatedMachinings = {}
-- controllo su topologia
if not IsTopologyOk( Proc) then
@@ -181,7 +193,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
-- controllo dimensioni solo se non è forzata
if not CustomParameters.bForcedStrategy then
if not IsPositionOK( Proc, Part) then
if not IsPositionOk( Proc, Part) then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
return false, Strategy.Result
end
@@ -212,41 +224,75 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
dExtendAfterTail = 10000
end
-- lavorazione della BottomFace
local bAreAllMachiningsAdded = true
local Milling = {}
local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
local EdgeToMachine = GetBottomFaceEdge( Proc, 1)
if EdgeToMachine.bIsOpen then
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
end
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[1], EdgeToMachine, OptionalParametersFaceByMill)
if Milling.bIsApplicable then
table.insert( Strategy.Machinings, Milling)
-- per prima si lavora sempre la BottomFace (deve avere 4 lati esatti)
local BottomFace1 = Proc.MainFaces.BottomFaces[1]
if #BottomFace1.Edges ~= 4 then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
return false, Strategy.Result
end
-- si lavora seconda BottomFace
if Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2]
-- se convesso o concavo maggiore di angolo retto
if dAngleBetweenFaces >= -91 then
Milling = {}
OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
EdgeToMachine = GetBottomFaceEdge( Proc, 2)
if EdgeToMachine.bIsOpen then
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
end
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill)
if Milling.bIsApplicable then
table.insert( Strategy.Machinings, Milling)
-- ricerca utensile
local ToolSearchParameters = {}
ToolSearchParameters.dElevation = BottomFace1.dElevation
ToolSearchParameters.vtToolDirection = BottomFace1.vtN
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = true
local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
local nToolIndex = ToolInfo.nToolIndex
-- se utensile non trovato si esce subito
if not TOOLS[nToolIndex] or not TOOLS[nToolIndex].sName then
local sMessage = 'Mill not found'
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
return false, Strategy.Result
end
-- per prima si lavora sempre la Bottom principale
local Milling = {}
local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
local BottomEdgeToMachine = GetLongEdgeToMachine( BottomFace1, TOOLS[nToolIndex].SetupInfo.HeadType)
if BottomEdgeToMachine.bIsOpen then
OptionalParametersFaceByMill.dDepthToMachine = BottomEdgeToMachine.dElevation + BeamData.CUT_EXTRA
end
Milling = FaceByMill.Make( Proc, Part, BottomFace1, BottomEdgeToMachine, OptionalParametersFaceByMill)
table.insert( CalculatedMachinings, Milling)
-- se necessario si lavora la seconda Bottom
local BottomFace2 = Proc.MainFaces.BottomFaces[2]
if BottomFace2 then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]
if dAngleBetweenFaces >= -89.5 then
local Milling2 = {}
if #BottomFace2.Edges == 4 then
local OptionalParametersFaceByMill2 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
local BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, TOOLS[nToolIndex].SetupInfo.HeadType)
if BottomEdgeToMachine2.bIsOpen then
OptionalParametersFaceByMill2.dDepthToMachine = BottomEdgeToMachine.dElevation + BeamData.CUT_EXTRA
end
Milling2 = FaceByMill.Make( Proc, Part, BottomFace2, BottomEdgeToMachine2, OptionalParametersFaceByMill2)
else
Milling2.bIsApplicable = false
end
table.insert( CalculatedMachinings, Milling2)
end
end
-- evenutali puliture lati chiusi
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( Strategy.Machinings)
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings)
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
-- lavorazioni da applicare spostate in lista finale
for i = 1, #CalculatedMachinings do
if CalculatedMachinings[i].bIsApplicable then
table.insert( Strategy.Machinings, CalculatedMachinings[i])
end
end
Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part)
table.sort( Strategy.Machinings, SortMachiningsBySegment)