From d9f06eb07d298152156750ceb30447bc177afd02 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 4 Oct 2022 17:14:51 +0200 Subject: [PATCH 01/10] Fix commenti --- LuaLibs/BeamExec.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index a1732f6..fda8bc3 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -35,6 +35,7 @@ -- 2022/08/01 Tolleranza su sezione portata a 0.1 mm (100 * GEO.EPS_SMALL). -- 2022/08/08 Modifica per macchine senza BD.MAX_WIDTH2 e BD.MAX_HEIGHT2. -- 2022/08/18 Aggiunta gestione macchine con testa da sotto con lama da sotto disabilitata. +-- 2022/09/21 Nella funzione di ordinamento il foro del birdsmouth viene sempre fatto prima della lavorazione stessa -- 2022/09/28 I fori vengono sempre fatti prima delle tacche. -- 2022/09/29 Aggiunta la ricerca di feature specchiate, al momento solo per DtMortise, con le relative funzioni. From dc781d06bad752d33982684833d868844f9aeaa1 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 16 Dec 2022 12:35:15 +0100 Subject: [PATCH 02/10] Feature/SideMillOnL20: - Per L20 implementata forzatura utilizzo fresa di lato tramite parametro Q04 --- LuaLibs/ProcessLapJoint.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 17fbf70..1cba7a1 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -57,6 +57,7 @@ -- 2022/09/27 Aggiunta gestione SCC per svuotature con TURN (solo dopo applicazione lavorazione). -- 2022/10/20 In MakeByChainOrSaw modificato check per trovare la faccia adiacente sul lato più lungo. -- 2022/12/12 Default 1000 per BD.MIN_LEN_LAMELLO. In MachineByMill migliorata ricerca utensile e gestione inversione in funzione del lato di lavoro. +-- 2022/12/16 Implementato parametro Q_SIDE_ROUGH_TOOL anche per L20 -- Tabella per definizione modulo local ProcessLapJoint = {} @@ -140,6 +141,7 @@ local function AssignQIdent( Proc) Q_DEPTH_CHAMFER = 'Q01' -- d Q_USE_MILL = 'Q02' -- i Q_USE_ROUGH_TOOL = 'Q03' -- i + Q_SIDE_ROUGH_TOOL = 'Q04' -- i Q_BORE_ON_CORNER = 'Q06' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then Q_BORE_ON_CORNER = 'Q01' -- i @@ -5599,7 +5601,7 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) local nForceUseBladeOnNotContinueFace -- se ho attivo la lama e ho la feature 30, verifico i parametri Q propri della feature if bUseBlade then - if Proc.Prc == 30 then + if Proc.Prc == 30 or Proc.Prc == 20 then local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 nForceUseBladeOnNotContinueFace = EgtGetInfo( Proc.Id, Q_BLADE_ON_ALONG_FACE, 'i') or 0 From c7b5570dd88c292cf485f5874706680f0a5cd02c Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 22 Dec 2022 19:04:52 +0100 Subject: [PATCH 03/10] Feature/FindMirroredFeatures: - aggiunto riconoscimento forature da fare in doppio, da testare - aggiunto riconoscimento code di rondine in doppio, da testare - in caso di riconoscimento lavorazione in doppio si scrivono le opportune note nella lavorazione --- LuaLibs/BeamExec.lua | 202 ++++++++++++++++++++++------------- LuaLibs/MachiningLib.lua | 12 +-- LuaLibs/ProcessDrill.lua | 18 ++-- LuaLibs/ProcessDtMortise.lua | 33 ++++-- 4 files changed, 174 insertions(+), 91 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index b15c420..a5f5a8e 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1370,88 +1370,149 @@ local function MoveDrillsOnTenon( vProc) end end -------------------------------------------------------------------------------------------------------------- --- Estrazione parametri P da lavorazioni di tipo DtMortise -local function GetPParametersDtMortise( Proc) - local vPParameters = { - { 'P01', 'd'}, - { 'P02', 'd'}, - { 'P03', 'd'}, - { 'P04', 'i'}, - { 'P05', 'i'}, - { 'P06', 'd'}, - { 'P07', 'd'}, - { 'P09', 'd'}, - { 'P10', 'd'}, - { 'P11', 'd'}, - { 'P12', 'd'}, - { 'P13', 'd'}, - { 'P14', 'd'}, - { 'P15', 'd'} - } - for i = 1, #vPParameters do - vPParameter = vPParameters[i] - vPParameter[3] = EgtGetInfo( Proc.Id, vPParameter[1], vPParameter[2]) - end - return vPParameters -end - ------------------------------------------------------------------------------------------------------------- -- Controlla se la feature ProcMirror è la specchiata di Proc, per feature di tipo DtMortise -local function CheckMirrorDtMortise( Proc, ProcMirror, dHBeam) +local function CheckMirrorDtMortise( Proc, ProcMirror, b3Raw, AuxId) local bIsMirror = true - local vPParametersProc = GetPParametersDtMortise( Proc) - local vPParametersMirror = GetPParametersDtMortise( ProcMirror) - local nP02, nP06 = 2, 6 - -- controllo che i parametri P delle due feature, tranne P02 e P06, siano uguali - for i = 1, #vPParametersProc do - local vPParameterProc = vPParametersProc[i] - local vPParameterMirror = vPParametersMirror[i] - if vPParameterProc[1] ~= 'P02' and vPParameterProc[1] ~= 'P06'then - bIsMirror = ( abs( vPParameterProc[3] - vPParameterMirror[3]) < 100 * GEO.EPS_SMALL) - if bIsMirror == false then break end - elseif vPParameterProc[1] == 'P02' then - nP02 = i - elseif vPParameterProc[1] == 'P06' then - nP06 = i - end + + -- recupero i dati geometrici della curva Proc + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + local rfDtMrt = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_RT.GLOB) + local b3DtMrt = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfDtMrt) + -- determino l'asse della curva Proc + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + + -- recupero e verifico l'entità curva ProcMirror + local AuxIdMirror = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i') + if AuxIdMirror then AuxIdMirror = AuxIdMirror + ProcMirror.Id end + if not AuxIdMirror or ( EgtGetType( AuxIdMirror) & GDB_FY.GEO_CURVE) == 0 then + bIsMirror = false end - -- se gli altri parametri P sono uguali, verifico che P02 e P06 siano compatibili con feature specchiate - if bIsMirror == true then - bIsMirror = ( ( vPParametersProc[nP02][3] == 0 and abs( vPParametersMirror[nP02][3] - dHBeam) < 100 * GEO.EPS_SMALL) and - ( vPParametersProc[nP06][3] == 90 and vPParametersMirror[nP06][3] == -90)) or - ( ( vPParametersMirror[nP02][3] == 0 and abs( vPParametersProc[nP02][3] - dHBeam) < 100 * GEO.EPS_SMALL) and - ( vPParametersMirror[nP06][3] == 90 and vPParametersProc[nP06][3] == -90)) + -- recupero i dati geometrici della curva ProcMirror + local vtExtrMirror = EgtCurveExtrusion( AuxIdMirror, GDB_RT.GLOB) + local ptBCMirror = EgtGP( AuxIdMirror, GDB_RT.GLOB) + local b3DtMrtMirror = EgtGetBBoxRef( ProcMirror.Id, GDB_BB.STANDARD, rfDtMrt) + -- determino l'asse della curva ProcMirror + local vtAxMirror = EgtEV( AuxIdMirror, GDB_RT.GLOB) - EgtSV( AuxIdMirror, GDB_RT.GLOB) + + -- verifico se le mortase sono specchiate + if bIsMirror then + local vtDisplacement = ptBC - ptBCMirror + local ptCenRaw = b3Raw:getCenter() + -- controllo che il centro delle due mortase sia allineato e che queste siano equidistanti dalla mezzeria della trave + if AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + bIsMirror = vtDisplacement:getX() < 500 * GEO.EPS_SMALL and vtDisplacement:getZ() < 500 * GEO.EPS_SMALL and + ( abs( ptBC:getY() - ptCenRaw:getY()) - abs( ptBCMirror:getY() - ptCenRaw:getY())) < 500 * GEO.EPS_SMALL + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + bIsMirror = vtDisplacement:getX() < 500 * GEO.EPS_SMALL and vtDisplacement:getY() < 500 * GEO.EPS_SMALL and + ( abs( ptBC:getZ() - ptCenRaw:getZ()) - abs( ptBCMirror:getZ() - ptCenRaw:getZ())) < 500 * GEO.EPS_SMALL + end + -- controllo che le dimensioni dei due box siano le stesse + bIsMirror = abs( b3DtMrt:getDimX() - b3DtMrtMirror:getDimX()) < 500 * GEO.EPS_SMALL and + abs( b3DtMrt:getDimY() - b3DtMrtMirror:getDimY()) < 500 * GEO.EPS_SMALL and + abs( b3DtMrt:getDimZ() - b3DtMrtMirror:getDimZ()) < 500 * GEO.EPS_SMALL + -- controllo che l'asse delle due mortase sia allineato + bIsMirror = AreSameVectorApprox( vtAx, vtAxMirror) end return bIsMirror end ------------------------------------------------------------------------------------------------------------- --- Cerca se esiste una feature specchiata di Proc e nel caso ne restituisce la posizione in vProc -local function FindMirrorFeature( vProc, Proc, sFeatureType, dHBeam) - local nProcMirror +-- Verifica se Proc è lavorabile in doppio e nel caso ne restituisce la direzione di specchiatura. +local function IsFeatureMirrored( vProc, Proc, sFeatureType, b3Raw) + local nDouble = 0 -- se mortasa a coda di rondine if sFeatureType == 'DtMortise' then - Proc.Side = EgtGetInfo( Proc.Id, 'SIDE', 'i') + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati geometrici della curva + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1) + -- recupero il raggio minimo della mortasa + local dMinRad = 1000 + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dMinRad then + dMinRad = dRad + end + end + local dMaxDiam = 2 * dMinRad + local sMilling = ML.FindMilling( 'DtMortise', nil, nil, dMaxDiam, nil, true, false, _, true) + if sMilling then EgtMdbSetCurrMachining( sMilling) end + local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + -- verifico che l'utensile indicato abbia un diametro coerente con la curva + local dToolDoubleDiam = 9999 + if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then + dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd') + end + if dToolDoubleDiam < dMaxDiam + GEO.EPS_SMALL and ( AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) or AreSameOrOppositeVectorApprox( vtExtr, Z_AX())) and not bPocket then for i = 1, #vProc do local ProcMirror = vProc[i] - if DtMortise.SideIdentify(ProcMirror) then - ProcMirror.Side = EgtGetInfo( ProcMirror.Id, 'SIDE', 'i') - if ( Proc.Side == 1 and ProcMirror.Side == 3) or ( Proc.Side == 3 and ProcMirror.Side == 1) or - ( Proc.Side == 2 and ProcMirror.Side == 4) or ( Proc.Side == 4 and ProcMirror.Side == 2) then - local bIsMirror = CheckMirrorDtMortise( Proc, ProcMirror, dHBeam) - if bIsMirror then nProcMirror = i end + if DtMortise.SideIdentify(ProcMirror) and ProcMirror.Id ~= Proc.Id then + if CheckMirrorDtMortise( Proc, ProcMirror, b3Raw, AuxId) then + if AreSameVectorApprox( vtExtr, Y_AX()) then + nDouble = 2 + elseif AreSameVectorApprox( vtExtr, Z_AX()) then + nDouble = 3 + else + Proc.Flg = 0 + end end end end + end + -- se foratura + elseif sFeatureType == 'Drill' then + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + local sErr = 'Error : missing drill geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero direzione e dimensioni del foro + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local dMachiningDepth = dLen / 2 + BD.DRILL_OVERLAP + -- verifico che l'utensile di foratura abbia indicato il suo doppio nelle note + local sDrilling = ML.FindDrilling( dDiam, dMachiningDepth, true, false, true) + if not sDrilling then sDrilling = ML.FindDrilling( dDiam, 0, true, false, true) end + if sDrilling then EgtMdbSetCurrMachining( sDrilling) end + local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + -- verifico che l'utensile indicato abbia un diametro coerente con il foro + local dToolDoubleDiam = 0 + if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then + dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd') + end + if dToolDoubleDiam < dDiam + 10 * GEO.EPS_SMALL and dToolDoubleDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then + if Proc.Flg == -2 then vtExtr = vtExtr * -1 end + if Proc.Fce ~= 0 then + if AreSameVectorApprox( vtExtr, Y_AX()) then + nDouble = 2 + elseif AreSameVectorApprox( vtExtr, Z_AX()) and BD.DOWN_HEAD then + nDouble = 3 + elseif AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) or ( AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) and BD.DOWN_HEAD) then + Proc.Flg = 0 + end + end + end end - -- se foratura (da implementare) - return nProcMirror + return nDouble end ------------------------------------------------------------------------------------------------------------- --- Cerca in vProc la presenza di feature specchiate. Se le trova scrive in Proc e nelle info l'Id della specchiata. -local function SetMirroredFeatures( vProc, dHBeam) +-- Cerca in vProc la presenza di feature da lavorare in doppio. Se le trova scrive in Proc la direzione di specchiatura e l'utensile da utilizzare. +local function SetMirroredFeatures( vProc, b3Raw) for i = 1, #vProc do local Proc = vProc[i] local sFeatureType @@ -1460,14 +1521,10 @@ local function SetMirroredFeatures( vProc, dHBeam) elseif Drill.Identify(Proc) then sFeatureType = 'Drill' end - if ( sFeatureType == 'DtMortise' or sFeatureType == 'Drill') and not Proc.MirrorId then - local nProcMirror = FindMirrorFeature( vProc, Proc, sFeatureType, dHBeam) - if nProcMirror then - Proc.MirrorId = vProc[nProcMirror].Id - vProc[nProcMirror].MirrorId = Proc.Id - EgtSetInfo( Proc.Id, 'MIRRORID', vProc[nProcMirror].Id) - EgtSetInfo( vProc[nProcMirror].Id, 'MIRRORID', Proc.Id) - end + if ( sFeatureType == 'DtMortise' and BD.DOUBLE_HEAD_DOVETAIL) or ( sFeatureType == 'Drill' and BD.DOUBLE_HEAD_DRILLING) then + local nDouble = IsFeatureMirrored( vProc, Proc, sFeatureType, b3Raw) + -- 0: nessuna specchiatura, 1: specchiatura X, 2: specchiatura Y, 3: specchiatura Z + Proc.Double = nDouble end end end @@ -1567,9 +1624,8 @@ function BeamExec.ProcessFeatures() SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachineBeforeIntersectingDrillings) end -- verifica presenza di feature specchiate per eventuali lavorazioni simultanee - local bConcurrentDoubleHead = BD.DOUBLE_HEAD_MIRRORED_FEATURES and ( BD.TWO_EQUAL_HEADS or BD.TWO_UP_DOWN_HEADS) - if bConcurrentDoubleHead then - SetMirroredFeatures( vProc, EgtGetRawPartBBox( nRawId):getDimZ()) + if BD.TWO_EQUAL_HEADS or BD.DOWN_HEAD then + SetMirroredFeatures( vProc, b3Raw) end -- le ordino lungo X OrderFeatures( vProc, b3Raw) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index b51dd6b..b06f87b 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -224,7 +224,7 @@ function ReturnParams( MachiningType, MachiningName, sType, ToolParams) end --------------------------------------------------------------------- -local function FindMachining( MachiningType, sType, Params, bTopHead, bDownHead, bExcludeH3) +local function FindMachining( MachiningType, sType, Params, bTopHead, bDownHead, bExcludeH3, bExcludeH2) if bTopHead == nil and bDownHead == nil then bTopHead = true bDownHead = false @@ -276,7 +276,7 @@ local function FindMachining( MachiningType, sType, Params, bTopHead, bDownHead, end -- recupero dati utensile local bToolActive, sToolName, bH2, bFixed, bH3 = SetCurrMachiningAndTool( Machining.Name) - if Machining.On and sMachiningType == sType and bToolActive and ( not bH3 or bH3 == not bExcludeH3) then + if Machining.On and sMachiningType == sType and bToolActive and ( not bH3 or bH3 == not bExcludeH3) and ( not bH2 or bH2 == not bExcludeH2) then local bOk, ToolParams = VerifyTool( MachiningType, sType, Params, bH2) if bOk then if MachineHeadUse == ONE_HEAD then @@ -367,8 +367,8 @@ function MachiningLib.FindCutting( sType, bTopHead, bDownHead) end --------------------------------------------------------------------- -function MachiningLib.FindDrilling( dDiam, dDepth, bTopHead, bDownHead) - local MachiningName, MachiningType, Param1, Param2, Param3, Param4, Param5 = FindMachining( MCH_MY.DRILLING, 'Drill', { Diam = dDiam, Depth = dDepth}, bTopHead, bDownHead) +function MachiningLib.FindDrilling( dDiam, dDepth, bTopHead, bDownHead, bExcludeH2) + local MachiningName, MachiningType, Param1, Param2, Param3, Param4, Param5 = FindMachining( MCH_MY.DRILLING, 'Drill', { Diam = dDiam, Depth = dDepth}, bTopHead, bDownHead, _, bExcludeH2) if not MachiningName or MachiningName == '' then MachiningName, MachiningType, Param1, Param2, Param3, Param4, Param5 = FindMachining( MCH_MY.DRILLING, 'Pocket', { Diam = dDiam, Depth = dDepth}, bTopHead, bDownHead) end @@ -386,8 +386,8 @@ function MachiningLib.FindAngleDrilling( dDiam, dDepth, bTopHead, bDownHead) end --------------------------------------------------------------------- -function MachiningLib.FindMilling( sType, dDepth, sTuuidMstr, dMaxDiam, dMaxTotLen, bTopHead, bDownHead, bExcludeH3) - return FindMachining( MCH_MY.MILLING, sType, { Depth = dDepth, TuuidMstr = sTuuidMstr, MaxDiam = dMaxDiam, MaxTotLen = dMaxTotLen}, bTopHead, bDownHead, bExcludeH3) +function MachiningLib.FindMilling( sType, dDepth, sTuuidMstr, dMaxDiam, dMaxTotLen, bTopHead, bDownHead, bExcludeH3, bExcludeH2) + return FindMachining( MCH_MY.MILLING, sType, { Depth = dDepth, TuuidMstr = sTuuidMstr, MaxDiam = dMaxDiam, MaxTotLen = dMaxTotLen}, bTopHead, bDownHead, bExcludeH3, bExcludeH2) end --------------------------------------------------------------------- diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua index d53f865..8f5ffac 100644 --- a/LuaLibs/ProcessDrill.lua +++ b/LuaLibs/ProcessDrill.lua @@ -269,11 +269,17 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) -- abilitazione foratura da sotto local bDrillDown = ( bDownDrill and ( Proc.Down or vtExtr:getZ() < -0.1 or vtExtr:getZ() < 0.259)) local bDrillUp = ( bDownDrill and vtExtr:getZ() > -0.421) + local bExcludeH2 = false + if Proc.Double and Proc.Double > 0 then + bMillUp = true + bDrillDown = false + bExcludeH2 = true + end -- primo gruppo di controlli con lunghezza utensile pari a metà foro se passante -- recupero la lavorazione - local sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillUp, bDrillDown) + local sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillUp, bDrillDown, bExcludeH2) if not sDrilling and dCheckDepth then - sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown) + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown, bExcludeH2) if sDrilling then dCheckDepth = nil end end if not sDrilling then @@ -480,10 +486,10 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) sUserNotes = sUserNotes .. 'Open=1;' end -- se lavorazione in doppio - if EgtExistsInfo( Proc.Id, 'MAIN') then - sUserNotes = sUserNotes .. 'Double;' - elseif EgtExistsInfo( Proc.Id, 'DOU') then - sUserNotes = sUserNotes .. 'Main;' + if Proc.Double and Proc.Double > 0 and ( sType == 'Drill') then + local sToolNameDouble = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + sUserNotes = sUserNotes .. 'DOUBLE=' .. Proc.Double .. ',' + sUserNotes = sUserNotes .. sToolNameDouble .. ';' end EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) -- eseguo diff --git a/LuaLibs/ProcessDtMortise.lua b/LuaLibs/ProcessDtMortise.lua index e7ebb09..1556b19 100644 --- a/LuaLibs/ProcessDtMortise.lua +++ b/LuaLibs/ProcessDtMortise.lua @@ -232,10 +232,16 @@ function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) elseif bMillAngTrasm then sMchExt = '_AT' end + local bExcludeH2 = false + if Proc.Double and Proc.Double > 0 then + bMillUp = true + bMillDown = false + bExcludeH2 = true + end -- recupero la lavorazione : prima ricerca per sola tipologia - local sMilling = ML.FindMilling( sMillType..sMchExt, nil, nil, nil, nil, bMillUp, bMillDown) + local sMilling = ML.FindMilling( sMillType..sMchExt, nil, nil, nil, nil, bMillUp, bMillDown, _, bExcludeH2) if not sMilling and bMillUp then - sMilling = ML.FindMilling( sMillType, nil, nil, nil, nil, bMillUp, bMillDown) + sMilling = ML.FindMilling( sMillType, nil, nil, nil, nil, bMillUp, bMillDown, _, bExcludeH2) end if not sMilling then local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) @@ -243,9 +249,9 @@ function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) return false, sErr end -- recupero la lavorazione : seconda ricerca con tipologia e diametro massimo - sMilling = ML.FindMilling( sMillType..sMchExt, nil, nil, 2 * dMinRad, nil, bMillUp, bMillDown) + sMilling = ML.FindMilling( sMillType..sMchExt, nil, nil, 2 * dMinRad, nil, bMillUp, bMillDown, _, bExcludeH2) if not sMilling and bMillUp then - sMilling = ML.FindMilling( sMillType, nil, nil, 2 * dMinRad, nil, bMillUp, bMillDown) + sMilling = ML.FindMilling( sMillType, nil, nil, 2 * dMinRad, nil, bMillUp, bMillDown, _, bExcludeH2) sMchExt = '' end if not sMilling then @@ -412,8 +418,15 @@ function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) if nSCC then EgtSetMachiningParam( MCH_MP.SCC, nSCC) end + local sUserNotes = '' -- dichiaro non si generano sfridi per VMill - local sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' + sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' + -- se lavorazione in doppio + if Proc.Double and Proc.Double > 0 then + local sToolNameDouble = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + sUserNotes = sUserNotes .. 'DOUBLE=' .. Proc.Double .. ',' + sUserNotes = sUserNotes .. sToolNameDouble .. ';' + end EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) -- eseguo if not ML.ApplyMachining( true, false) then @@ -489,8 +502,16 @@ function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) if nSCC then EgtSetMachiningParam( MCH_MP.SCC, nSCC) end + local sUserNotes = '' -- dichiaro non si generano sfridi per VMill - local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + -- se lavorazione in doppio + if Proc.Double and Proc.Double > 0 then + local sToolNameDouble = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + sUserNotes = sUserNotes .. 'DOUBLE=' .. Proc.Double .. ',' + sUserNotes = sUserNotes .. sToolNameDouble .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + end EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) -- eseguo if not ML.ApplyMachining( true, false) then From cb70e2a47dfe32e6dcc5ad08d0d033ffe9a3dc81 Mon Sep 17 00:00:00 2001 From: Emmanuele Sassi Date: Fri, 23 Dec 2022 17:57:10 +0100 Subject: [PATCH 04/10] - nuovo nesting che fa piu' tentativi con diversi indici di pezzi piccoli --- NestProcess.lua | 363 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 242 insertions(+), 121 deletions(-) diff --git a/NestProcess.lua b/NestProcess.lua index be7ea92..ace4f83 100644 --- a/NestProcess.lua +++ b/NestProcess.lua @@ -17,6 +17,9 @@ EgtEnableDebug( false) local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN["1"] EgtOutLog( sLog) +-- flag per abilitare statistiche in log +local bLogStat = false + -- Cancello file di log specifico local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt') EgtEraseFile( sLogFile) @@ -87,9 +90,9 @@ local function ExecMaximumFilling( Raw, Parts) EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1) end -- Eseguo l'ottimizzazione - EgtStartCounter() + --EgtStartCounter() EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType) - local dTime = EgtStopCounter() + --local dTime = EgtStopCounter() -- Recupero i risultati local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults() local OneRes = {} @@ -97,7 +100,8 @@ local function ExecMaximumFilling( Raw, Parts) local nPartId, nCount = EgtMaxFillerGetOneResult( i) table.insert( OneRes, { Id=nPartId, Count=nCount}) end - return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes} + --return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes} + return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes} end -- Funzione per trovare nome MachGroup @@ -155,7 +159,6 @@ local nErrCnt = 0 local nWarnCnt = 0 -- Grezzi --- lista dei grezzi local Raws = {} -- creo tabella dei grezzi for nIndex, nLen in pairs( LEN) do @@ -165,8 +168,6 @@ for nIndex, nQty in pairs( QTY) do Raws[tonumber(nIndex)].Count = nQty end ---local nTotRaws = Raws.Count - -- Pezzi local Parts = {} @@ -176,13 +177,17 @@ for RawIndex = 1, #Raws do maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap) end -- ciclo su pezzi per aggiungerli al nesting +local dTotLen = 0 for nPartId, nCount in pairs( PART) do -- recupero lunghezza pezzo local Len = EgtGetInfo( nPartId, "L", 'd') local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0) -- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione if Len < maxRawLenToFillNoStartGap then - table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = nCount}) + for nCntIndex = 1 , nCount do + table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1}) + dTotLen = dTotLen + Len + end end end @@ -201,131 +206,247 @@ local MediumRawQty = ceil( RawQtySum / #NeededRawsForType) if MediumRawQty > 1 then MediumRawQty = MediumRawQty - 1 end --- recupero pezzi piu' corti di mille -local ShortList = {} -local LongList = {} -for PartIndex = 1, #Parts do - if Parts[PartIndex].Len <= 1000 then - table.insert( ShortList, Parts[PartIndex]) - else - table.insert( LongList, Parts[PartIndex]) + +-- lista dei risultati +local ResultList = {} +local BestResult = nil +local BestResultIndex = nil +-- riordino lista pezzi per lunghezza +table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end) + +local function NestSolutionByIndex( Index) + + -- creo copia lista raw + local TempRaws = {} + for TempRawIndex = 1, #Raws do + table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count}) end -end --- numero di pezzi piccoli per barra -local ShortCount = 0 -for ShortIndex = 1, #ShortList do - ShortCount = ShortCount + ShortList[ShortIndex].Cnt -end -local ShortForRaw = floor( ShortCount / MediumRawQty) -local ExtraShortForRaw = 0 -if MediumRawQty > 0 then - ExtraShortForRaw = fmod( ShortCount, MediumRawQty) -end --- creo lista pezzi corti singoli -local SingleShortList = {} -for ShortIndex = 1, #ShortList do - for ShortCount = 1, ShortList[ShortIndex].Cnt do - table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1}) + + -- recupero pezzi corti + local ShortList = {} + local LongList = {} + + for PartIndex = 1, #Parts do + if PartIndex <= Index then + table.insert( ShortList, Parts[PartIndex]) + else + table.insert( LongList, Parts[PartIndex]) + end + Parts[PartIndex].Cnt = 1 end -end --- li divido per le barre previste -local RawsShortList = {} -local RawIndex = 0 -local ShortRawIndex = 0 -for ShortIndex = 1, #SingleShortList do - if ShortRawIndex > 0 then - table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex]) - ShortRawIndex = ShortRawIndex - 1 - else - table.insert( RawsShortList, {SingleShortList[ShortIndex]}) - RawIndex = RawIndex + 1 - ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1 + -- numero di pezzi piccoli per barra + local ShortCount = Index + local ShortForRaw = floor( ShortCount / MediumRawQty) + local ExtraShortForRaw = 0 + if MediumRawQty > 0 then + ExtraShortForRaw = fmod( ShortCount, MediumRawQty) + end + -- creo lista pezzi corti singoli + local SingleShortList = {} + for ShortIndex = 1, #ShortList do + for ShortCount = 1, ShortList[ShortIndex].Cnt do + table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1}) + end + end + -- li divido per le barre previste + local RawsShortList = {} + local RawIndex = 0 + local ShortRawIndex = 0 + for ShortIndex = 1, #SingleShortList do + if ShortRawIndex > 0 then + table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex]) + ShortRawIndex = ShortRawIndex - 1 + else + table.insert( RawsShortList, {SingleShortList[ShortIndex]}) + RawIndex = RawIndex + 1 + ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1 + end + end + + -- Ciclo fino ad esaurimento pezzi o barre + local dTotPartInRawLen = 0 + local nRawTot = 0 + local dRawTotLen = 0 + local dTime = 0 + local nCycle = 1 + local CurrResult = {} + while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do + + -- creo lista con pezzi lunghi e pezzi corti di questo Cycle + local PartsToNest = {} + for PartIndex = 1, #LongList do + table.insert( PartsToNest, LongList[PartIndex]) + end + for CycleIndex = 1, #RawsShortList do + if CycleIndex <= nCycle then + for PartIndex = 1, #RawsShortList[CycleIndex] do + table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex]) + end + end + end + + -- se non ci sono pezzi da nestare, esco + if PartsToFill( PartsToNest) <= 0 then + break + end + -- Eseguo ottimizzazione per ogni lunghezza di barra + local Results = {} + for RawIndex = 1, #TempRaws do + if TempRaws[RawIndex].Count > 0 then + Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest) + else + Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000} + end + end + -- verifico quale e' quella con meno scarto + local nMinWasteRawIndex = GDB_ID.NULL + local dMinWaste = 100000 + for ResultIndex = 1, #Results do + if Results[ResultIndex] then + local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill + if dWaste < dMinWaste then + dMinWaste = dWaste + nMinWasteRawIndex = ResultIndex + end + end + end + -- verifico se ci sono pezzi + if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then + -- riporto barra e pezzi nel risultato corrente + local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}} + local CurrX = TempRaws[nMinWasteRawIndex].StartGap + local nInfoIndex = 1 + for i = 1, Results[nMinWasteRawIndex].DiffParts do + local PartIndex = Results[nMinWasteRawIndex].Data[i].Id + local PartId = PartsToNest[PartIndex].Id + local dLen = PartsToNest[PartIndex].Len + for j = 1, Results[nMinWasteRawIndex].Data[i].Count do + -- creo pezzo copia + CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX} + table.insert( CurrBar.Parts, CurrPart) + CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap + nInfoIndex = nInfoIndex + 1 + end + end + table.insert( CurrResult, CurrBar) + dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill) + nRawTot = nRawTot + 1 + dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill + -- Aggiorno per prossima iterazione + TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1 + for i = 1, Results[nMinWasteRawIndex].DiffParts do + local PartId = Results[nMinWasteRawIndex].Data[i].Id + PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count + end + else + -- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili + break + end + nCycle = nCycle + 1 + end + -- riporto risultato in lista + ResultList[Index] = dTotPartInRawLen + if not BestResult or not BestResultIndex or + ( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then + BestResult = CurrResult + BestResult.RawTotLen = dRawTotLen + BestResultIndex = Index end end --- Ciclo fino ad esaurimento pezzi o barre -local nRawTot = 0 -local dTime = 0 -local nCycle = 1 -while TotRawCount( Raws) > 0 and PartsToFill( Parts) > 0 do +local CycleCount = 0 + +local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1) +if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end +local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1) +if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end +local TargetRatio = 0.98 +local dTargetRatioLen = TargetRatio * dTotLen +if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end +local CurrTime = 0 + +local function NestSolutionFromSP( StartingPoint, OscillationStep) + -- ciclo sulle possibilita' da un punto di origine con uno step fisso + local CurrResultIndex = StartingPoint + NestSolutionByIndex( StartingPoint) + if OscillationStep == 0 then return end + local CycleIndex = 1 + local nOutOfBoundary = 0 + while nOutOfBoundary ~= 3 do + CurrTime = EgtStopCounter() / 1000 + if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end + if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end + -- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia + if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then + if bLogStat then EgtOutLog('Brake') end + break + end + local bCurrOutOfBoundary = false + if CurrResultIndex < 0 then + bCurrOutOfBoundary = true + if nOutOfBoundary == 2 then + nOutOfBoundary = 3 + else + nOutOfBoundary = 1 + end + end + if CurrResultIndex > #Parts then + bCurrOutOfBoundary = true + if nOutOfBoundary == 1 then + nOutOfBoundary = 3 + else + nOutOfBoundary = 2 + end + end + if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then + NestSolutionByIndex( CurrResultIndex) + if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end + if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end + CycleCount = CycleCount + 1 + end + CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep ) + CycleIndex = CycleIndex + 1 + end +end - -- creo lista pezzi con pezzi lunghi e pezzi corti di questo Cycle - local PartsToNest = {} - for PartIndex = 1, #LongList do - table.insert( PartsToNest, LongList[PartIndex]) +-- lancio calcolo +EgtStartCounter() +local StartingResult = floor( #Parts * 0.3) +if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end +--local Step = floor( #Parts / 10) * floor( log10( #Parts)) +local nDividendo = pow( 10, floor( log10( #Parts)) - 1) +nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10) +local Step = floor( #Parts / nDividendo) * floor( log10( #Parts)) +if bLogStat then EgtOutLog('Step: ' .. Step ) end +NestSolutionFromSP( StartingResult, Step) +if Step > 1 then + NestSolutionFromSP( StartingResult, 1) +end + +-- creo gruppi di lavorazione per risultato +for MachGroupIndex = 1, #BestResult do + local CurrMachGroup = BestResult[ MachGroupIndex] + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + nMachGroup = EgtAddMachGroup( MachGroupName) + EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen) + EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo( nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + -- Disegno i pezzi + for i = 1, #CurrMachGroup.Parts do + local CurrPart = CurrMachGroup.Parts[ i] + -- creo pezzo copia + local nPartDuploId = EgtDuploNew( CurrPart.PartId) + EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX) end - for CycleIndex = 1, #RawsShortList do - if CycleIndex <= nCycle then - for PartIndex = 1, #RawsShortList[CycleIndex] do - table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex]) - end - end - end - - -- se non ci sono pezzi da nestare, esco - if PartsToFill( PartsToNest) <= 0 then - break - end - -- Eseguo ottimizzazione per ogni lunghezza di barra - local Results = {} - for RawIndex = 1, #Raws do - if Raws[RawIndex].Count > 0 then - Results[RawIndex] = ExecMaximumFilling( Raws[RawIndex], PartsToNest) - else - Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000} - end - end - -- verifico quale e' quella con meno scarto - local nMinWasteRawIndex = GDB_ID.NULL - local dMinWaste = 100000 - for ResultIndex = 1, #Results do - if Results[ResultIndex] then - local dWaste = (1 - Results[ResultIndex].FillRatio) * Raws[ResultIndex].LenToFill - if dWaste < dMinWaste then - dMinWaste = dWaste - nMinWasteRawIndex = ResultIndex - end - end - end - -- verifico se ci sono pezzi - if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then - -- creo gruppo di lavorazione - local MachGroupName = NewMachGroupName() - nMachGroup = EgtAddMachGroup( MachGroupName) - EgtSetInfo( nMachGroup, "BARLEN", Raws[nMinWasteRawIndex].LenToFill) - EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL) - EgtSetInfo( nMachGroup, "AUTONEST", 1) - -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione - EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) - EgtSetInfo( nMachGroup, "PATTID", nMachGroup) - -- Disegno i pezzi - local CurrX = Raws[nMinWasteRawIndex].StartGap - local nInfoIndex = 1 - for i = 1, Results[nMinWasteRawIndex].DiffParts do - local PartIndex = Results[nMinWasteRawIndex].Data[i].Id - local PartId = PartsToNest[PartIndex].Id - local dLen = PartsToNest[PartIndex].Len - for j = 1, Results[nMinWasteRawIndex].Data[i].Count do - -- creo pezzo copia - local nPartDuploId = EgtDuploNew( PartId) - EgtSetInfo( nMachGroup, "PART" .. nInfoIndex, nPartDuploId .. "," .. CurrX) - CurrX = CurrX + dLen + Raws[nMinWasteRawIndex].MidGap - nInfoIndex = nInfoIndex + 1 - end - end - nRawTot = nRawTot + 1 - -- Aggiorno per prossima iterazione - Raws[nMinWasteRawIndex].Count = Raws[nMinWasteRawIndex].Count - 1 - for i = 1, Results[nMinWasteRawIndex].DiffParts do - local PartId = Results[nMinWasteRawIndex].Data[i].Id - PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count - end - end - nCycle = nCycle + 1 end -- creo grezzi per ogni gruppo di lavorazione local nRawCnt = 0 +local nRawTot = ResultList[BestResultIndex] _G.BEAM = {} BEAM.FILE = NEST.FILE BEAM.MACHINE = NEST.MACHINE From 8e037e0943a5ba4668f01869c55b5f0db56f41e4 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 28 Dec 2022 19:02:03 +0100 Subject: [PATCH 05/10] Feature/FindMirroredFeatures: - per le forature in doppio aggiunto controllo attivazione e lunghezza seconda punta --- LuaLibs/BeamExec.lua | 33 +++++++++++++++++++++++---------- LuaLibs/ProcessDrill.lua | 9 +++++++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index a5f5a8e..d402a87 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -955,7 +955,7 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) end -- se senza geometria (già disabilitato - if Proc.Flg == 0 then + if Proc.Flg == 0 and not Proc.Double then bOk = false -- se intestatura elseif Hcut.Identify( Proc) then @@ -1485,22 +1485,35 @@ local function IsFeatureMirrored( vProc, Proc, sFeatureType, b3Raw) local dLen = abs( EgtCurveThickness( AuxId)) local dMachiningDepth = dLen / 2 + BD.DRILL_OVERLAP -- verifico che l'utensile di foratura abbia indicato il suo doppio nelle note - local sDrilling = ML.FindDrilling( dDiam, dMachiningDepth, true, false, true) - if not sDrilling then sDrilling = ML.FindDrilling( dDiam, 0, true, false, true) end - if sDrilling then EgtMdbSetCurrMachining( sDrilling) end - local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') - -- verifico che l'utensile indicato abbia un diametro coerente con il foro - local dToolDoubleDiam = 0 - if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then - dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd') + local sDrilling, sType, dMaxDepth = ML.FindDrilling( dDiam, dMachiningDepth, true, false, true) + if not sDrilling then + sDrilling, sType, dMaxDepth = ML.FindDrilling( dDiam, 0, true, false, true) + dMachiningDepth = dMaxDepth or dMachiningDepth end - if dToolDoubleDiam < dDiam + 10 * GEO.EPS_SMALL and dToolDoubleDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then + local sToolDoubleName + if sDrilling and sType == 'Drill' and EgtMdbSetCurrMachining( sDrilling) then + EgtTdbSetCurrTool( EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)) + sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') + end + -- verifico le dimensioni dell'utensile indicato + local dToolDoubleDiam = 0 + local dMaxDepthDouble = 0 + if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) and EgtTdbGetCurrToolParam( MCH_TP.TYPE, 'd') == MCH_TY.DRILL_STD then + if EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) then + dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd') + dMaxDepthDouble = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + end + end + dMachiningDepth = min( dMachiningDepth, dMaxDepthDouble) + if abs( Proc.Flg) == 2 and dToolDoubleDiam < dDiam + 10 * GEO.EPS_SMALL and dToolDoubleDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then if Proc.Flg == -2 then vtExtr = vtExtr * -1 end if Proc.Fce ~= 0 then if AreSameVectorApprox( vtExtr, Y_AX()) then nDouble = 2 + Proc.MachDepthDouble = dMachiningDepth elseif AreSameVectorApprox( vtExtr, Z_AX()) and BD.DOWN_HEAD then nDouble = 3 + Proc.MachDepthDouble = dMachiningDepth elseif AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) or ( AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) and BD.DOWN_HEAD) then Proc.Flg = 0 end diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua index 8f5ffac..03a3156 100644 --- a/LuaLibs/ProcessDrill.lua +++ b/LuaLibs/ProcessDrill.lua @@ -399,7 +399,7 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) local dMaxElev local sMyWarn -- se c'è un taglio precedente di testa o coda in cui il foro "entra" devo ricalcolare i dati della foratura - if (( Proc.MachineAfterHeadCutId and vtExtr:getX() > 0) or ( Proc.MachineAfterTailCutId and vtExtr:getX() < 0)) then + if ( not Proc.Double or Proc.Double == 0) and(( Proc.MachineAfterHeadCutId and vtExtr:getX() > 0) or ( Proc.MachineAfterTailCutId and vtExtr:getX() < 0)) then local bIntersectionOk, _, vDistance = EgtLineSurfTmInters( ptCen, -vtExtr, Proc.MachineAfterHeadCutId or Proc.MachineAfterTailCutId, GDB_RT.GLOB) if bIntersectionOk then local dHoleToCutDistance = vDistance[1] @@ -469,6 +469,11 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto affondamento + if Proc.Double and Proc.Double > 0 and dDepth > Proc.MachDepthDouble + 10 * GEO.EPS_SMALL then + sMyWarn = 'Warning in double head drilling : depth (' .. EgtNumToString( dDepth, 1) .. ') reduced to (' .. EgtNumToString( Proc.MachDepthDouble, 1) .. ') to match H2 max tool depth' + dDepth = Proc.MachDepthDouble + dMaxElev = Proc.MachDepthDouble + end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- imposto il valore della distanza di sicurezza per l'attacco. Se il valore del db utensili è troppo basso lo alzo a 10. local dToolDbStartPos = EgtGetMachiningParam( MCH_MP.STARTPOS) @@ -486,7 +491,7 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) sUserNotes = sUserNotes .. 'Open=1;' end -- se lavorazione in doppio - if Proc.Double and Proc.Double > 0 and ( sType == 'Drill') then + if Proc.Double and Proc.Double > 0 then local sToolNameDouble = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'TOOLDOUBLE', 's') sUserNotes = sUserNotes .. 'DOUBLE=' .. Proc.Double .. ',' sUserNotes = sUserNotes .. sToolNameDouble .. ';' From b60c76e64bad2d203defd339432996972e01b058 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 28 Dec 2022 19:18:35 +0100 Subject: [PATCH 06/10] Feature/FindMirroredFeatures: - piccola correzione nel riconoscimento mortase specchiate --- LuaLibs/BeamExec.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index d402a87..6f101f2 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1402,18 +1402,18 @@ local function CheckMirrorDtMortise( Proc, ProcMirror, b3Raw, AuxId) local ptCenRaw = b3Raw:getCenter() -- controllo che il centro delle due mortase sia allineato e che queste siano equidistanti dalla mezzeria della trave if AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then - bIsMirror = vtDisplacement:getX() < 500 * GEO.EPS_SMALL and vtDisplacement:getZ() < 500 * GEO.EPS_SMALL and + bIsMirror = abs( vtDisplacement:getX()) < 500 * GEO.EPS_SMALL and abs( vtDisplacement:getZ()) < 500 * GEO.EPS_SMALL and ( abs( ptBC:getY() - ptCenRaw:getY()) - abs( ptBCMirror:getY() - ptCenRaw:getY())) < 500 * GEO.EPS_SMALL elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then - bIsMirror = vtDisplacement:getX() < 500 * GEO.EPS_SMALL and vtDisplacement:getY() < 500 * GEO.EPS_SMALL and + bIsMirror = abs( vtDisplacement:getX()) < 500 * GEO.EPS_SMALL and abs( vtDisplacement:getY()) < 500 * GEO.EPS_SMALL and ( abs( ptBC:getZ() - ptCenRaw:getZ()) - abs( ptBCMirror:getZ() - ptCenRaw:getZ())) < 500 * GEO.EPS_SMALL end -- controllo che le dimensioni dei due box siano le stesse - bIsMirror = abs( b3DtMrt:getDimX() - b3DtMrtMirror:getDimX()) < 500 * GEO.EPS_SMALL and + bIsMirror = bIsMirror and abs( b3DtMrt:getDimX() - b3DtMrtMirror:getDimX()) < 500 * GEO.EPS_SMALL and abs( b3DtMrt:getDimY() - b3DtMrtMirror:getDimY()) < 500 * GEO.EPS_SMALL and abs( b3DtMrt:getDimZ() - b3DtMrtMirror:getDimZ()) < 500 * GEO.EPS_SMALL -- controllo che l'asse delle due mortase sia allineato - bIsMirror = AreSameVectorApprox( vtAx, vtAxMirror) + bIsMirror = bIsMirror and AreSameVectorApprox( vtAx, vtAxMirror) end return bIsMirror end From 0ec9661d9aaad5090811654d68ee9b715cb36c39 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 28 Dec 2022 19:26:51 +0100 Subject: [PATCH 07/10] Feature/FindMirroredFeatures: - fix commenti --- LuaLibs/BeamExec.lua | 1 + LuaLibs/ProcessDrill.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 6f101f2..ec12c9d 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -38,6 +38,7 @@ -- 2022/09/28 I fori vengono sempre fatti prima delle tacche. -- 2022/09/29 Aggiunta la ricerca di feature specchiate, al momento solo per DtMortise, con le relative funzioni. -- 2022/12/23 Corrette rotazioni 90 deg per macchine con carico da destra. +-- 2022/12/28 Implementata gestione forature e code di rondine in doppio. -- Tabella per definizione modulo diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua index 03a3156..f4ec471 100644 --- a/LuaLibs/ProcessDrill.lua +++ b/LuaLibs/ProcessDrill.lua @@ -15,6 +15,7 @@ -- 2022/08/18 Aggiunta gestione macchine con testa da sotto e punta disabilitata. -- 2022/10/25 Nella funzione Split aggiunto il controllo che le facce di ingresso e uscita siano differenti (potrebbe succedere per fori molto corti). Modifica importatore in futuro. -- 2022/11/23 Aggiunta la gestione dei fori con angolo < 30 gradi, per i quali si usa la testa della macchina per accorciare l'utile di lavoro. +-- 2022/12/28 Implementata gestione forature in doppio -- Tabella per definizione modulo local ProcessDrill = {} From 8dddb4cc35980e2cb52a92bca0e7e96878c088a2 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 9 Jan 2023 10:34:58 +0100 Subject: [PATCH 08/10] Fix dopo merge --- LuaLibs/ProcessDtMortise.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/LuaLibs/ProcessDtMortise.lua b/LuaLibs/ProcessDtMortise.lua index 33bb986..a268f35 100644 --- a/LuaLibs/ProcessDtMortise.lua +++ b/LuaLibs/ProcessDtMortise.lua @@ -418,7 +418,6 @@ function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) if nSCC then EgtSetMachiningParam( MCH_MP.SCC, nSCC) end - local sUserNotes = '' -- dichiaro non si generano sfridi per VMill local sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' -- se lavorazione in doppio From 3c5faceedf7f75ef0028b098a484a933ed03f638 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 10 Jan 2023 16:46:55 +0100 Subject: [PATCH 09/10] BugFix: - in BeamLib.GetFaceWithMostAdj aggiunto controllo che la feature abbia almeno una faccia aperta --- LuaLibs/BeamLib.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index b2c8e42..a3dd126 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -495,6 +495,10 @@ end --------------------------------------------------------------------- function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- verifica che la superficie non sia chiusa e quindi non lavorabile + if EgtSurfIsClosed( nSurfId) then + return + end -- recupero il numero di facce local nFacCnt = EgtSurfTmFacetCount( nSurfId) if not dCosSideAng then From 2523475a06217fb53daef394b40d5d40be733cb7 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 10 Jan 2023 16:48:15 +0100 Subject: [PATCH 10/10] fix commenti --- LuaLibs/BeamLib.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index a3dd126..c0c165d 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -17,6 +17,7 @@ -- 2022/07/26 Aggiunta la funzione FindFaceBestOrientedAsAxis, precedentemente in ProcessLapJoint -- 2022/07/26 Alla funzione FindFaceBestOrientedAsAxis aggiunta la possibilità di escludere una faccia dalla ricerca -- 2022/09/01 Aggiunte le funzioni GetTunnelDimension, CalcCollisionSafety, SetOpenSide, precedentemente in ProcessLapJoint. +-- 2023/01/10 In GetFaceWithMostAdj aggiunta verifica che la feature abbia almeno una faccia aperta. -- Tabella per definizione modulo local BeamLib = {}