diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index f65dc8d..5293154 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -1169,4 +1169,19 @@ function BeamLib.IsFeatureCuttingEntireSection( b3Proc, dRawW, dRawH) end ------------------------------------------------------------------------------------------------------------- -return BeamLib +function BeamLib.GetAdjacentFaces( Proc, nFacet) + local AdjacentFaces = {} + local vFaceAdjacencies = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1] + for i = 1, #vFaceAdjacencies do + if vFaceAdjacencies[i] > -1 then + local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacet, vFaceAdjacencies[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + table.insert( AdjacentFaces, { Id = vFaceAdjacencies[i], LengthOnMainFace = dLen}) + end + end + + return AdjacentFaces +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib \ No newline at end of file diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 87c7b26..780d6b9 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -4587,7 +4587,15 @@ end --------------------------------------------------------------------- --#region SawPlusChain + +-- 5 facce: la faccia di fondo è il fondo della tasca, la faccia da lavorare è grande, le facce laterali sono le due piccole +-- 4 facce con faccia di fondo piccola: la faccia da lavorare è grande (2 adj) e l'unica faccia laterale è piccola +-- 4 facce con faccia di fondo grande: la faccia da lavorare è piccola (3 adj) e le facce laterali sono le due piccole +-- 3 facce: la faccia di fondo è il fondo della tasca, la faccia da lavorare è grande, non ci sono facce laterali + local SawPlusChain = {} +SawPlusChain.Saw = {} +SawPlusChain.Chainsaw = {} function SawPlusChain.IsTopologyOk( Proc) @@ -4640,20 +4648,12 @@ function SawPlusChain.GetFaceToMachine( Proc) Proc.Pocket.BottomFace = SawPlusChain.GetBottomFace( Proc) end - -- si cercano le facce adiacenti a quella di fondo - local FacesAdjacentToBottom = {} - local vBottomFaceAdjacencies = EgtSurfTmFacetAdjacencies( Proc.Id, Proc.Pocket.BottomFace.Id)[1] - for i = 1, #vBottomFaceAdjacencies do - if vBottomFaceAdjacencies[i] > -1 then - local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, Proc.Pocket.BottomFace.Id, vBottomFaceAdjacencies[i], GDB_ID.ROOT) - local dLen = dist( ptP1, ptP2) - table.insert( FacesAdjacentToBottom, { Id = vBottomFaceAdjacencies[i], LengthOnBottom = dLen}) - end - end + -- facce adiacenti a quella di fondo, ordinate + local FacesAdjacentToBottom = BL.GetAdjacentFaces( Proc, Proc.Pocket.BottomFace.Id) + table.sort( FacesAdjacentToBottom, function( a, b) return a.LengthOnMainFace > b.LengthOnMainFace end) -- si sceglie la faccia adiacente sul lato più lungo local FaceToMachine = {} - table.sort( FacesAdjacentToBottom, function( a, b) return a.LengthOnBottom > b.LengthOnBottom end) FaceToMachine.Id = FacesAdjacentToBottom[1].Id for i = 1, Proc.Fct do if FaceToMachine.Id == Proc.Face[i].Id then @@ -4679,24 +4679,18 @@ function SawPlusChain.GetSideFaces( Proc) Proc.Pocket.FaceToMachine = SawPlusChain.GetFaceToMachine( Proc) end - -- si cercano le facce adiacenti a quella di fondo - local FacesAdjacentToBottom = {} - local vBottomFaceAdjacencies = EgtSurfTmFacetAdjacencies( Proc.Id, Proc.Pocket.BottomFace.Id)[1] - for i = 1, #vBottomFaceAdjacencies do - if vBottomFaceAdjacencies[i] > -1 then - local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, Proc.Pocket.BottomFace.Id, vBottomFaceAdjacencies[i], GDB_ID.ROOT) - local dLen = dist( ptP1, ptP2) - table.insert( FacesAdjacentToBottom, { Id = vBottomFaceAdjacencies[i], LengthOnBottom = dLen}) - end - end + -- facce adiacenti a quella di fondo, ordinate + local FacesAdjacentToBottom = BL.GetAdjacentFaces( Proc, Proc.Pocket.BottomFace.Id) + table.sort( FacesAdjacentToBottom, function( a, b) return a.LengthOnMainFace > b.LengthOnMainFace end) + + -- si determina il criterio di scelta delle facce laterali + local FacesAdjacentToFaceToMachine = BL.GetAdjacentFaces( Proc, Proc.Pocket.FaceToMachine.Id) + local bIsFaceToMachineTheLargest = not ( Proc.Fct == 4 and #FacesAdjacentToFaceToMachine == 3) - -- se non 4 facce, le facce laterali sono quelle che rimangono una volta escluse le due sopra e sotto, che sono le più lunghe - -- se 4 facce, le facce laterali sono le rimanenti esclusa quella da lavorare - table.sort( FacesAdjacentToBottom, function( a, b) return a.LengthOnBottom > b.LengthOnBottom end) local SideFaces = {} for i = 1, #FacesAdjacentToBottom do - if ( Proc.Fct ~= 4 and i > 2) or - ( Proc.Fct == 4 and ( FacesAdjacentToBottom[i].Id ~= Proc.Pocket.FaceToMachine.Id)) then + if ( not bIsFaceToMachineTheLargest and i < #FacesAdjacentToBottom) or + ( bIsFaceToMachineTheLargest and i > 2) then table.insert( SideFaces, FacesAdjacentToBottom[i]) SideFaces[ #SideFaces].Id = FacesAdjacentToBottom[i].Id SideFaces[ #SideFaces].Width = Proc.Face[FacesAdjacentToBottom[i].Id + 1].Width @@ -4847,11 +4841,19 @@ function SawPlusChain.GetLeadInOut( Proc, Machining) LeadIn.CompLength = 0 LeadOut.CompLength = 0 if bIsStartClosed then + LeadIn.StartAddLength = -dAddLengthToReduce LeadIn.PerpDistance = 1 end if bIsEndClosed then + LeadOut.EndAddLength = -dAddLengthToReduce LeadOut.PerpDistance = 1 end + if abs( LeadIn.StartAddLength) > Proc.Pocket.Width - 10 * GEO.EPS_SMALL then + LeadOut.EndAddLength = -LeadIn.StartAddLength - Proc.Pocket.Width + 1 + end + if abs( LeadOut.EndAddLength) > Proc.Pocket.Width - 10 * GEO.EPS_SMALL then + LeadIn.StartAddLength = -LeadOut.EndAddLength - Proc.Pocket.Width + 1 + end end if bIsStartClosed then LeadIn.StartAddLength = -dAddLengthToReduce @@ -4926,58 +4928,40 @@ function SawPlusChain.ApplyMachining( Machining, sOperationNamePrefix, b3Raw) end -function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) - Proc.Pocket = {} - Proc.Pocket.Strategy = 'SawPlusChain' - - if not SawPlusChain.IsTopologyOk( Proc) then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not implemented for topology ' .. Proc.TopologyLongName - return false, sErr - end - - -- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto) - -- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama da sotto - if Proc.AffectedFaces.Bottom then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket on bottom face' - return false, sErr - end - - -- caratteristiche della tasca - Proc.Pocket.BottomFace = SawPlusChain.GetBottomFace( Proc) - Proc.Pocket.FaceToMachine = SawPlusChain.GetFaceToMachine( Proc) - Proc.Pocket.SideFaces = SawPlusChain.GetSideFaces( Proc) - Proc.Pocket.Width = Proc.Pocket.BottomFace.Width - Proc.Pocket.Height = Proc.Pocket.BottomFace.Height - Proc.Pocket.Depth = Proc.Pocket.BottomFace.Elevation - Proc.Pocket.Direction = Proc.Pocket.BottomFace.VtN - - -- lavorazione di lama e relativi dati +function SawPlusChain.Saw.CalculateMachiningParameters( Proc) local Cutting = {} + Cutting.CanApply = true + Cutting.Message = '' Cutting.ProcId = Proc.Id + + -- ricerca lavorazione Cutting.Name = ML.FindCutting( 'HeadSide', true, false) if not Cutting.Name then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - saw blade not found' - return false, sErr + Cutting.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - saw blade not found' + Cutting.CanApply = false + return Cutting end Cutting.Type = MCH_OY.MILLING Cutting.Tool = SawPlusChain.GetToolFromMachining( Cutting.Name) Cutting.FaceToMachine = Proc.Pocket.FaceToMachine - -- verifica dimensioni tasca compatibili con lama + -- verifica dimensioni tasca compatibili -- se tasca meno spessa della lama la strategia non è applicabile if Cutting.Tool.Thickness > Proc.Pocket.Height - 10 * GEO.EPS_SMALL then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for saw blade thickness' - return false, sErr + Cutting.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for saw blade thickness' + Cutting.CanApply = false + return Cutting end if Proc.Pocket.SideOpeningsCount == 0 then -- se tasca più stretta della lama la strategia non è applicabile if Cutting.Tool.Diameter > Proc.Pocket.Width - 10 * GEO.EPS_SMALL then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for saw blade diameter' - return false, sErr + Cutting.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for saw blade diameter' + Cutting.CanApply = false + return Cutting end end - -- parametri della lavorazione con lama + -- parametri della lavorazione -- lato di lavoro e inversioni if Cutting.Tool.IsCCW then Cutting.Workside = MCH_MILL_WS.RIGHT @@ -5026,8 +5010,6 @@ function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) Cutting.BlockedAxis.VtOut = EgtIf( Cutting.FaceToMachine.VtN:getX() > 0, X_AX(), -X_AX()) -- approccio e retrazione Cutting.LeadIn, Cutting.LeadOut = SawPlusChain.GetLeadInOut( Proc, Cutting) - - -- lavorazione con lama -- eventuale step orizzontale if Cutting.Tool.SideStep then Cutting.HorizontalSteps = SawPlusChain.GetHorizontalSteps( Cutting) @@ -5035,49 +5017,47 @@ function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) Cutting.HorizontalSteps.Count = 1 Cutting.HorizontalSteps.StepLength = 0 end - local bIsCuttingOk, sErrorMessageCutting - local dOriginalRadialOffsetCutting = Cutting.RadialOffset - for i = Cutting.HorizontalSteps.Count, 1, -1 do - Cutting.RadialOffset = dOriginalRadialOffsetCutting + Cutting.HorizontalSteps.StepLength * ( i - 1) - bIsCuttingOk, sErrorMessageCutting = SawPlusChain.ApplyMachining( Cutting, 'Cut_', b3Raw) - end - if bOnlySaw or not bIsCuttingOk then - return bIsCuttingOk, sErrorMessageCutting - end - - -- lavorazione di sega a catena e relativi dati + return Cutting +end + + +function SawPlusChain.Chainsaw.CalculateMachiningParameters( Proc) local Chainsawing = {} + Chainsawing.CanApply = true + Chainsawing.Message = '' Chainsawing.ProcId = Proc.Id + + -- ricerca lavorazione Chainsawing.Name = ML.FindSawing( 'Sawing', Proc.Pocket.Depth) if not Chainsawing.Name then Chainsawing.Name = ML.FindSawing( 'Sawing', nil, nil, 'Longest') end if not Chainsawing.Name then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - chainsaw not found' - return false, sErr + Chainsawing.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - chainsaw not found' + Chainsawing.CanApply = false + return Chainsawing end Chainsawing.Type = MCH_OY.MORTISING Chainsawing.Tool = SawPlusChain.GetToolFromMachining( Chainsawing.Name) Chainsawing.FaceToMachine = Proc.Pocket.FaceToMachine - -- verifica dimensioni tasca compatibili con sega a catena + -- verifica dimensioni tasca compatibili -- se tasca meno spessa della sega a catena la strategia non è applicabile - if not bOnlySaw and Chainsawing.Tool.Thickness > Proc.Pocket.Height - 10 * GEO.EPS_SMALL then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for chainsaw thickness' - return false, sErr + if Chainsawing.Tool.Thickness > Proc.Pocket.Height - 10 * GEO.EPS_SMALL then + Chainsawing.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for chainsaw thickness' + Chainsawing.CanApply = false + return Chainsawing end - if Proc.Pocket.SideOpeningsCount == 0 then -- se tasca più stretta della sega a catena la strategia non è applicabile - if not bOnlySaw and Chainsawing.Tool.Width > Proc.Pocket.Width - 10 * GEO.EPS_SMALL then - local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for chainsaw width' - return false, sErr + if Chainsawing.Tool.Width > Proc.Pocket.Width - 10 * GEO.EPS_SMALL then + Chainsawing.Message = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket too narrow for chainsaw width' + Chainsawing.CanApply = false + return Chainsawing end end - local sErrorMessageChainsawing = '' - -- parametri della lavorazione con sega a catena -- lato di lavoro e inversioni if Chainsawing.Tool.IsCCW then @@ -5095,12 +5075,10 @@ function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) else Chainsawing.Depth = Chainsawing.Tool.MaxMat Chainsawing.LongitudinalOffset = Proc.Pocket.Depth - Chainsawing.Depth - sErrorMessageChainsawing = 'Feature '.. Proc.FeatureId .. ' : chainsawing elevation bigger than max tool depth' + Chainsawing.Message = 'Feature '.. Proc.FeatureId .. ' : chainsawing elevation bigger than max tool depth' end -- offset radiale Chainsawing.RadialOffset = 0 - -- profondità da lavorare, ossia MaxElev. Si lavora solo quanto non lavorato dalla lama - Chainsawing.MaxElev = Cutting.RadialOffset + BD.CUT_EXTRA -- distanza di sicurezza Chainsawing.StartSafetyLength = Proc.Pocket.Depth -- overlap @@ -5116,20 +5094,79 @@ function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) Chainsawing.BlockedAxis.Orientation = 'perpendicular' -- approccio e retrazione Chainsawing.LeadIn, Chainsawing.LeadOut = SawPlusChain.GetLeadInOut( Proc, Chainsawing) + -- eventuale step verticale + Chainsawing.VerticalSteps = SawPlusChain.GetVerticalSteps( Proc, Chainsawing) --- lavorazione con sega a catena -Chainsawing.VerticalSteps = SawPlusChain.GetVerticalSteps( Proc, Chainsawing) -local dOriginalRadialOffsetChainsawing = Chainsawing.RadialOffset -local bIsChainsawingOk, sErrorMessageChainsawingApply -for i = Chainsawing.VerticalSteps.Count, 1, -1 do - Chainsawing.RadialOffset = dOriginalRadialOffsetChainsawing + Chainsawing.VerticalSteps.StepLength * ( i - 1) - bIsChainsawingOk, sErrorMessageChainsawingApply = SawPlusChain.ApplyMachining( Chainsawing, 'Chainsaw_', b3Raw) -end -if sErrorMessageChainsawingApply and #sErrorMessageChainsawingApply > 0 then - sErrorMessageChainsawing = sErrorMessageChainsawing .. '\n' .. 'Apply : ' .. sErrorMessageChainsawingApply + return Chainsawing end -return bIsChainsawingOk, sErrorMessageChainsawing + +function SawPlusChain.Make( Proc, b3Raw, bOnlySaw) + Proc.Pocket = {} + Proc.Pocket.Strategy = 'SawPlusChain' + + if not SawPlusChain.IsTopologyOk( Proc) then + local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not implemented for topology ' .. Proc.TopologyLongName + return false, sErr + end + + -- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto) + -- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama da sotto + if Proc.AffectedFaces.Bottom then + local sErr = 'Feature '.. Proc.FeatureId .. ' : strategy ' .. Proc.Pocket.Strategy .. ' not applicable - pocket on bottom face' + return false, sErr + end + + -- caratteristiche della tasca + Proc.Pocket.BottomFace = SawPlusChain.GetBottomFace( Proc) + Proc.Pocket.FaceToMachine = SawPlusChain.GetFaceToMachine( Proc) + Proc.Pocket.SideFaces = SawPlusChain.GetSideFaces( Proc) + Proc.Pocket.Width = Proc.Pocket.BottomFace.Width + Proc.Pocket.Height = Proc.Pocket.BottomFace.Height + Proc.Pocket.Depth = Proc.Pocket.BottomFace.Elevation + Proc.Pocket.Direction = Proc.Pocket.BottomFace.VtN + + -- parametri lavorazione di lama + local Cutting = SawPlusChain.Saw.CalculateMachiningParameters( Proc) + + -- applicazione lavorazione di lama + local bIsCuttingOk = false + local sCuttingApplyMessage = '' + if Cutting.CanApply then + local dOriginalRadialOffset = Cutting.RadialOffset + for i = Cutting.HorizontalSteps.Count, 1, -1 do + Cutting.RadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.StepLength * ( i - 1) + bIsCuttingOk, sCuttingApplyMessage = SawPlusChain.ApplyMachining( Cutting, 'Cut_', b3Raw) + if sCuttingApplyMessage and #sCuttingApplyMessage > 0 then + Cutting.Message = Cutting.Message .. '\n' .. 'Apply : ' .. sCuttingApplyMessage + end + end + end + + if bOnlySaw or not bIsCuttingOk then + return bIsCuttingOk, Cutting.Message + end + + -- parametri lavorazione con sega a catena + local Chainsawing = SawPlusChain.Chainsaw.CalculateMachiningParameters( Proc) + -- si lavora solo quanto non lavorato dalla lama + Chainsawing.MaxElev = Cutting.RadialOffset + BD.CUT_EXTRA + + -- applicazione lavorazione con sega a catena + local bIsChainsawingOk = false + local sChainsawingApplyMessage = '' + if Chainsawing.CanApply then + local dOriginalRadialOffsetChainsawing = Chainsawing.RadialOffset + for i = Chainsawing.VerticalSteps.Count, 1, -1 do + Chainsawing.RadialOffset = dOriginalRadialOffsetChainsawing + Chainsawing.VerticalSteps.StepLength * ( i - 1) + bIsChainsawingOk, sChainsawingApplyMessage = SawPlusChain.ApplyMachining( Chainsawing, 'Chainsaw_', b3Raw) + if sChainsawingApplyMessage and #sChainsawingApplyMessage > 0 then + Chainsawing.Message = Chainsawing.Message .. '\n' .. 'Apply : ' .. sChainsawingApplyMessage + end + end + end + + return bIsChainsawingOk, Chainsawing.Message end --#endregion SawPlusChain