diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index da8fe19..6bff6b5 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -645,6 +645,8 @@ local function CollectFeatures( Part, dRotIndex) Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) -- volume feature approssimato Proc.dVolume = FeatureLib.GetFeatureVolume( Proc, Part) + -- se trimesh, numero di parti di cui è composta + Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1 -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL local bIsFeatureReadyForProcessing = false if FeatureLib.NeedTopologyFeature( Proc, Part) then diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 34ca9c4..4bd64d9 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -91,7 +91,9 @@ function FaceData.GetFacesByAdjacencyNumber( Proc) FacesByAdjacencyNumber[i] = {} end for i = 1, Proc.nFct do - table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i]) + if #Proc.Faces[i].Adjacencies > 0 then + table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i]) + end end return FacesByAdjacencyNumber @@ -186,7 +188,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) Faces[i].id = i - 1 Faces[i].idTrimesh = Proc.id Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT) - if Proc.nFct < 6 or FaceIsToGet( i) then + if Proc.nFct < 7 or FaceIsToGet( i) then -- frame OCS faccia Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN) -- elevazione calcolata rispetto al box della parte @@ -383,10 +385,28 @@ 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 + if Proc.nParts == 1 then + BottomFaces = FacesByAdjacencyNumber[ Proc.nFct / 2] + -- DoubleBevel composto da più parti + else + for i = #FacesByAdjacencyNumber, 1, -1 do + if #FacesByAdjacencyNumber[i] > 0 then + BottomFaces = FacesByAdjacencyNumber[i] + break + end + end + -- se non sono state trovate facce di fondo significa che nessuna faccia ha adiacenze -> DoubleBevel-2 + if #BottomFaces == 0 then + BottomFaces = Proc.Faces + end + end + end -- si rimuovono le facce non adatte ad essere lavorate local nBottomFaces = #BottomFaces local nCurrentFace = 1 @@ -476,7 +496,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 +604,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 {} @@ -690,15 +710,21 @@ function FaceData.GetMainFaces( Proc, Part) Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Bevel' or Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sFamily == 'Cut' or Proc.Topology.sFamily == 'HeadCut' or Proc.Topology.sFamily == 'TailCut' then - if ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5) - or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind' then + if Proc.nParts == 1 and ( ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5) + or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind') then MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part) end MainFaces.BottomFaces = GetBottomFaces( Proc) - MainFaces.LongFaces = GetLongFaces( Proc, MainFaces) - MainFaces.SideFaces = GetSideFaces( Proc, MainFaces) + if Proc.nParts == 1 then + MainFaces.LongFaces = GetLongFaces( Proc, MainFaces) + MainFaces.SideFaces = GetSideFaces( Proc, MainFaces) + -- caso tipo DoubleBevel con facce separate + else + MainFaces.LongFaces = {} + MainFaces.SideFaces = {} + end else MainFaces = nil diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 895f680..d083f81 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -226,13 +226,13 @@ function FeatureLib.ClassifyTopology( Proc, Part) elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then sFamily = 'Bevel' bIsThrough = false - elseif Proc.nFct == 2 and bAllAnglesConcave and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then + elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then sFamily = 'Rabbet' bIsThrough = true - elseif Proc.nFct == 2 and bAllAnglesConcave then + elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 then sFamily = 'VGroove' bIsThrough = true - elseif Proc.nFct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then + elseif Proc.nFct == 2 and ( not bAllAnglesConcave or Proc.nParts == 2) and bIsAnyDimensionLongAsPart then sFamily = 'DoubleBevel' bIsThrough = true elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then @@ -244,7 +244,9 @@ 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 ( ( not bAllAnglesConcave and ( ( #vFacesByAdjNumber[2] == 2 and #vTriangularFaces == 2) or ( #vFacesByAdjNumber[3] == 2))) + or ( #vTriangularFaces == 2 and Proc.nParts == 2)) then sFamily = 'DoubleBevel' bIsThrough = false elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then @@ -259,7 +261,9 @@ 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 and not bAllAnglesConcave) + or ( #vFacesByAdjNumber[1] == 4 and #vTriangularFaces == 4 and Proc.nParts == 2)) then sFamily = 'DoubleBevel' bIsThrough = false end diff --git a/Strategies/Standard/STR0010/STR0010.json b/Strategies/Standard/STR0010/STR0010.json index 11a8b69..71b9f93 100644 --- a/Strategies/Standard/STR0010/STR0010.json +++ b/Strategies/Standard/STR0010/STR0010.json @@ -3,7 +3,7 @@ "sStrategyName": "Milling", "ParameterList" : [ { - "sName": "dAntiSplintWithBlade", + "sName": "bAntiSplintWithBlade", "sNameNge": "ANTISPLINT_BLADE", "sValue": "false", "sDescriptionShort": "Antisplint with blade", @@ -22,6 +22,26 @@ "sMessageId": " ", "sMinUserLevel": "1" }, + { + "sName": "bFinishWithMill", + "sNameNge": "ALLOW_FINISH_MILL", + "sValue": "true", + "sDescriptionShort": "Clean radius with mill", + "sDescriptionLong": "Clean radius with mill", + "sType": "b", + "sMessageId": " ", + "sMinUserLevel": "1" + }, + { + "sName": "dMillingOffsetFromSide", + "sNameNge": "MILLING_OFFSET_SIDE", + "sValue": "1", + "sDescriptionShort": "Milling offset from side", + "sDescriptionLong": "", + "sType": "d", + "sMessageId": " ", + "sMinUserLevel": "1" + }, { "sName": "sCanDamageNextPiece", "sNameNge": "DAMAGE_NEXT_PIECE", diff --git a/Strategies/Standard/STR0010/STR0010.lua b/Strategies/Standard/STR0010/STR0010.lua index 15ee988..fbaf928 100644 --- a/Strategies/Standard/STR0010/STR0010.lua +++ b/Strategies/Standard/STR0010/STR0010.lua @@ -9,7 +9,8 @@ local BeamData = require( 'BeamDataNew') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base -local FaceByMill = require('FACEBYMILL') +local FaceByMill = require( 'FACEBYMILL') +local FaceByBlade = require( 'FACEBYBLADE') -- Tabella per definizione modulo local STR0010 = {} @@ -34,7 +35,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 +48,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 +112,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 +131,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 @@ -148,15 +160,28 @@ local function SortMachiningsBySegment( MachiningA, MachiningB) return false elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then return true + -- se segmento uguale, si guarda la priorità else - if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then - return true - elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then + if MachiningA.nInternalSortingPriority > MachiningB.nInternalSortingPriority then return false + elseif MachiningB.nInternalSortingPriority > MachiningA.nInternalSortingPriority then + return true + -- se priorità uguale, si minimizzano i cambi di lato else - if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then - return true - elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then + local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0) + if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then + if bIsOddSegment then + return true + else + return false + end + elseif MachiningA.vtToolDirection:getY() > MachiningB.vtToolDirection:getY() + 10 * GEO.EPS_SMALL then + if bIsOddSegment then + return false + else + return true + end + else return false end end @@ -172,6 +197,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 +207,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 @@ -198,8 +224,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters) -- volume della feature local dFeatureVolume = Proc.dVolume - -- TODO taglio su eventuali facce di chiusura - -- eventuali punti di spezzatura local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local bIsSplitFeature = false @@ -212,41 +236,187 @@ 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 + -- 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 Milling1 = {} + local OptionalParametersMilling1 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} + local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, TOOLS[nToolIndex].SetupInfo.HeadType) + if BottomEdgeToMachine1.bIsOpen then + OptionalParametersMilling1.dDepthToMachine = BottomEdgeToMachine1.dElevation + BeamData.CUT_EXTRA + end + Milling1 = FaceByMill.Make( Proc, Part, BottomFace1, BottomEdgeToMachine1, OptionalParametersMilling1) + Milling1.nInternalSortingPriority = 2 + Milling1.dResultWeight = 0.3 + 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 + local dAngleBetweenFaces = Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1] + if dAngleBetweenFaces >= -89.5 then + Milling2 = {} + if #BottomFace2.Edges == 4 then + local OptionalParametersMilling2 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} + BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, TOOLS[nToolIndex].SetupInfo.HeadType) + if BottomEdgeToMachine2.bIsOpen then + OptionalParametersMilling2.dDepthToMachine = BottomEdgeToMachine2.dElevation + BeamData.CUT_EXTRA + end + Milling2 = FaceByMill.Make( Proc, Part, BottomFace2, BottomEdgeToMachine2, OptionalParametersMilling2) + Milling2.nInternalSortingPriority = 2 + Milling2.dResultWeight = 0.3 + else + Milling2.bIsApplicable = false end - Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill) - if Milling.bIsApplicable then - table.insert( Strategy.Machinings, Milling) + table.insert( CalculatedMachinings, Milling2) + end + end + + -- fresatura eventuali facce di chiusura (se non già lavorate) + if Strategy.Parameters.bFinishWithMill then + + if Milling1 then + -- si recuperano i lati chiusi non lavorati + local EdgesClosedNotMachined = {} + for i = 1, #BottomFace1.Edges do + if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then + table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i]) + end + end + -- su ognuno si fa la fresatura di pulizia + for i = 1, #EdgesClosedNotMachined do + local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - Strategy.Parameters.dMillingOffsetFromSide + local dToolMarkLength = Milling1.dToolMarkLength or 0 + local OptionalParameters = { + bIsSplitFeature = bIsSplitFeature, + dExtendAfterTail = dExtendAfterTail, + dRadialStepSpan = dToolMarkLength, + dDepthToMachine = dDepthToMachine + } + local Milling = FaceByMill.Make( Proc, Part, BottomFace1, EdgesClosedNotMachined[i], OptionalParameters) + Milling.nInternalSortingPriority = 3 + Milling.dResultWeight = 0.05 + table.insert( CalculatedMachinings, Milling) + end + end + + if Milling2 then + -- si recuperano i lati chiusi non lavorati + local EdgesClosedNotMachined = {} + for i = 1, #BottomFace2.Edges do + if not( ( BottomFace2.Edges[i].id == BottomEdgeToMachine2.id) or BottomFace2.Edges[i].bIsOpen) then + table.insert( EdgesClosedNotMachined, BottomFace2.Edges[i]) + end + end + -- su ognuno si fa la fresatura di pulizia + for i = 1, #EdgesClosedNotMachined do + local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - Strategy.Parameters.dMillingOffsetFromSide + local dToolMarkLength = Milling2.dToolMarkLength or 0 + local OptionalParameters = { + bIsSplitFeature = bIsSplitFeature, + dExtendAfterTail = dExtendAfterTail, + dRadialStepSpan = dToolMarkLength, + dDepthToMachine = dDepthToMachine + } + local Milling = FaceByMill.Make( Proc, Part, BottomFace2, EdgesClosedNotMachined[i], OptionalParameters) + Milling.nInternalSortingPriority = 3 + Milling.dResultWeight = 0.05 + table.insert( CalculatedMachinings, Milling) end end end + -- taglio eventuali facce di chiusura controvena, per ogni faccia bottom lavorata + if Strategy.Parameters.bAntiSplintWithBlade then + + if Milling1 then + local ClosingFacesAgainstGrain1 = {} + for i = 1, #BottomFace1.Edges do + local CurrentFace = Proc.Faces[BottomFace1.Edges[i].idAdjacentFace + 1] + if ( not BottomFace1.Edges[i].bIsOpen) and abs( CurrentFace.vtN:getX()) > 0.707 then + table.insert( ClosingFacesAgainstGrain1, CurrentFace) + end + end + for i = 1, #ClosingFacesAgainstGrain1 do + local EdgeToMachine = {} + for j = 1, #ClosingFacesAgainstGrain1[i].Edges do + if ClosingFacesAgainstGrain1[i].Edges[j].idAdjacentFace == BottomFace1.id then + EdgeToMachine = ClosingFacesAgainstGrain1[i].Edges[j] + break + end + end + local Cutting = {} + local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} + Cutting = FaceByBlade.Make( Proc, Part, ClosingFacesAgainstGrain1[i], EdgeToMachine, OptionalParametersFaceByBlade) + Cutting.nInternalSortingPriority = 1 + Cutting.dResultWeight = 0.15 + table.insert( CalculatedMachinings, Cutting) + end + end + + if Milling2 then + local ClosingFacesAgainstGrain2 = {} + for i = 1, #BottomFace2.Edges do + local CurrentFace = Proc.Faces[BottomFace2.Edges[i].idAdjacentFace + 1] + if ( not BottomFace2.Edges[i].bIsOpen) and abs( CurrentFace.vtN:getX()) > 0.707 then + table.insert( ClosingFacesAgainstGrain2, CurrentFace) + end + end + for i = 1, #ClosingFacesAgainstGrain2 do + local EdgeToMachine = {} + for j = 1, #ClosingFacesAgainstGrain2[i].Edges do + if ClosingFacesAgainstGrain2[i].Edges[j].idAdjacentFace == BottomFace2.id then + EdgeToMachine = ClosingFacesAgainstGrain2[i].Edges[j] + break + end + end + local Cutting = {} + local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} + Cutting = FaceByBlade.Make( Proc, Part, ClosingFacesAgainstGrain2[i], EdgeToMachine, OptionalParametersFaceByBlade) + Cutting.nInternalSortingPriority = 1 + Cutting.dResultWeight = 0.15 + table.insert( CalculatedMachinings, Cutting) + end + end + end + + -- 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) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index d2fce68..502fc1a 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -1215,14 +1215,21 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) else -- per ogni faccia si calcola la lavorazione for i = 1, #Proc.Faces do - -- ricerca lato in comune da lavorare + -- ricerca lato in comune da lavorare; se non trovato è una feature splittata (DoubleBevel) e il lato sarà scelto della GetSingleCutStratetegy local nCommonEdgeIndex for j = 1, #Proc.Faces[i].Edges do if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then nCommonEdgeIndex = j end end - local EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex] + local EdgeToMachine + if nCommonEdgeIndex then + EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex] + end + local EdgeToMachineList + if EdgeToMachine then + EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine} + end -- scelta lama local nToolIndex = OptionalParameters.nToolIndex @@ -1230,11 +1237,11 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local OptionalParametersGetSingleCutStrategy = { bReduceBladePath = false, nFaceToMachineIndex = i, - EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}, + EdgeToMachineList = EdgeToMachineList, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, bCannotSplitRestLength = bCannotSplitRestLength } - nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) + nToolIndex, EdgeToMachine = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) end -- se lama non trovata si provano i cubetti