diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 2f507cc..3434010 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -53,6 +53,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Front Slot @@ -65,6 +69,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Birds Mouth @@ -83,6 +91,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Lap Joint @@ -95,6 +107,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Notch/Rabbet @@ -107,6 +123,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Block Haus @@ -122,6 +142,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : French Ridge Lap @@ -146,6 +170,10 @@ local function GetStrategies_Egalware( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Drilling @@ -293,6 +321,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Front Slot @@ -305,6 +337,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Birds Mouth @@ -323,6 +359,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Lap Joint @@ -335,6 +375,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Notch/Rabbet @@ -347,6 +391,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Block Haus @@ -362,6 +410,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : French Ridge Lap @@ -386,6 +438,10 @@ local function GetStrategies_Essetre( Proc) Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}} elseif Proc.Topology.sName == 'Tunnel-4-Through' then Strategies = { { sStrategyId = 'STR0003'}} + elseif Proc.Topology.sName == 'Groove-3-Blind' then + Strategies = { { sStrategyId = 'STR0002'}} + elseif Proc.Topology.sName == 'Rabbet-2-Through' then + Strategies = { { sStrategyId = 'STR0002'}} end --------------------------------------------------------------------- -- Feature : Drilling diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 43ba678..cd3fced 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -500,7 +500,7 @@ local function CollectFeatures( Part) Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureData.GetDrillingData( Proc) end -- informazioni facce e topologia - Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc) + Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL Proc.Topology = {} if FeatureData.NeedTopologyFeature( Proc) then @@ -925,6 +925,7 @@ end if EgtGetDebugLevel() >= 3 then local timeCollect = EgtStopCounter() timeCollect = timeCollect + 0 + EgtOutBox( timeCollect, 'Collect calculation time') EgtStartCounter() end @@ -970,6 +971,7 @@ end if EgtGetDebugLevel() >= 3 then local timeMachining = EgtStopCounter() timeMachining = timeMachining + 0 + EgtOutBox( timeMachining, 'Machining calculation time') end diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 2657bfd..ddf4a91 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -148,27 +148,25 @@ end ------------------------------------------------------------------------------------------------------------- -- restituisce le facce della parte interessate dalla feature Proc -function BeamLib.GetAffectedFaces( Proc) - local nBoxSolidId = EgtGetFirstNameInGroup( Proc.idPart or GDB_ID.NULL, 'Box') - local b3Part = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD) +function BeamLib.GetAffectedFaces( Proc, Part) local vtFacesAffected = { bTop = false, bBottom = false, bFront = false, bBack = false, bLeft = false, bRight = false} if Proc.b3Box and not Proc.b3Box:isEmpty() then - if Proc.b3Box:getMax():getZ() > b3Part:getMax():getZ() - 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMax():getZ() > Part.b3Solid:getMax():getZ() - 500 * GEO.EPS_SMALL then vtFacesAffected.bTop = true end - if Proc.b3Box:getMin():getZ() < b3Part:getMin():getZ() + 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMin():getZ() < Part.b3Solid:getMin():getZ() + 500 * GEO.EPS_SMALL then vtFacesAffected.bBottom = true end - if Proc.b3Box:getMin():getY() < b3Part:getMin():getY() + 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMin():getY() < Part.b3Solid:getMin():getY() + 500 * GEO.EPS_SMALL then vtFacesAffected.bFront = true end - if Proc.b3Box:getMax():getY() > b3Part:getMax():getY() - 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMax():getY() > Part.b3Solid:getMax():getY() - 500 * GEO.EPS_SMALL then vtFacesAffected.bBack = true end - if Proc.b3Box:getMin():getX() < b3Part:getMin():getX() + 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + 500 * GEO.EPS_SMALL then vtFacesAffected.bLeft = true end - if Proc.b3Box:getMax():getX() > b3Part:getMax():getX() - 500 * GEO.EPS_SMALL then + if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - 500 * GEO.EPS_SMALL then vtFacesAffected.bRight = true end end @@ -211,6 +209,40 @@ function BeamLib.GetNearestOrthoOpposite( vtRef, vtNorm) return nil end +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- se prevalente una componente orizzontale (con piccolissimo vantaggio) + if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.95 * abs( vtMyRef:getZ()) then + if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getY()) then + if vtMyRef:getX() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtMyRef:getY() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + --------------------------------------------------------------------- -- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId) diff --git a/LuaLibs/FeatureData.lua b/LuaLibs/FeatureData.lua index 7060ecb..8bb7b82 100644 --- a/LuaLibs/FeatureData.lua +++ b/LuaLibs/FeatureData.lua @@ -133,7 +133,7 @@ end function FeatureData.ClassifyTopology( Proc, Part) local FeatureTopology = {} - if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc) end + if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part) local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part) @@ -154,7 +154,7 @@ function FeatureData.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.Left or Proc.AffectedFaces.Right) and ( Proc.AffectedFaces.Front or Proc.AffectedFaces.Back) then + elseif Proc.nFct == 2 and bAllAnglesConcave 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 @@ -263,7 +263,7 @@ function FeatureData.GetFeatureQuality( sTypeTools) nQuality = min( nQuality, 5) elseif TypeTools[i] == 'Mill' then nQuality = min( nQuality, 4) - elseif TypeTools[i] == 'ChainSaw' then + elseif TypeTools[i] == 'Chainsaw' then nQuality = min( nQuality, 2) else nQuality = min( nQuality, 1) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index ed98c02..8324884 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -286,6 +286,7 @@ function MachiningLib.FindChainSaw( Proc, ToolSearchParameters) end ToolInfo.nToolIndex = nBestToolIndex + ToolInfo.dResidualDepth = dBestToolResidualDepth return ToolInfo end @@ -337,8 +338,8 @@ function MachiningLib.AddNewMachining( Machining) EgtSetMachiningGeometry( {{ Machining.idProc, Machining.idFaceToMachine}}) -- impostazione parametri lavorazione - if Machining.dDepth then - EgtSetMachiningParam( MCH_MP.DEPTH, Machining.dDepth) + if Machining.sDepth then + EgtSetMachiningParam( MCH_MP.DEPTH_STR, Machining.sDepth) end if Machining.bInvert then EgtSetMachiningParam( MCH_MP.INVERT, Machining.bInvert) diff --git a/Strategies/STR0002/STR0002.lua b/Strategies/STR0002/STR0002.lua index 46e8e95..f2b62a1 100644 --- a/Strategies/STR0002/STR0002.lua +++ b/Strategies/STR0002/STR0002.lua @@ -15,8 +15,12 @@ local Strategy = {} ------------------------------------------------------------------------------------------------------------- local function IsTopologyOk( Proc) - if Proc.Topology.sName == 'Pocket-5-Blind' or Proc.Topology.sName == 'Groove-4-Blind' or - Proc.Topology.sName == 'Tunnel-4-Through' or Proc.Topology.sName == 'Groove-3-Through' then + if Proc.Topology.sName == 'Pocket-5-Blind' or + Proc.Topology.sName == 'Groove-4-Blind' or + Proc.Topology.sName == 'Groove-3-Through' or + Proc.Topology.sName == 'Groove-3-Blind' or + Proc.Topology.sName == 'Rabbet-2-Through' then + return true else return false diff --git a/Strategies/STR0003/STR0003.lua b/Strategies/STR0003/STR0003.lua index 1ad420a..298c09a 100644 --- a/Strategies/STR0003/STR0003.lua +++ b/Strategies/STR0003/STR0003.lua @@ -14,6 +14,8 @@ local STR0003 = {} local Strategy = {} local Blade = {} local Chainsaw = {} +Blade.Result = {} +Chainsaw.Result = {} ------------------------------------------------------------------------------------------------------------- @@ -52,6 +54,18 @@ local function GetCompletionPercentage( Proc, Result) end +local function AddResult( Machining, Result) + table.insert( Result, {}) + Result[#Result].bCanApply = Machining.bCanApply + Result[#Result].sMessage = Machining.sMessage + Result[#Result].dDepthMachined = Machining.dDepthToMachine + Result[#Result].bIsApplyOk = Machining.bIsApplyOk + Result[#Result].sApplyMessage = Machining.sApplyMessage + + return Result +end + + local function CalculateLeadInOut( Machining, EdgeToMachine) -- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom) @@ -127,15 +141,15 @@ local function AddNewMachining( Machining, Part) -- impostazione parametri lavorazione local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) EgtSetMachiningGeometry( Machining.Geometry) - EgtSetMachiningParam( MCH_MP.DEPTH, Machining.Depth or 0) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, Machining.sDepth) EgtSetMachiningParam( MCH_MP.FACEUSE, Machining.nFaceuse) - EgtSetMachiningParam( MCH_MP.SCC, Machining.nSCC) + EgtSetMachiningParam( MCH_MP.SCC, Machining.nSCC or MCH_SCC.STD) EgtSetMachiningParam( MCH_MP.INVERT, Machining.bInvert) EgtSetMachiningParam( MCH_MP.WORKSIDE, Machining.nWorkside) EgtSetMachiningParam( MCH_MP.TOOLINVERT, Machining.bToolInvert) EgtSetMachiningParam( MCH_MP.OFFSR, Machining.dRadialOffset) EgtSetMachiningParam( MCH_MP.OFFSL, Machining.dLongitudinalOffset) - if Machining.Type ~= MCH_OY.MORTISING then + if Machining.nType ~= MCH_OY.MORTISING then EgtSetMachiningParam( MCH_MP.LEADINTYPE, Machining.LeadIn.nType) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, Machining.LeadOut.nType) EgtSetMachiningParam( MCH_MP.LITANG, Machining.LeadIn.dTangentDistance) @@ -277,6 +291,8 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine) end -- parametri della lavorazione + -- profondità (parametro DEPTH) non usata + Cutting.sDepth = 0 -- inizio e fine aperti o chiusi Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen @@ -298,7 +314,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine) else Cutting.bToolInvert = false end - -- profondità e offset radiale + -- profondità da lavorare e offset radiale if TOOLS[Cutting.nToolIndex].dMaxDepth > abs( EdgeToMachine.dElevation) - 10 * GEO.EPS_SMALL then -- TODO la depth dovrebbe essere quella del machining Cutting.dDepthToMachine = abs( EdgeToMachine.dElevation) @@ -322,7 +338,7 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine) end -- step verticale e offset longitudinale Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness) - Cutting.Steps.StepType = MCH_MILL_ST.ONEWAY + Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY Cutting.dMaxElev = Cutting.Steps.dStepLength * Cutting.Steps.nCount - 10 * GEO.EPS_SMALL if Cutting.bToolInvert and Cutting.Steps.nCount > 1 then Cutting.dLongitudinalOffset = - dPocketHeight @@ -363,21 +379,26 @@ function Blade.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachine) -- eventuale avviso di danneggiamento pezzo successivo -- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza - local dOffsideLength = max( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength) + TOOLS[Cutting.nToolIndex].dDiameter / 2 + 10 * GEO.EPS_SMALL - if ( not Proc.Tail or Proc.AdvTail) and Proc.AffectedFaces.Left and ( Proc.DistanceToNextPart < dOffsideLength) then - local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : sawblade can damage next piece.' - if #Cutting.sMessage > 0 then - Cutting.sMessage = Cutting.sMessage .. '\n' .. sDamageNextPieceMessage - else - Cutting.sMessage = sDamageNextPieceMessage - end - EgtOutLog( sDamageNextPieceMessage) - end +-- local dOffsideLength = max( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength) + TOOLS[Cutting.nToolIndex].dDiameter / 2 + 10 * GEO.EPS_SMALL +-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then +-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : sawblade can damage next piece.' +-- if #Cutting.sMessage > 0 then +-- Cutting.sMessage = Cutting.sMessage .. '\n' .. sDamageNextPieceMessage +-- else +-- Cutting.sMessage = sDamageNextPieceMessage +-- end +-- EgtOutLog( sDamageNextPieceMessage) +-- end return Cutting, dResidualDepth end +function Blade.AddResult( Cutting) + AddResult( Cutting, Blade.Result) +end + + function Blade.AddMachiningAllSteps( Cutting, Part) local bIsCuttingOk = false local sCuttingApplyMessage = '' @@ -414,7 +435,7 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi local dPocketHeight = 0 if Proc.Topology.sFamily == 'Tunnel' then - dPocketHeight = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.dHeight + dPocketHeight = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dHeight else if FaceToMachine.Type == 'Long' then dPocketHeight = Proc.MainFaces.BottomFace.MainEdges.SideEdges[1].dLength @@ -488,6 +509,8 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi end -- parametri della lavorazione + -- profondità (parametro DEPTH) non usata + Mortising.sDepth = 'TH' -- inizio e fine aperti o chiusi Mortising.bIsStartClosed = not EdgeToMachine.bIsStartOpen Mortising.bIsEndClosed = not EdgeToMachine.bIsEndOpen @@ -510,14 +533,14 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi elseif sMortisingType == 'BothSidesAndExtend' then Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) / 2 + TOOLS[Mortising.nToolIndex].dCornerRadius + BeamData.CUT_EXTRA_MIN end - if TOOLS[Mortising.nToolIndex].dMaxMat > Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then + if TOOLS[Mortising.nToolIndex].dMaxMaterial > Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then Mortising.dLongitudinalOffset = 0 else Mortising.dLongitudinalOffset = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine end else - Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMat - 1 + Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMaterial - 1 dResidualDepth = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - Mortising.dDepthToMachine @@ -533,6 +556,13 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi Mortising.dStartSafetyLength = EdgeToMachine.dElevation -- overlap Mortising.dOverlap = 0 + -- step + Mortising.Steps = {} + if Strategy.Parameters.bUseZigZagMortising then + Mortising.Steps.nStepType = MCH_MILL_ST.ZIGZAG + else + Mortising.Steps.nStepType = MCH_MILL_ST.ONEWAY + end -- faceuse if EdgeToMachine.dElevation > - 10 * GEO.EPS_SMALL then Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( EdgeToMachine.vtToolDirection) @@ -559,21 +589,27 @@ function Chainsaw.CalculateMachiningParameters( Proc, FaceToMachine, EdgeToMachi Mortising.sOperationName = 'Chainsaw_' .. ( EgtGetName( Mortising.idProc) or tostring( Mortising.idProc)) .. '_' .. tostring( FaceToMachine.id + 1) -- eventuale avviso di danneggiamento pezzo successivo - local dOffsideLength = max( Mortising.LeadIn.dStartAddLength, Mortising.LeadOut.dEndAddLength) + TOOLS[Mortising.nToolIndex].dWidth / 2 + 10 * GEO.EPS_SMALL - if ( not Proc.Tail or Proc.AdvTail) and Proc.AffectedFaces.Left and ( Proc.DistanceToNextPart < dOffsideLength) then - local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw can damage next piece.' - if #Mortising.sMessage > 0 then - Mortising.sMessage = Mortising.sMessage .. '\n' .. sDamageNextPieceMessage - else - Mortising.sMessage = sDamageNextPieceMessage - end - EgtOutLog( sDamageNextPieceMessage) - end + -- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza +-- local dOffsideLength = max( Mortising.LeadIn.dStartAddLength, Mortising.LeadOut.dEndAddLength) + TOOLS[Mortising.nToolIndex].dWidth / 2 + 10 * GEO.EPS_SMALL +-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then +-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw can damage next piece.' +-- if #Mortising.sMessage > 0 then +-- Mortising.sMessage = Mortising.sMessage .. '\n' .. sDamageNextPieceMessage +-- else +-- Mortising.sMessage = sDamageNextPieceMessage +-- end +-- EgtOutLog( sDamageNextPieceMessage) +-- end return Mortising, dResidualDepth end +function Chainsaw.AddResult( Mortising) + AddResult( Mortising, Chainsaw.Result) +end + + function Chainsaw.AddMachiningAllSteps( Mortising, Part) local bIsMortisingOk = false local sMortisingApplyMessage = '' @@ -603,75 +639,65 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) Strategy.Result = {} Strategy.Result.sInfo = '' - Blade.Result = {} - Chainsaw.Result = {} local dResidualDepth = 0 if not IsTopologyOk( Proc) then local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented' EgtOutLog( sErr) + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.sInfo = 'Topology' return false, Strategy.Result 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 and ( Proc.Fct > 3 or not Proc.AffectedFaces.Top) then + if Proc.AffectedFaces.bBottom and ( Proc.nFct > 3 or not Proc.AffectedFaces.bTop) then local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket on bottom face' EgtOutLog( sErr) + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.sInfo = 'Direction' return false, Strategy.Result end -- lama -- lavorazione di lama - fondo della tasca o fino a massimo materiale se tunnel - table.insert( Blade.Result, {}) local Cutting = {} if Proc.Topology.sFamily == 'Tunnel' then Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1]) else Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge) end - Blade.Result[#Blade.Result].bCanApply = Cutting.bCanApply - Blade.Result[#Blade.Result].sMessage = Cutting.sMessage - Blade.Result[#Blade.Result].dDepthMachined = Cutting.dDepthToMachine if bAddMachining and Cutting.bCanApply then - Blade.Result[#Blade.Result].bIsApplyOk, Blade.Result[#Blade.Result].sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) + Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) end + Blade.AddResult( Cutting) local dBottomDepthToMachine = dResidualDepth -- lato opposto del tunnel if Proc.Topology.sFamily == 'Tunnel' then Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2]) - table.insert( Blade.Result, {}) - Blade.Result[#Blade.Result].bCanApply = Cutting.bCanApply - Blade.Result[#Blade.Result].sMessage = Cutting.sMessage - Blade.Result[#Blade.Result].dDepthMachined = Cutting.dDepthToMachine if bAddMachining and Cutting.bCanApply then - Blade.Result[#Blade.Result].bIsApplyOk, Blade.Result[#Blade.Result].sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) + Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) end + Blade.AddResult( Cutting) else -- se la lama non è arrivata sul fondo e c'è almeno un lato aperto va lavorato if dResidualDepth > 10 * GEO.EPS_SMALL then -- eventuale lavorazione di lama - lato della tasca da cui inizia la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1]) - table.insert( Blade.Result, {}) - Blade.Result[#Blade.Result].bCanApply = Cutting.bCanApply - Blade.Result[#Blade.Result].sMessage = Cutting.sMessage - Blade.Result[#Blade.Result].dDepthMachined = Cutting.dDepthToMachine if bAddMachining and Cutting.bCanApply then - Blade.Result[#Blade.Result].bIsApplyOk, Blade.Result[#Blade.Result].sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) + Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) end + Blade.AddResult( Cutting) end -- eventuale lavorazione di lama - lato della tasca in cui finisce la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then Cutting, dResidualDepth = Blade.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2]) - table.insert( Blade.Result, {}) - Blade.Result[#Blade.Result].bCanApply = Cutting.bCanApply - Blade.Result[#Blade.Result].sMessage = Cutting.sMessage - Blade.Result[#Blade.Result].dDepthMachined = Cutting.dDepthToMachine if bAddMachining and Cutting.bCanApply then - Blade.Result[#Blade.Result].bIsApplyOk, Blade.Result[#Blade.Result].sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) + Cutting.bIsApplyOk, Cutting.sApplyMessage = Blade.AddMachiningAllSteps( Cutting, Part) end + Blade.AddResult( Cutting) end -- la lama è arrivata sul fondo e tasca passante, non servono ulteriori lavorazioni elseif #( Proc.MainFaces.SideFaces) == 0 then @@ -680,6 +706,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) end end + -- TODO da migliorare / refactoring in funzione if not Strategy.Parameters.bFinishWithChainSaw then local nCanApplyCount = 0 local nApplyOkCount = 0 @@ -709,11 +736,10 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) end Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dCompletionPercentage) Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade') - local MrrParameters = { dStep = TOOLS[Cutting.nToolIndex].dThickness, - dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, - Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength), + local MRRParameters = { dStep = TOOLS[Cutting.nToolIndex].dThickness, + dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength), dFeed = TOOLS[Cutting.nToolIndex].Feeds.dFeed} - Strategy.Result.dMRR = MachiningLib.GetToolMRR( MrrParameters) + Strategy.Result.dMRR = MachiningLib.GetToolMRR( MRRParameters) return bAreAllApplyOk, Strategy.Result end @@ -721,61 +747,81 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) -- sega a catena -- parametri lavorazione con sega a catena - fondo della tasca o tunnel local Mortising = {} - if Proc.Topology == 'Tunnel' then + if Proc.Topology.sFamily == 'Tunnel' then Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1]) else - Mortising = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge) + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge) -- si lavora solo quanto non lavorato dalla lama Mortising.MaxElev = dBottomDepthToMachine + BeamData.CUT_EXTRA end - local bIsMortisingOk = false if bAddMachining and Mortising.bCanApply then - bIsMortisingOk, Mortising.Message = Chainsaw.AddMachiningAllSteps( Mortising, Part) + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Mortising, Part) end + Chainsaw.AddResult( Mortising) -- lato opposto del tunnel - if Proc.Topology == 'Tunnel' and ( dResidualDepth > 10 * GEO.EPS_SMALL) then - Mortising = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2]) - bIsMortisingOk = false + if Proc.Topology.sFamily == 'Tunnel' and ( dResidualDepth > 10 * GEO.EPS_SMALL) then + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2]) if bAddMachining and Mortising.bCanApply then - bIsMortisingOk, Mortising.Message = Chainsaw.AddMachiningAllSteps( Mortising, Part) - end - if not bIsMortisingOk then - return bIsMortisingOk, Mortising.Message + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Mortising, Part) end + Chainsaw.AddResult( Mortising) else -- se la sega a catena non è arrivata sul fondo e c'è almeno un lato aperto va lavorato - if Mortising.LongitudinalOffset > 10 * GEO.EPS_SMALL then + if Mortising.dLongitudinalOffset > 10 * GEO.EPS_SMALL then -- eventuale lavorazione di sega a catena - lato della tasca da cui inizia la lavorazione if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then - Mortising = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1]) - bIsMortisingOk = false + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1]) if bAddMachining and Mortising.bCanApply then - bIsMortisingOk, Mortising.Message = Chainsaw.AddMachiningAllSteps( Mortising, Part) - end - if not bIsMortisingOk then - return bIsMortisingOk, Mortising.Message + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Mortising, Part) end + Chainsaw.AddResult( Mortising) end -- eventuale lavorazione di sega a catena - lato della tasca in cui finisce la lavorazione if Proc.MainFaces.LongFace[1].MainEdges.BottomEdge.bIsEndOpen then - Mortising = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].Edges.SideEdges[2]) - bIsMortisingOk = false + Mortising, dResidualDepth = Chainsaw.CalculateMachiningParameters( Proc, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2]) if bAddMachining and Mortising.bCanApply then - bIsMortisingOk, Mortising.Message = Chainsaw.AddMachiningAllSteps( Mortising, Part) - end - if not bIsMortisingOk then - return bIsMortisingOk, Mortising.Message + Mortising.bIsApplyOk, Mortising.sApplyMessage = Chainsaw.AddMachiningAllSteps( Mortising, Part) end + Chainsaw.AddResult( Mortising) end end end - local sFinalMessage = '' - if #Cutting.Message > 0 or #Mortising.Message > 0 then - sFinalMessage = Cutting.Message .. '\n' .. Mortising.Message + -- TODO da migliorare / refactoring in funzione + local nCanApplyCount = 0 + local nApplyOkCount = 0 + local bAreAllApplyOk + local dCompletionPercentage = 0 + for i = 1, #Chainsaw.Result do + Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result[i].sMessage .. '\n' .. ( Chainsaw.Result[i].sApplyMessage or '') + if Chainsaw.Result[i].bCanApply then + nCanApplyCount = nCanApplyCount + 1 + end + if Chainsaw.Result[i].bIsApplyOk then + nApplyOkCount = nApplyOkCount + 1 + end end - - return bIsMortisingOk, sFinalMessage + if bAddMachining then + bAreAllApplyOk = ( nApplyOkCount == #Chainsaw.Result) + end + if nCanApplyCount == 0 then + Strategy.Result.sStatus = 'Not-Applicable' + else + dCompletionPercentage = GetCompletionPercentage( Proc, Chainsaw.Result) + if ( nCanApplyCount == #Chainsaw.Result) and dCompletionPercentage > 99 + 10 * GEO.EPS_SMALL then + Strategy.Result.sStatus = 'Completed' + else + Strategy.Result.sStatus = 'Not-Completed' + end + end + Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dCompletionPercentage) + Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Chainsaw') + local MRRParameters = { dStep = TOOLS[Cutting.nToolIndex].dThickness, + dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength), + dFeed = TOOLS[Cutting.nToolIndex].Feeds.dFeed} + Strategy.Result.dMRR = MachiningLib.GetToolMRR( MRRParameters) + + return bAreAllApplyOk, Strategy.Result end ------------------------------------------------------------------------------------------------------------- diff --git a/Strategies/STR0003/STR0003Config.lua b/Strategies/STR0003/STR0003Config.lua index fb8d6e3..a093563 100644 --- a/Strategies/STR0003/STR0003Config.lua +++ b/Strategies/STR0003/STR0003Config.lua @@ -3,10 +3,11 @@ local STR0003Data = { sStrategyId = 'STR0003', Parameters = { - { sName = 'bFinishWithChainSaw', sValue = 'false', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, + { sName = 'bFinishWithChainSaw', sValue = 'true', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, { sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, { sName = 'bContinueOnFailedApply', sValue = 'true', sDescriptionShort = 'Continue to next machining on failed apply', sDescriptionLong = 'If one machining of the strategy fails to apply continue with the others', sType = 'b', sMessageId = '', sMinUserLevel = '9'}, - { sName = 'bNotCompleteWithBladeRadius', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'} + { sName = 'bNotCompleteWithBladeRadius', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, + { sName = 'bUseZigZagMortising', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'} } } diff --git a/Strategies/Strategies.ini b/Strategies/Strategies.ini index 760dc45..03788bb 100644 --- a/Strategies/Strategies.ini +++ b/Strategies/Strategies.ini @@ -20,11 +20,15 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega 16,0,Pocket-5-Blind,STR0002,STR0003 16,0,Groove-4-Blind,STR0002,STR0003 16,0,Groove-3-Through,STR0002,STR0003 +16,0,Groove-3-Blind,STR0002 +16,0,Rabbet-2-Through,STR0002 16,0,Tunnel-4-Through,STR0003 ; Feature : Front Slot 17,0,Pocket-5-Blind,STR0002,STR0003 17,0,Groove-4-Blind,STR0002,STR0003 +17,0,Groove-3-Blind,STR0002 17,0,Groove-3-Through,STR0002,STR0003 +17,0,Rabbet-2-Through,STR0002 17,0,Tunnel-4-Through,STR0003 ; Feature : Birds Mouth 20,0,Feature, @@ -33,24 +37,32 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega ; Feature : Ridge Lap 30,1,Pocket-5-Blind,STR0002,STR0003 30,1,Groove-4-Blind,STR0002,STR0003 +30,1,Groove-3-Blind,STR0002 30,1,Groove-3-Through,STR0002,STR0003 +30,1,Rabbet-2-Through,STR0002 30,1,Tunnel-4-Through,STR0003 ; Feature : Lap Joint 30,0,Pocket-5-Blind,STR0002,STR0003 30,0,Groove-4-Blind,STR0002,STR0003 +30,0,Groove-3-Blind,STR0002 30,0,Groove-3-Through,STR0002,STR0003 +30,0,Rabbet-2-Through,STR0002 30,0,Tunnel-4-Through,STR0003 ; Feature : Notch/Rabbet 32,0,Pocket-5-Blind,STR0002,STR0003 32,0,Groove-4-Blind,STR0002,STR0003 +32,0,Groove-3-Blind,STR0002 32,0,Groove-3-Through,STR0002,STR0003 +32,0,Rabbet-2-Through,STR0002 32,0,Tunnel-4-Through,STR0003 ; Feature : Block Haus 33,0,Feature, ; Feature : Notch 34,0,Pocket-5-Blind,STR0002,STR0003 34,0,Groove-4-Blind,STR0002,STR0003 +34,0,Groove-3-Blind,STR0002 34,0,Groove-3-Through,STR0002,STR0003 +34,0,Rabbet-2-Through,STR0002 34,0,Tunnel-4-Through,STR0003 ; Feature : French Ridge Lap 35,1,Feature, @@ -63,7 +75,9 @@ STR0003 = Topologia tipo LapJoint. Lama + motosega ; Feature : Pocket 39,0,Pocket-5-Blind,STR0002,STR0003 39,0,Groove-4-Blind,STR0002,STR0003 +39,0,Groove-3-Blind,STR0002 39,0,Groove-3-Through,STR0002,STR0003 +39,0,Rabbet-2-Through,STR0002 39,0,Tunnel-4-Through,STR0003 ; Feature : Drilling 40,0,Feature,