diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index a09a9eb..d541c35 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -372,6 +372,7 @@ end ------------------------------------------------------------------------------------------------------------- function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + -- TODO convertire in GetMinUnloadableRaw che viene richiamata all'inizio delle funzioni che necessitano di dMinRaw if BeamData.GetMinUnloadableRaw then BeamData.dMinRaw = BeamData.GetMinUnloadableRaw( dRawW, dRawH) else diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 5d077a7..d5ed6a5 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -293,6 +293,92 @@ function FeatureLib.CalculateCompositeRating( StrategyResult) return StrategyResult end + +------------------------------------------------------------------------------------------------------------- +function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters) + local vFeatureSplittingPoints = {} + local bFeatureStartsOnEdgeLeft = false + local bFeatureStartsOnEdgeRight = false + local dSplitXLeft = Proc.b3Box:getMin():getX() + local dSplitXRight = Proc.b3Box:getMax():getX() + local dFeatureCentralLength = Proc.b3Box:getDimX() + + -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end + local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN + local dMaxSegmentLengthOnEdges = OptionalParameters.dMaxSegmentLengthOnEdges or BeamData.LONGCUT_ENDLEN + local dToolOverlapBetweenSegments = OptionalParameters.dToolOverlapBetweenSegments or BeamData.MILL_OVERLAP + + -- verifica spezzatura necessaria + if ( Proc.b3Box:getDimX() < dMaxSegmentLength + 10 * GEO.EPS_SMALL) and ( Proc.b3Box:getDimX() < 0.7 * Part.b3Solid:getDimX() + 10 * GEO.EPS_SMALL) then + return {} + end + + -- verifica se necessari spezzoni differenti sugli estremi + if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges - 10 * GEO.EPS_SMALL then + bFeatureStartsOnEdgeLeft = true + end + if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges + 10 * GEO.EPS_SMALL then + bFeatureStartsOnEdgeRight = true + end + + -- calcolo punto estremo sinistro + local ptSplitXLeft + if bFeatureStartsOnEdgeLeft then + -- decido punto spezzatura verso la coda + if Proc.b3Box:getDimX() > dMaxSegmentLengthOnEdges * 2 then + dSplitXLeft = max( Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges, Proc.b3Box:getMin():getX() + dMaxSegmentLengthOnEdges / 2) + else + -- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante' + if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then + dSplitXLeft = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2) + else + dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges) + end + end + dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft) + ptSplitXLeft = Point3d( dSplitXLeft, 0, 0) + end + + -- calcolo punto estremo destro + local ptSplitXRight + if bFeatureStartsOnEdgeRight then + dSplitXRight = min( ( Proc.b3Box:getMax():getX() - dSplitXRight * 3), Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges) + if dSplitXRight - dSplitXLeft < 500 * GEO.EPS_SMALL then + dSplitXRight = dSplitXLeft - dToolOverlapBetweenSegments + dFeatureCentralLength = 0 + else + dFeatureCentralLength = dSplitXRight - dSplitXLeft + end + ptSplitXRight = Point3d( dSplitXRight, 0, 0) + end + + -- aggiungo eventuale punto estemo sinistro + if bFeatureStartsOnEdgeLeft then + table.insert( vFeatureSplittingPoints, ptSplitXLeft) + end + + -- aggiungo punti centrali della feature + if dFeatureCentralLength > 0 then + local nSplitParts = max( ceil( dFeatureCentralLength / dMaxSegmentLength + 10 * GEO.EPS_SMALL), 1) + local dSplitPartsLen = dFeatureCentralLength / nSplitParts + for i = 1, ( nSplitParts - 1) do + local ptOn + local dCurrentPointX = dSplitXLeft + i * dSplitPartsLen + ptOn = Point3d( dCurrentPointX, 0, 0) + table.insert( vFeatureSplittingPoints, ptOn) + end + end + + -- aggiungo eventuale punto estremo destro + if bFeatureStartsOnEdgeRight then + table.insert( vFeatureSplittingPoints, ptSplitXRight) + end + + return vFeatureSplittingPoints +end ------------------------------------------------------------------------------------------------------------- return FeatureLib \ No newline at end of file diff --git a/Strategies/Core/SLOTBYBLADE.lua b/Strategies/Core/SLOTBYBLADE.lua index afb9db8..4797f1b 100644 --- a/Strategies/Core/SLOTBYBLADE.lua +++ b/Strategies/Core/SLOTBYBLADE.lua @@ -96,6 +96,9 @@ function SLOTBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sEdgeType = EdgeToMachine.sType -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false local dPocketHeight = 0 diff --git a/Strategies/Core/SLOTBYCHAINSAW.lua b/Strategies/Core/SLOTBYCHAINSAW.lua index edeac0d..f192145 100644 --- a/Strategies/Core/SLOTBYCHAINSAW.lua +++ b/Strategies/Core/SLOTBYCHAINSAW.lua @@ -58,6 +58,9 @@ function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional Mortising.sEdgeType = EdgeToMachine.sType -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end local bUseZigZagMortising = OptionalParameters.bUseZigZagMortising or false local sSideToMachine = OptionalParameters.sSideToMachine or '' local dLengthToMachine = OptionalParameters.dLengthToMachine or EdgeToMachine.dLength diff --git a/Strategies/Standard/STR0002/STR0002.lua b/Strategies/Standard/STR0002/STR0002.lua index 4f55ada..156c609 100644 --- a/Strategies/Standard/STR0002/STR0002.lua +++ b/Strategies/Standard/STR0002/STR0002.lua @@ -350,142 +350,49 @@ local function GetBestPocketingStrategy( Proc) end ------------------------------------------------------------------------------------------------------------- -local function VerifySplitMachiningNeeded( Proc, Part) +local function GetSplittedSurfaces( Proc, Part) local vAddId = {} local vAddIdTunnel = {} - local bSplit - - -- la lunghezza richiede spezzatura - if Proc.b3Box:getDimX() > BeamData.LONGCUT_MAXLEN or Proc.b3Box:getDimX() > 0.7 * Part.b3Solid:getDimX() then - bSplit = true - else - bSplit = false + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local nIdTunnel + if Proc.MainFaces.TunnelAddedFaces then + nIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id end - -- la lunghezza richiede spezzatura - if ( bSplit) then - -- recupero gruppo per geometria aggiuntiva - local nAddGrpId = BeamLib.GetAddGroup( Part.id) - local bStartLeft, bStartRight - local nIdTunnel = nil - if Proc.MainFaces.TunnelAddedFaces then - nIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id - end + -- recupero punti di spezzatura - da sinistra a destra + local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) - -- se feature inizia al di sotto del limite sinistro (coda) - if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN then - bStartLeft = true - end - -- se feature inizia al di sotto del limite destro (testa) - if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN then - bStartRight = true - end - - -- recupero utensile con massimo diametro - local dMaxDiam = 30 - for t = 1, #Strategy.Machining do - if Strategy.Machining[t].bIsApplicable then - dMaxDiam = min( dMaxDiam, TOOLS[Strategy.Machining[t].ToolInfo.nToolIndex].dDiameter) - end - end - -- salvo valori - local dNewMinX = Proc.b3Box:getMin():getX() - local dNewMaxX = Proc.b3Box:getMax():getX() - local dNewRest = Proc.b3Box:getDimX() - - -- creo primo spezzone sulla sinistra - if bStartLeft then - local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - -- copio faccia tunnel - local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL - - -- decido punto spezzatura verso la coda - if Proc.b3Box:getDimX() > BeamData.LONGCUT_ENDLEN * 2 then - dNewMinX = max( Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN, Proc.b3Box:getMin():getX() + dMaxDiam * 3) - else - -- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante' - if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then - dNewMinX = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2) - else - dNewMinX = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN) - end - end - - local ptOn = Point3d( dNewMinX, 0, 0) - dNewRest = abs( dNewMaxX - dNewMinX) - -- taglio della superficie lato sinistro - EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB) - -- eseguo inserimento - table.insert( vAddId, AddId) - table.insert( vAddIdTunnel, AddIdTunnel) - end - -- creo spezzone sulla destra - if bStartRight then - local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - -- copio faccia tunnel - local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL - dNewMaxX = min( ( Proc.b3Box:getMax():getX() - dMaxDiam * 3), Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN) - if dNewMaxX - dNewMinX < 500 * GEO.EPS_SMALL then - dNewMaxX = dNewMinX - BeamData.MILL_OVERLAP - dNewRest = 0 - else - dNewRest = dNewMaxX - dNewMinX - end - local ptOn = Point3d( dNewMaxX, 0, 0) - -- taglio della superficie lato destro - EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB) - -- eseguo inserimento - table.insert( vAddId, 1, AddId) - table.insert( vAddIdTunnel, AddIdTunnel) - end - -- lavoro il restante - if dNewRest > 0 then - local nSplitParts = max( ceil( dNewRest / BeamData.LONGCUT_MAXLEN + 10 * GEO.EPS_SMALL), 1) - local dSplitPartsLen = dNewRest / nSplitParts - for i = 1, nSplitParts do - local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL - -- copio faccia tunnel - local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL - local ptOn - -- se un solo spezzone, prendo punto massimo e minimo - if nSplitParts == 1 then - ptOn = Point3d( dNewMinX, 0, 0) - -- taglio della superficie lato sinistro - EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB) - ptOn = Point3d( dNewMaxX, 0, 0) - -- taglio della superficie lato destro - EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB) - else - -- eseguo trim sinistro - if i ~= 1 or bStartLeft then - ptOn = Point3d( dNewMinX, 0, 0) - -- taglio della superficie lato sinistro - EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB) - end - -- eseguo trim destro - dNewMaxX = dNewMinX + dSplitPartsLen - if i ~= nSplitParts or bStartRight then - ptOn = Point3d( dNewMaxX, 0, 0) - -- taglio della superficie lato destro - EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) - EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB) - end - -- il nuovo minimo è il punto massimo del precedente - dNewMinX = dNewMaxX - end - -- eseguo inserimento in modo da ordinare da X- a X+ - table.insert( vAddId, EgtIf( #vAddId == 0 or not bStartRight, 1, 2), AddId) - table.insert( vAddIdTunnel, EgtIf( #vAddIdTunnel == 0 or not bStartRight, 1, 2), AddIdTunnel) - end - end + if #vFeatureSplittingPoints == 0 then + local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL + table.insert( vAddId, nAddId) + table.insert( vAddIdTunnel, nAddIdTunnel) else - -- TODO se è sulla coda, messaggio che posso rovinare - table.insert( vAddId, Proc.id) + for i = 1, #vFeatureSplittingPoints do + local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL + if i == 1 then + -- prima superficie, va tagliata solo a destra + EgtCutSurfTmPlane( nAddId, vFeatureSplittingPoints[i], X_AX(), true, GDB_RT.GLOB) + EgtCutSurfTmPlane( nAddIdTunnel, vFeatureSplittingPoints[i], X_AX(), true, GDB_RT.GLOB) + else + -- taglio della superficie corrente - lato sinistro + EgtCutSurfTmPlane( nAddId, vFeatureSplittingPoints[i - 1], -X_AX(), true, GDB_RT.GLOB) + EgtCutSurfTmPlane( nAddIdTunnel, vFeatureSplittingPoints[i -1 ], -X_AX(), true, GDB_RT.GLOB) + -- taglio della superficie corrente - lato destro + EgtCutSurfTmPlane( nAddId, vFeatureSplittingPoints[i], X_AX(), true, GDB_RT.GLOB) + EgtCutSurfTmPlane( nAddIdTunnel, vFeatureSplittingPoints[i], X_AX(), true, GDB_RT.GLOB) + end + table.insert( vAddId, nAddId) + table.insert( vAddIdTunnel, nAddIdTunnel) + end + -- taglio ultima superficie, va tagliata solo a sinistra + local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL + local nAddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL + EgtCutSurfTmPlane( nAddId, vFeatureSplittingPoints[#vFeatureSplittingPoints], -X_AX(), true, GDB_RT.GLOB) + EgtCutSurfTmPlane( nAddIdTunnel, vFeatureSplittingPoints[#vFeatureSplittingPoints], -X_AX(), true, GDB_RT.GLOB) + table.insert( vAddId, nAddId) + table.insert( vAddIdTunnel, nAddIdTunnel) end return vAddId, vAddIdTunnel @@ -520,7 +427,11 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) Strategy.Machining = GetBestPocketingStrategy( Proc) if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then - local vAddId, vAddIdTunnel = VerifySplitMachiningNeeded( Proc, Part) + local vAddId = {} + local vAddIdTunnel = {} + + -- recupero superficie, se necessario trimmata sugli spezzoni + vAddId, vAddIdTunnel = GetSplittedSurfaces( Proc, Part) -- si applicano le lavorazioni for i = 1, #vAddId do diff --git a/Strategies/Standard/STR0004/STR0004.lua b/Strategies/Standard/STR0004/STR0004.lua index 5e9a065..616a36d 100644 --- a/Strategies/Standard/STR0004/STR0004.lua +++ b/Strategies/Standard/STR0004/STR0004.lua @@ -194,6 +194,10 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters) Chainsaw.AddResult( Mortising) end end + + -- calcolo eventuali spezzoni + local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) + -- aggiunta lavorazioni local nIsApplicableCount = 0 local dFinalCompletionPercentage = 100