diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 0196e52..d0c1a28 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -522,6 +522,20 @@ end -- *** Eseguo simulazione con verifica collisione in cieco *** if ( WALL.FLAG == 0 and ( bToProcess or bToRecalc)) or WALL.FLAG == 3 or WALL.FLAG == 4 then EgtOutLog( ' +++ Simulating with collision check >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione local bSimOk, nErr, sErr = EgtSimulate() if not bSimOk then if nErr == MCH_SHE.INIT then diff --git a/LuaLibs/WProcessFreeContour.lua b/LuaLibs/WProcessFreeContour.lua index a63b380..6f388d6 100644 --- a/LuaLibs/WProcessFreeContour.lua +++ b/LuaLibs/WProcessFreeContour.lua @@ -1,8 +1,9 @@ --- ProcessFreeContour.lua by Egaltech s.r.l. 2022/01/13 +-- ProcessFreeContour.lua by Egaltech s.r.l. 2022/02/03 -- Gestione calcolo profilo libero per Pareti -- 2021/11/15 Penna e chiodature sono sempre riportate sulla faccia sopra anche se nel progetto sono sotto. -- 2021/12/10 In taglio con lama aggiunta gestione SCC per testa Gearbox. -- 2022/01/13 Aggiunta gestione massimo affondamento in Z anche per pulizia spigoli con fresa 60deg (WD.MAX_CLEAN_CRN60). +-- 2022/02/03 Corretto controllo massimo affondamento nella tavola. -- Tabella per definizione modulo local WPF = {} @@ -16,6 +17,8 @@ EgtOutLog( ' WProcessFreeContour started', 1) -- Dati local WD = require( 'WallData') local WM = require( 'WMachiningLib') +if WD.CHECK_MIN_Z_SAW == nil then WD.CHECK_MIN_Z_SAW = true end +if not WD.MIN_Z_SAW then WD.MIN_Z_SAW = 0 end if not WD.MAX_CLEAN_CRN60 then WD.MAX_CLEAN_CRN60 = 150 end local WHISK_OFFS = 0.1 local WHISK_SAFE = 5 @@ -1193,8 +1196,12 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd local dDepth = vFace[i].Width + WD.CUT_EXTRA dThick = vFace[i].Width local vtNz = vFace[i].Norm:getZ() - if vtNz < 0 then - dDepth = dDepth - dMillDiam * abs( vtNz) / sqrt( 1 - vtNz * vtNz) + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end end -- se affondamento superiore ai limiti della fresa if dDepth > dMaxDepth then @@ -1251,8 +1258,12 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd local dDepth = vFace[i].Width + WD.CUT_EXTRA dThick = vFace[i].Width local vtNz = vFace[i].Norm:getZ() - if vtNz < 0 then - dDepth = dDepth - dMillDiam * abs( vtNz) / sqrt( 1 - vtNz * vtNz) + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end end -- se affondamento superiore ai limiti della fresa if dDepth > dMaxDepth then @@ -1417,8 +1428,12 @@ local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAdd local dDepth = vFace[i].Width + WD.CUT_EXTRA dThick = vFace[i].Width local vtNz = vFace[i].Norm:getZ() - if vtNz < 0 then - dDepth = dDepth - dMillDiam * abs( vtNz) / sqrt( 1 - vtNz * vtNz) + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end end -- se affondamento superiore ai limiti della fresa if dDepth > dMaxDepth then @@ -1500,7 +1515,7 @@ local function AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) end EgtSetInfo( nMchId, 'Part', Proc.PartId) -- calcolo l'affondamento - local dDepth = vFace[i].Width + WD.CUT_EXTRA + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) dThick = vFace[i].Width -- se affondamento superiore ai limiti della sega a catena if dDepth > dMaxDepth then @@ -1549,7 +1564,7 @@ local function AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) end EgtSetInfo( nMchId, 'Part', Proc.PartId) -- calcolo l'affondamento - local dDepth = vFace[i].Width + WD.CUT_EXTRA + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) dThick = vFace[i].Width -- se affondamento superiore ai limiti della sega a catena if dDepth > dMaxDepth then @@ -1621,11 +1636,15 @@ local function AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick) local bGearbox = EgtGetInfo( EgtGetHeadId( sHead) or GDB_ID.NULL, 'Gearbox', 'b') -- aggiungo geometria EgtSetMachiningGeometry( { { Proc.Id, vFace[i].Fac}}) - -- assegno affondamento + -- calcolo l'affondamento local dDepth = vFace[i].Depth local vtNz = vFace[i].Norm:getZ() - if ( WD.CHECK_MIN_Z_SAW == nil or WD.CHECK_MIN_Z_SAW) and vtNz < 0 then - dDepth = dDepth - dSawThick * abs( vtNz) + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, -WD.MIN_Z_SAW) + else + dDepth = min( dDepth, -WD.MIN_Z_SAW + dSawThick * vtNz) + end end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- verifico se va invertita la direzione di lavorazione perchè faccia verso l'alto (angolo maggiore di 0.01 deg) diff --git a/LuaLibs/WProcessLapJoint.lua b/LuaLibs/WProcessLapJoint.lua index a003a49..2041f79 100644 --- a/LuaLibs/WProcessLapJoint.lua +++ b/LuaLibs/WProcessLapJoint.lua @@ -1,4 +1,4 @@ --- WProcessLapJoint.lua by Egaltech s.r.l. 2022/01/17 +-- WProcessLapJoint.lua by Egaltech s.r.l. 2022/02/03 -- Gestione calcolo mezzo-legno per Pareti -- 2021/08/27 DS Se tre o più facce con flag PCKT=1 forzo svuotatura con fresa (per Variant). -- 2021/08/29 DS Se svuotatura di fianco setto flag per farla dopo i tagli. @@ -7,6 +7,7 @@ -- 2021/11/29 DS Correzione lav.ni SideMill quando più profonde che larghe. -- 2022/01/04 DS Se U con fondo verso basso o alto non ci possono essere spigoli verticali da pulire. -- 2022/01/17 ES Migliorata scelta fresa per lavorazione di fianco sotto. +-- 2022/02/03 DS Gorge larga come gambo più sicurezza. -- Tabella per definizione modulo local WPL = {} @@ -1230,6 +1231,12 @@ local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV) if WD.GetChainSawBlockedAxis then sRot3Ang = WD.GetChainSawBlockedAxis( 1) end + -- Calcolo angoli iniziali suggeriti + local sStartAngs + if WD.GetChainSawStartAngs then + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + sStartAngs = WD.GetChainSawStartAngs( vtN2) + end -- Lati chiusi local bOpenStart = false local bOpenEnd = false @@ -1258,6 +1265,10 @@ local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV) EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) -- imposto angolo 3° asse rot EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- imposto angoli iniziali suggeriti + if sStartAngs then + EgtSetMachiningParam( MCH_MP.INITANGS, sStartAngs) + end -- imposto offset radiale local dOffs = ( i - 1) * dStep EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) @@ -1365,19 +1376,14 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) - local dElevToPiece = dElev local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) local dThick = min( dH, dV) local sMilling - -- verifico se ho lavorazione custom (lavorazione speciale) + -- se ho lavorazione custom if sCustomMach then sMilling = sCustomMach - -- ricalcolo l'elevazione della faccia dal pezzo finito - -- recupero l'ingombro della parete - local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) - dElevToPiece = WL.GetFaceElevation( Proc.Id, nFacet) + -- altrimenti la cerco else - -- recupero la lavorazione sMilling = WM.FindMilling( 'SideGroove') end if not sMilling then @@ -1397,7 +1403,17 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen - dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + end + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + end dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh end end @@ -1535,7 +1551,7 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) end - -- asseggno lato di lavoro seconda faccia + -- assegno lato di lavoro seconda faccia if bMachFromDn then nFace2ndFace = MCH_MILL_FU.ORTUP_BACK else @@ -1543,17 +1559,22 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d end end end + if not bEnablePreMill then + dExtraLongIni = 0 + dExtraLongEnd = 0 + end -- se ho abilitato la lavorazione di fresatura per garantire passaggio gambo utensile inserisco la lavorazione if bEnablePreMill then - -- calcolo di quanto deve essere largo e lungo il canale di fresatura - local dDimGorge = ( 0.5 * ( dMillDiam + dMillDiamTh)) - dElevToPiece + 2 + -- calcolo quanto deve essere largo e lungo il canale di fresatura + local dDistGorge = ( dMillDiam - dMillDiamTh) / 2 - WD.COLL_SIC + local dDimGorge = dMillDiamTh + 2 * WD.COLL_SIC -- se il materiale extra è inferiore della gola completa, ricalcolo la dimensione della gola -- per fare meno fresature inutili - if ( dElev - dElevToPiece) < dDimGorge then - dDimGorge = ( dElev - dElevToPiece) + 5 + if dElev + 2 * WD.COLL_SIC < dDistGorge + dDimGorge then + dDimGorge = max( dElev - dDistGorge + 2 * WD.COLL_SIC, 0) end -- calcolo extra allungamenti - local dExtraLongGorge = ( dMillDiamTh + 5) /2 + local dExtraLongGorge = ( dMillDiamTh + WD.COLL_SIC) / 2 -- recupero la lavorazione local sMillingGorge = WM.FindMilling( 'Gorge', nil, nil, nil, 80) if not sMillingGorge then @@ -1572,60 +1593,58 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d end end -- calcolo quanti passi devo fare in larghezza per scaricare l'area di impegno utensile - local nNumStep = ceil( ( dDimGorge - dMillDiamFirst) / ( dMillDiamFirst * 0.8)) + 1 + local nNumStep = ceil( ( dDimGorge - dMillDiamFirst) / ( dMillDiamFirst * 0.9)) + 1 local dC = 0 if ( nNumStep - 1) > 0 then dC = ( dDimGorge - dMillDiamFirst) / ( nNumStep - 1) else nNumStep = 1 end - -- inserisco lavorazione solo se ho la condizione per farlo - if bEnablePreMill then - local nNm = 0 - -- passi di allargamento - for i = 1, nNumStep do - nNm = nNm + 1 - -- inserisco la lavorazione di fresatura - local sNameGorge = 'Gorge_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) - local nMchFId = EgtAddMachining( sNameGorge, sMillingGorge) - if not nMchFId then - local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sMillingGorge - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) - -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.ADIR_ZP - if AreSameVectorApprox( vtN, Z_AX()) then - nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- imposto modo di lavorare la faccia - local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- imposto elevazione e step - local dStep = EgtGetMachiningParam( MCH_MP.STEP) - if dStep < GEO.EPS_SMALL then dStep = dMaxMat end - -- se sto lavorando la gola centrale setto l'elevazione e l'affondamento - if nSinglePass and nSinglePass == 0 then - local dZElev = b3Raw:getDimZ() - local dDepth = Proc.Box:getMax():getZ() - b3Raw:getMin():getZ() - EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dZElev, 3) .. ';') - EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) - end - EgtSetMachiningParam( MCH_MP.STEP, dStep) - -- aggiungo l'offset laterale - EgtSetMachiningParam( MCH_MP.OFFSR, ( dElevToPiece + (dC * (i-1)) + 1)) - -- aggiungo allungamenti iniziali e finali - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni + dExtraLongGorge) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd + dExtraLongGorge) - -- eseguo - if not EgtApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end + -- inserisco la lavorazione + local nNm = 0 + -- passi di allargamento + for i = 1, nNumStep do + nNm = nNm + 1 + -- inserisco la lavorazione di fresatura + local sNameGorge = 'Gorge_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) + local nMchFId = EgtAddMachining( sNameGorge, sMillingGorge) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sMillingGorge + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vtN:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto elevazione e step + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + if dStep < GEO.EPS_SMALL then dStep = dMaxMat end + -- se sto lavorando la gola centrale setto l'elevazione e l'affondamento + if nSinglePass and nSinglePass == 0 then + local dZElev = b3Raw:getDimZ() + local dDepth = Proc.Box:getMax():getZ() - b3Raw:getMin():getZ() + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dZElev, 3) .. ';') + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- aggiungo l'offset laterale + EgtSetMachiningParam( MCH_MP.OFFSR, ( dDistGorge + dC * ( i - 1))) + -- aggiungo allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni + dExtraLongGorge) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd + dExtraLongGorge) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr end end end @@ -1641,10 +1660,11 @@ local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, d -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.ADIR_ZP - if abs( vtN:getZ()) < GEO.EPS_SMALL then - nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) - end + --local nSCC = MCH_SCC.ADIR_ZP + --if abs( vtN:getZ()) < GEO.EPS_SMALL then + -- nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + --end + local nSCC = MCH_SCC.ADIR_NEAR EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto modo di lavorare la faccia local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) @@ -2120,6 +2140,10 @@ local function MakeTwoFaces( Proc, nRawId, b3Raw) -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola if bInsertMach then return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng) + else + local sErr = 'Error feature not machinable (dimensions)' + EgtOutLog( sErr) + return false, sErr end -- se altrimenti di fianco in alto elseif vtN[1]:getZ() > dMaxZVers or vtN[2]:getZ() > dMaxZVers then @@ -2298,7 +2322,7 @@ local function MakeMoreFaces( Proc, nRawId, b3Raw) bInsertMach = true bMakeFirstGroove = true end - -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione precedura da sgossatura gola + -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola -- e gola più grande o uguale spessore utensile if bInsertMach and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then local nSinglePass = 0 @@ -2316,9 +2340,29 @@ local function MakeMoreFaces( Proc, nRawId, b3Raw) end else -- fresatura (se definita) - local sMilling, _, dMaxMat, dDiam = WM.FindMilling( 'SideGroove') - if sMilling and dElev < dDiam / 2 - 30 and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then - return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw) + local sMilling = WM.FindMilling( 'SideGroove') + -- recupero i dati dell'utensile + local dMaxMat = 1000 + local dMaxDepthOnSide = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + local dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + if not dMaxDepthOnSide then + local dMillDiamTh = EgtTdbGetCurrToolThDiam() or 60 + dMaxDepthOnSide = ( dMillDiam - dMillDiamTh) / 2 + end + end + end + if sMilling and dElev < dMaxDepthOnSide and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then + return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling) -- altrimenti sega a catena else return MakeByChainSaw( Proc, nFacInd, nRawId, b3Raw, dElev, dH, dV) diff --git a/LuaLibs/WallExec.lua b/LuaLibs/WallExec.lua index 5725f39..9e4ff0b 100644 --- a/LuaLibs/WallExec.lua +++ b/LuaLibs/WallExec.lua @@ -401,7 +401,7 @@ local function ContainsStartName( nOperId, StartNames) end ------ Ordinamento dei tagli, delle fresature e delle forature ------- -local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName, sInfo, bExistInfo, bOneWay, bByTool) +local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName, sInfo, bExistInfo, bOneWay, bByTool, bByToolAngle) -- dichiarazione tabella local TabCut = {} -- Recupero gli identificativi delle lavorazioni e annullo eventuali allungamenti e Id di altre lavorazioni rappresentate @@ -424,6 +424,7 @@ local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName local sTUUID = '' local nToolType = 0 local nToolDiam = 0 + local nToolDir = 0 if bByTool then sTUUID = EgtGetMachiningParam( MCH_MP.TUUID) local sToolName = EgtTdbGetToolFromUUID( sTUUID) @@ -434,7 +435,13 @@ local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName sTUUID = '' end end - table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Tool=sTUUID, ToolType=nToolType, ToolDiam=nToolDiam}) + if bByToolAngle then + local nClId = EgtGetFirstNameInGroup( nOperId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + nToolDir = EgtIf( vtTool:getZ() > 0.999999, 1, 0) + end + table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Tool=sTUUID, ToolType=nToolType, ToolDiam=nToolDiam, ToolDir=nToolDir}) end end -- Passo alla operazione successiva @@ -443,7 +450,6 @@ local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName if bByTool then function ToolCompare(a,b) - local y = a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool if a.ToolType < b.ToolType then return true elseif a.ToolType == b.ToolType then @@ -452,21 +458,48 @@ local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName elseif a.ToolDiam == b.ToolDiam then if a.Tool < b.Tool then return true - else - return false + elseif a.Tool == b.Tool then + if bByToolAngle then + if a.ToolDir > b.ToolDir then + return true + elseif a.ToolDir == b.ToolDir then + return a.Mch < b.Mch + end + else + return a.Mch < b.Mch + end end end end return false --- return a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool end + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #TabCut do + for j = i + 1, #TabCut do + local bComp1 = ToolCompare( TabCut[i], TabCut[j]) + local bComp2 = ToolCompare( TabCut[j], TabCut[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', TabCut[i].Mch, TabCut[j].Mch)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + table.sort(TabCut, ToolCompare) -- table.sort(TabCut, function(a,b) return a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool end) local SupportTabCut = {} local nPrevTUUID = 0 + local nPrevTDirZ = 1 for i = 1, #TabCut do -- se tuuid uguale al precedente, lo aggiungo alla lista - if nPrevTUUID == TabCut[i].Tool then + if nPrevTUUID == TabCut[i].Tool and ( not bByToolAngle or nPrevTDirZ == TabCut[i].ToolDir) then table.insert( SupportTabCut, TabCut[i]) -- se tuuid diverso, else @@ -475,6 +508,9 @@ local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName -- cancello la lista e aggiorno tuuid corrente SupportTabCut = {} nPrevTUUID = TabCut[i].Tool + if bByToolAngle then + nPrevTDirZ = TabCut[i].ToolDir + end table.insert( SupportTabCut, TabCut[i]) end end @@ -511,7 +547,7 @@ local function SortMachinings( nPhase, PrevMch, nPartId) -- Fresature per gole PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Gorge_'}, true, 'MOVE_AFTER', false) -- Fresature che sono rifiniture di spigoli - PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true) + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true, true) -- Fresature che sono puliture di spigoli PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, true, 'MOVE_AFTER', false) -- Tagli con lama diff --git a/NestProcess.lua b/NestProcess.lua index b009c39..c3d2cfd 100644 --- a/NestProcess.lua +++ b/NestProcess.lua @@ -375,10 +375,12 @@ local function ComputeToolOutlines( nPartId) end -local function ClassifyDrillsOnLateralFaces( nPartId) +local function ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) + local dDeltaRaw = WD.MAX_WIDTH - dMinSheetWidth + NEST.KERF local DrillClassif - local DrillOnFaces = { F = {nbr = 0, closed = false, long = false}, B = {nbr = 0, closed = false, long = false}, L = {nbr = 0, closed = false, long = false}, R = {nbr = 0, closed = false, long = false}} + local DrillOnFaces = { F = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, B = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, + L = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, R = {nbr = 0, closed = false, long = false, OnlyOnRef = false}} local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) @@ -398,15 +400,19 @@ local function ClassifyDrillsOnLateralFaces( nPartId) local ptDrill = EgtCP( AuxId, GDB_RT.GLOB) local dLen = abs( EgtCurveThickness( AuxId)) local bLong = dLen > WD.HOR_DRILL_LEN - 1 + local bOnlyOnRef = dLen + dDeltaRaw > WD.HOR_DRILL_LEN - GEO.EPS_SMALL and not bLong -- faccia Front local dTol = GEO.EPS_SMALL if ( abs( ptDrill:getY() - ptPartMin:getY()) < dTol) then - DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end if bOpen then DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end else - DrillOnFaces.F.closed = true + DrillOnFaces.F.closed = true + end if bLong then DrillOnFaces.F.long = true @@ -415,11 +421,13 @@ local function ClassifyDrillsOnLateralFaces( nPartId) -- faccia Back elseif ( abs( ptDrill:getY() - ptPartMax:getY()) < dTol) then - DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end if bOpen then - DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end else - DrillOnFaces.B.closed = true + DrillOnFaces.B.closed = true end if bLong then DrillOnFaces.B.long = true @@ -428,11 +436,13 @@ local function ClassifyDrillsOnLateralFaces( nPartId) -- faccia Left elseif ( abs( ptDrill:getX() - ptPartMin:getX()) < dTol) then - DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end if bOpen then - DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end else - DrillOnFaces.L.closed = true + DrillOnFaces.L.closed = true end if bLong then DrillOnFaces.L.long = true @@ -442,10 +452,12 @@ local function ClassifyDrillsOnLateralFaces( nPartId) -- faccia Right elseif ( abs( ptDrill:getX() - ptPartMax:getX()) < dTol) then DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end if bOpen then - DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end else - DrillOnFaces.R.closed = true + DrillOnFaces.R.closed = true end if bLong then DrillOnFaces.R.long = true @@ -460,20 +472,62 @@ local function ClassifyDrillsOnLateralFaces( nPartId) -- identifico la faccia da mettere sul lato del grezzo local sDrillFace, nMax = '', -100 for k, v in pairs( DrillOnFaces) do - if v.nbr > nMax then - sDrillFace, nMax = k, v.nbr + if v.nbr > nMax or ( v.nbr == nMax and not DrillOnFaces[sDrillFace].OnlyOnRef and v.OnlyOnRef) then + sDrillFace, nMax = k, v.nbr end end + local sDrillFace2 + if nMax > 0 then + if sDrillFace == 'F' or sDrillFace == 'B' then + -- cerco chi vince tra faccia left e right + if DrillOnFaces.L.nbr > DrillOnFaces.R.nbr then + sDrillFace2 = 'L' + elseif DrillOnFaces.L.nbr < DrillOnFaces.R.nbr then + sDrillFace2 = 'R' + elseif DrillOnFaces.L.nbr == DrillOnFaces.R.nbr and DrillOnFaces.L.nbr > 0 then + if DrillOnFaces.L.OnlyOnRef then + sDrillFace2 = 'L' + else + sDrillFace2 = 'R' + end + end + + else + -- cerco chi vince tra faccia front e back + if DrillOnFaces.F.nbr > DrillOnFaces.B.nbr then + sDrillFace2 = 'F' + elseif DrillOnFaces.F.nbr < DrillOnFaces.B.nbr then + sDrillFace2 = 'B' + elseif DrillOnFaces.F.nbr == DrillOnFaces.B.nbr and DrillOnFaces.F.nbr > 0 then + if DrillOnFaces.F.OnlyOnRef then + sDrillFace2 = 'F' + else + sDrillFace2 = 'B' + end + end + end + end + + if NEST.DRILL_MACH_AREA == 0 then DrillOnFaces[sDrillFace].long = false end if nMax > 0 then - DrillClassif = { sCase = sDrillFace, bClosed = DrillOnFaces[sDrillFace].closed, bLong = DrillOnFaces[sDrillFace].long} + DrillClassif = { sCase = sDrillFace, bClosed = DrillOnFaces[sDrillFace].closed, bLong = DrillOnFaces[sDrillFace].long, bOnlyOnRef = DrillOnFaces[sDrillFace].OnlyOnRef } end + + local DrillClassif2 + if sDrillFace2 then + if NEST.DRILL_MACH_AREA == 0 then + DrillOnFaces[sDrillFace2].long = false + end + DrillClassif2 = { sCase = sDrillFace2, bClosed = DrillOnFaces[sDrillFace2].closed, bLong = DrillOnFaces[sDrillFace2].long, bOnlyOnRef = DrillOnFaces[sDrillFace2].OnlyOnRef } + end + - return DrillClassif + return DrillClassif, DrillClassif2 end local function ClassifyLapJointsFromBottom( nPartId) @@ -673,11 +727,12 @@ end -- Funzione che classifica i pezzi in base alla loro necessità di stare negli angoli -local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot) +local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot, dMinSheetWidth) -- elimino eventuali info EgtSetInfo( nPartId, "NestOnEdge", 0) EgtSetInfo( nPartId, "NestOnAngle", 0) + EgtSetInfo( nPartId, "OnlyOnRefSide", 0) local nAngle local nRotate = 0 @@ -686,15 +741,18 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot) local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) -- fori - local DrillClassif = ClassifyDrillsOnLateralFaces( nPartId) + local DrillClassif, DrillClassif2 = ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) local bDrill = false local bDrillOpen = false - local bLongDrill = false + local bLongDrill = false if DrillClassif then bDrill = true bDrillOpen = not DrillClassif.bClosed bLongDrill = DrillClassif.bLong + if DrillClassif.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end end -- oriento il pezzo in base al foro @@ -718,8 +776,20 @@ local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot) -- ritorno nella posizione originaria EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), - RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) nRotate = nRotate - RotationAngles[DrillClassif.sCase] - -- dimentico di avere il foro - bDrill = false + -- se ho un'altra posizione possibile ruoto in quella + if DrillClassif2 then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif2.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif2.sCase] + bDrillOpen = not DrillClassif2.bClosed + bLongDrill = DrillClassif2.bLong + if DrillClassif2.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + else + -- dimentico di avere il foro + bDrill = false + end + end end @@ -962,8 +1032,9 @@ local function ComputeRestrictedZones( RawParts) end end - dMaxSheetWidth = -100 - nMaxSheet = 1 + local dMaxSheetWidth = -100 + local nMaxSheet = 1 + local dMinSheetWidth = WD.MAX_WIDTH for nInd = 1, #RawParts do local dSheetArea = RawParts[nInd].Len * RawParts[nInd].Width if RawParts[nInd].Width > dMaxSheetWidth + GEO.EPS_SMALL then @@ -974,6 +1045,9 @@ local function ComputeRestrictedZones( RawParts) nMaxSheet = nInd end end + if RawParts[nInd].Width < dMinSheetWidth then + dMinSheetWidth = RawParts[nInd].Width + end vSheetNbrEstimate[nInd] = min( ceil( dTotArea * vRawDistrib[nInd] / dSheetArea) + nSheetNbrCorrection, RawParts[nInd].Qty) if vSheetNbrEstimate[nInd] <= 0 then @@ -994,7 +1068,7 @@ local function ComputeRestrictedZones( RawParts) for nPartId, nCount in pairs( PART) do nPartIndex = nPartIndex + 1 local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') - local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER, bManualRot) + local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER, bManualRot, dMinSheetWidth) if PartClassif then for nI = 1, nCount do local newTab = {PartId = PartClassif.PartId, Angle = PartClassif.Angle, nRotate = PartClassif.nRotate, bDrill = PartClassif.bDrill, bLongDrill = PartClassif.bLongDrill, bManual = PartClassif.bManual} @@ -1059,8 +1133,10 @@ local function ComputeRestrictedZones( RawParts) local bOnOppositeSide = false for nInd2 = 1, #vManuallyDone do -- verifico se il pezzo può stare sull'altro angolo - local bCanBeOnOtherAngle = not AngleClassification[nInd].bDrill or - ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and RawParts[vManuallyDone[nInd2].RawPartId].Width >= WD.MINRAWY_HOR_DRILL) + local bOnlyOnRef = EgtGetInfo( AngleClassification[nInd].PartId, "OnlyOnRefSide", 'b') + local bCanBeOnOtherAngle = not bOnlyOnRef and + ( not AngleClassification[nInd].bDrill or + ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and RawParts[vManuallyDone[nInd2].RawPartId].Width >= WD.MINRAWY_HOR_DRILL)) if #(vManuallyDone[nInd2].Parts) == 0 then -- verifico che il pezzo stia in questo grezzo @@ -1079,7 +1155,8 @@ local function ComputeRestrictedZones( RawParts) if WD.ORIG_CORNER == 'BL' then sRefOrig = 'TL' end if WD.ORIG_CORNER == 'TR' then sRefOrig = 'BR' end if WD.ORIG_CORNER == 'BR' then sRefOrig = 'TR' end - local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig) + local bManTmp + local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig, bManTmp, dMinSheetWidth) -- verifico sia compatibile con pezzo già inserito local b3OtherPart = EgtGetBBoxGlob( vManuallyDone[nInd2].Parts[1].Id, GDB_BB.STANDARD) local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD) @@ -1599,7 +1676,16 @@ local function AddParts(RawParts, vPartsDoneManually) end -- vincolo StripY - EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, dRawMaxWidth - 2 * ( NEST.KERF + dval)) + local bOnlyOnRefSide = EgtGetInfo( nPartId, "OnlyOnRefSide", 'b') + if bOnlyOnRefSide then + if WD.ORIG_CORNER == 'BL' or WD.ORIG_CORNER == 'BR' then + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, 100000) + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, - 1000, dRawMaxWidth + 1000 - ( NEST.KERF + dval - dStripYCorr)) + end + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, dRawMaxWidth - 2 * ( NEST.KERF + dval)) + end -- se sull'angolo aggiungo anche vincolo StripX if bOnAngle then @@ -1855,7 +1941,7 @@ if bNestingOk then local nPartFlip = EgtGetInfo( nId, "INVERTED", 'i') nPartFlip = EgtIf( nPartFlip == 180, 1, 0) - local nTotFlip = nPartFlip ~ nFlag + local nTotFlip = EgtIf( nPartFlip ~ nFlag, 180, 0) EgtSetInfo( nPartDuploId, "FLIP", nTotFlip) end