diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 5a0947c..db886c6 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -250,6 +250,7 @@ elseif BEAM.FLAG == 9 then local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part) Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i') Proc.nPrc = EgtGetInfo( Proc.id, 'PRC', 'i') + Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1 Proc.Topology = {} if FeatureLib.NeedTopologyFeature( Proc, Part) then diff --git a/Strategies/Standard/STR0005/STR0005.lua b/Strategies/Standard/STR0005/STR0005.lua index df2c704..62b0764 100644 --- a/Strategies/Standard/STR0005/STR0005.lua +++ b/Strategies/Standard/STR0005/STR0005.lua @@ -66,7 +66,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) local dQualityAddedFace = 0 -- più di 3 facce non supportate - if Proc.nFct > 3 then + if Proc.nFct > 3 and ( not Proc.Topology.sFamily == 'DoubleBevel') then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'More than 3 faces not supported') end diff --git a/Strategies/Standard/STR0010/STR0010.lua b/Strategies/Standard/STR0010/STR0010.lua index fbaf928..e415f2d 100644 --- a/Strategies/Standard/STR0010/STR0010.lua +++ b/Strategies/Standard/STR0010/STR0010.lua @@ -238,8 +238,9 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters) local bAreAllMachiningsAdded = true - -- per prima si lavora sempre la BottomFace (deve avere 4 lati esatti) + -- ricerca delle Bottom (la principale deve avere 4 lati esatti) local BottomFace1 = Proc.MainFaces.BottomFaces[1] + local BottomFace2 = Proc.MainFaces.BottomFaces[2] if #BottomFace1.Edges ~= 4 then Strategy.Result = FeatureLib.GetStrategyResultNotApplicable() return false, Strategy.Result @@ -274,7 +275,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters) table.insert( CalculatedMachinings, Milling1) -- se necessario si lavora la seconda Bottom (solo se ha 4 lati esatti) - local BottomFace2 = Proc.MainFaces.BottomFaces[2] local Milling2 local BottomEdgeToMachine2 if BottomFace2 then @@ -405,7 +405,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters) end end - -- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachinings) Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) diff --git a/StrategyLibs/BLADEKEEPWASTE.lua b/StrategyLibs/BLADEKEEPWASTE.lua index 521d5ba..4fb1333 100644 --- a/StrategyLibs/BLADEKEEPWASTE.lua +++ b/StrategyLibs/BLADEKEEPWASTE.lua @@ -19,40 +19,57 @@ local FaceByMill = require('FACEBYMILL') -- tabelle per definizione modulo ------------------------------------------------------------------------------------------------------------- -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 GetLongEdgeToMachine( Face, bHeadType) + local Edge = {} + + local EdgesSorted = {} + for i = 1, #Face.Edges do + table.insert( EdgesSorted, Face.Edges[i]) + end + table.sort( EdgesSorted, CompareEdgesLongestTop) + + -- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) la lavorazione non è applicabile + Edge = EdgesSorted[1] + local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN) + if not EdgeOpposite.bIsOpen then + if Edge.bIsOpen then + Edge = EdgeOpposite + -- entrambi i lati non accessibili: codolo non applicabile + else + return nil + end + end + + return Edge +end + + local function SortMachiningsBySegment( MachiningA, MachiningB) if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then return false @@ -118,6 +135,76 @@ local function GetStrategyCompletionPercentage( Machinings) end +local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters) + local Cuttings = {} + local Cutting1 = {} + local Cutting2 = {} + + -- parametri dal chiamante + local bIsSplitFeature = Parameters.bIsSplitFeature + local dExtendAfterTail = Parameters.dExtendAfterTail + local nToolIndex = Parameters.nToolIndex + local dStripWidth = Parameters.dStripWidth + local OtherBottomFace = Parameters.OtherBottomFace + + local dDepthToMachine = EdgeToMachine.dElevation / 2 - dStripWidth / 2 + local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -EdgeToMachine.vtN) + + -- primo lato + if EdgeToMachineOpposite.bIsOpen then + Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1) + end + Cutting1.nInternalSortingPriority = 3 + Cutting1.dResultWeight = 0.3 + + -- secondo lato + local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1) + OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled' + if EdgeToMachine.bIsOpen then + Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2) + end + Cutting2.nInternalSortingPriority = 3 + Cutting2.dResultWeight = 0.3 + + -- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto + if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then + + -- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro + if EdgeToMachine.idAdjacentFace == OtherBottomFace.id then + dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth + end + dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth) + OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine + + Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2) + Cutting2.nInternalSortingPriority = 3 + Cutting2.dResultWeight = 0.3 + table.insert( Cuttings, Cutting2) + + elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then + + -- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro + if EdgeToMachine.idAdjacentFace == OtherBottomFace.id then + dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth + end + dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth) + OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine + + Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1) + Cutting1.nInternalSortingPriority = 3 + Cutting1.dResultWeight = 0.3 + table.insert( Cuttings, Cutting1) + + else + table.insert( Cuttings, Cutting1) + table.insert( Cuttings, Cutting2) + end + + return Cuttings +end + + function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) -- TODO verificare funzionamento con lama da sotto -- TODO scelta utensile è corretto lasciarla a FaceByBlade? @@ -126,12 +213,11 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) local Result = {} local Machinings = {} local CalculatedMachinings = {} - local Cutting1 = {} - local Cutting2 = {} -- controlli preventivi - if Proc.nFct > 3 then - error( 'BladeKeepWaste : max 3 faces supported') + if Proc.nFct > 3 and ( not Proc.Topology.sFamily == 'DoubleBevel') then + Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : max 3 faces supported') + return Machinings, Result elseif Proc.nFct == 2 then -- per angolo tra le facce >= 90deg (feature convessa) non applicabile if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then @@ -160,12 +246,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) end local nToolIndex = OptionalParameters.nToolIndex local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 - local bFinishWithMill - if OptionalParameters.bFinishWithMill == nil then - bFinishWithMill = true - else - bFinishWithMill = OptionalParameters.bFinishWithMill - end + local bFinishWithMill = ( OptionalParameters.bFinishWithMill ~= false) local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1 local dStripWidth = OptionalParameters.dStripWidth or 5 local bForced = OptionalParameters.bForced or false @@ -173,28 +254,22 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) -- volume della feature local dFeatureVolume = Proc.dVolume - -- si trovano le facce da lavorare - local BottomFace = {} - local LongFaces = {} + -- si trovano le facce da lavorare (solo 4 lati esatti) + local BottomFace1 + local BottomFace2 if Proc.nFct == 1 then - BottomFace = Proc.Faces[1] + BottomFace1 = Proc.Faces[1] else if not Proc.MainFaces then Proc.MainFaces = FaceData.GetMainFaces( Proc, Part) end - BottomFace = Proc.MainFaces.BottomFaces[1] - LongFaces = Proc.MainFaces.LongFaces + BottomFace1 = Proc.MainFaces.BottomFaces[1] + BottomFace2 = Proc.MainFaces.BottomFaces[2] end - - - -- si trova il lato della faccia di fondo da lavorare - local BottomEdgeToMachine = {} - local BottomEdgesSorted = {} - for i = 1, #BottomFace.Edges do - table.insert( BottomEdgesSorted, BottomFace.Edges[i]) + if #BottomFace1.Edges ~= 4 then + Result = FeatureLib.GetStrategyResultNotApplicable() + return Machinings, Result end - table.sort( BottomEdgesSorted, CompareEdges) - BottomEdgeToMachine = BottomEdgesSorted[1] -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) @@ -203,98 +278,66 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) bIsSplitFeature = true end - -- calcolo lavorazioni - -- taglio eventuali facce di chiusura o seconda faccia - for i = 1, #LongFaces do - local Cutting = {} - local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} - Cutting = FaceByBlade.Make( Proc, Part, LongFaces[i], LongFaces[i].MainEdges.BottomEdge, OptionalParametersFaceByBlade) - Cutting.nInternalSortingPriority = 1 - Cutting.dResultWeight = 0.15 - table.insert( CalculatedMachinings, Cutting) - end - - -- taglio con codolo faccia di fondo; si provano solo i lati a cui si può accedere (lato opposto aperto) - -- TODO il check del lato opposto aperto andrà messo nella FaceByBlade - -- TODO verificare se il calcolo del completamento (aggiunta lavorazioni applicabili/non) é corretto - local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - dStripWidth / 2 - local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} - local BottomEdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -BottomEdgeToMachine.vtN) - -- primo lato - if BottomEdgeToMachineOpposite.bIsOpen then - Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1) - end - Cutting1.nInternalSortingPriority = 3 - Cutting1.dResultWeight = 0.3 - - -- secondo lato - local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1) - OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled' - if BottomEdgeToMachine.bIsOpen then - Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2) - end - Cutting2.nInternalSortingPriority = 3 - Cutting2.dResultWeight = 0.3 - - -- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto - if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then - - -- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria - -- ci si deve quindi fermare piú indietro - for i = 1, #LongFaces do - if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then - dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth - break - end - end - dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth) - OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine - - Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2) - Cutting2.nInternalSortingPriority = 3 - Cutting2.dResultWeight = 0.3 - table.insert( CalculatedMachinings, Cutting2) - - elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then - - -- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria - -- ci si deve quindi fermare piú indietro - for i = 1, #LongFaces do - if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then - dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth - break - end - end - dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth) - OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine - - Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1) - Cutting1.nInternalSortingPriority = 3 - Cutting1.dResultWeight = 0.3 - table.insert( CalculatedMachinings, Cutting1) - - else - table.insert( CalculatedMachinings, Cutting1) - table.insert( CalculatedMachinings, Cutting2) + -- calcolo lavorazioni faccia principale + -- ricerca lato da lavorare + local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, { bTop = true}) + -- calcolo lavorazione + local Parameters1 = { + bIsSplitFeature = bIsSplitFeature, + dExtendAfterTail = dExtendAfterTail, + nToolIndex = nToolIndex, + dStripWidth = dStripWidth, + OtherBottomFace = BottomFace2 + } + local Cuttings1 = MakeBottomFace( Proc, Part, BottomFace1, BottomEdgeToMachine1, Parameters1) + -- aggiunta lavorazioni alla lista principale + for i = 1, #Cuttings1 do + table.insert( CalculatedMachinings, Cuttings1[i]) end - -- fresatura eventuali facce di chiusura - if bFinishWithMill then - for i = 1, #LongFaces do - if BottomEdgeToMachine.idAdjacentFace ~= LongFaces[i].id then - local dDepthToMachineMill = BottomFace.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide - local dToolMarkLength = max( Cutting1.dToolMarkLength or 0, Cutting2.dToolMarkLength or 0) - local OptionalParametersFaceByMill = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, - dRadialStepSpan = dToolMarkLength, dDepthToMachine = dDepthToMachineMill - } - local Milling = FaceByMill.Make( Proc, Part, BottomFace, BottomFace.MainEdges.LongEdges[i], OptionalParametersFaceByMill) - Milling.nInternalSortingPriority = 2 - Milling.dResultWeight = 0.05 - table.insert( CalculatedMachinings, Milling) - end + -- calcolo lavorazioni faccia secondaria, solo se lato convesso; se concavo, sarà lavorato come antisplint + local Cuttings2 + local bConvexAngle = ( Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]) > 0 + if BottomFace2 and bConvexAngle then + -- ricerca lato da lavorare + local BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, { bTop = true}) + -- calcolo lavorazione + local Parameters2 = BeamLib.TableCopyDeep( Parameters1) + Parameters2.OtherBottomFace = BottomFace1 + Cuttings2 = MakeBottomFace( Proc, Part, BottomFace2, BottomEdgeToMachine2, Parameters2) + for i = 1, #Cuttings2 do + table.insert( CalculatedMachinings, Cuttings2[i]) end end + + -- -- taglio eventuali facce di chiusura o seconda faccia + -- for i = 1, #LongFaces do + -- local Cutting = {} + -- local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} + -- Cutting = FaceByBlade.Make( Proc, Part, LongFaces[i], LongFaces[i].MainEdges.BottomEdge, OptionalParametersFaceByBlade) + -- Cutting.nInternalSortingPriority = 1 + -- Cutting.dResultWeight = 0.15 + -- table.insert( CalculatedMachinings, Cutting) + -- end + + -- -- fresatura eventuali facce di chiusura + -- if bFinishWithMill then + -- for i = 1, #LongFaces do + -- if BottomEdgeToMachine.idAdjacentFace ~= LongFaces[i].id then + -- local dDepthToMachineMill = BottomFace1.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide + -- local dToolMarkLength = max( Cutting1.dToolMarkLength or 0, Cutting2.dToolMarkLength or 0) + -- local OptionalParametersFaceByMill = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, + -- dRadialStepSpan = dToolMarkLength, dDepthToMachine = dDepthToMachineMill + -- } + -- local Milling = FaceByMill.Make( Proc, Part, BottomFace1, BottomFace1.MainEdges.LongEdges[i], OptionalParametersFaceByMill) + -- Milling.nInternalSortingPriority = 2 + -- Milling.dResultWeight = 0.05 + -- table.insert( CalculatedMachinings, Milling) + -- end + -- end + -- end + -- lavorazioni da applicare spostate in lista finale for i = 1, #CalculatedMachinings do if CalculatedMachinings[i].bIsApplicable then @@ -317,7 +360,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) table.sort( Machinings, SortMachiningsBySegment) -- calcolo risultati - if Cutting1.bIsApplicable or Cutting2.bIsApplicable then + if Cuttings1[1].bIsApplicable or Cuttings1[2].bIsApplicable then Result.dQuality = FeatureLib.GetStrategyQuality( Machinings) Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)