From 75cafdbc9c137aecaaf0d485c8d13791b2676ab3 Mon Sep 17 00:00:00 2001 From: DarioS Date: Thu, 9 Sep 2021 17:46:53 +0200 Subject: [PATCH] DataBeam : - modifiche per tagli longitudinali anche limitati con lama. --- LuaLibs/ProcessLapJoint.lua | 126 ++-- LuaLibs/ProcessLongCut.lua | 1038 ++++++++++++++++++++++++++---- LuaLibs/ProcessLongDoubleCut.lua | 359 ++++++++--- 3 files changed, 1279 insertions(+), 244 deletions(-) diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 80a4032..a84701e 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -1,4 +1,4 @@ --- ProcessLapJoint.lua by Egaltech s.r.l. 2021/08/30 +-- ProcessLapJoint.lua by Egaltech s.r.l. 2021/09/08 -- Gestione calcolo mezzo-legno per Travi -- 2019/10/08 Agg. gestione OpenPocket. -- 2021/01/24 Con sega a catena ora sempre impostato asse A. @@ -19,7 +19,8 @@ -- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto). -- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q. -- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli. --- 2021/07/15 Aggiunti anctischeggia con fresa. +-- 2021/07/15 Aggiunti antischeggia con fresa. +-- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura) -- Tabella per definizione modulo local ProcessLapJoint = {} @@ -40,18 +41,19 @@ local BD = require( 'BeamData') local ML = require( 'MachiningLib') -- variabili assegnazione parametri Q -local Q_FORCE_BLADE = '' -- i -local Q_DEPTH_CHAMFER = '' -- d -local Q_ONLY_CHAMFER = '' -- i -local Q_USE_MILL = '' -- i -local Q_USE_ROUGH_TOOL = '' -- i -local Q_USE_ROUGH_TOOL_B90 = '' -- i -local Q_USE_ROUGH_TOOL_B0 = '' -- i -local Q_BORE_ON_CORNER = '' -- 1 -local Q_CONTOUR_SMALL_TOOL = '' -- i -local Q_ONLY_CONTOUR = '' -- i -local Q_SIDE_ROUGH_TOOL = '' -- i -local Q_ANTISPLINT_TYPE = '' -- i +local Q_FORCE_BLADE = '' -- i +local Q_DEPTH_CHAMFER = '' -- d +local Q_ONLY_CHAMFER = '' -- i +local Q_USE_MILL = '' -- i +local Q_USE_ROUGH_TOOL = '' -- i +local Q_USE_ROUGH_TOOL_B90 = '' -- i +local Q_USE_ROUGH_TOOL_B0 = '' -- i +local Q_BORE_ON_CORNER = '' -- 1 +local Q_CONTOUR_SMALL_TOOL = '' -- i +local Q_ONLY_CONTOUR = '' -- i +local Q_SIDE_ROUGH_TOOL = '' -- i +local Q_ANTISPLINT_TYPE = '' -- i +local Q_BLADE_ON_ALONG_FACE = '' -- i -- variabile smussi local bMadeChamfer @@ -93,34 +95,35 @@ local function AssignQIdent( Proc) Q_ANTISPLINT_TYPE = '' if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then - Q_FORCE_BLADE = 'Q01' -- i - Q_DEPTH_CHAMFER = 'Q04' -- d - Q_ONLY_CHAMFER = 'Q05' -- i + Q_FORCE_BLADE = 'Q01' -- i + Q_DEPTH_CHAMFER = 'Q04' -- d + Q_ONLY_CHAMFER = 'Q05' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then - Q_DEPTH_CHAMFER = 'Q01' -- d - Q_ONLY_CHAMFER = 'Q02' -- i + Q_DEPTH_CHAMFER = 'Q01' -- d + Q_ONLY_CHAMFER = 'Q02' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then - Q_DEPTH_CHAMFER = 'Q01' -- d - Q_USE_MILL = 'Q02' -- i - Q_USE_ROUGH_TOOL = 'Q03' -- i - Q_USE_ROUGH_TOOL_B90 = 'Q04' -- i - Q_USE_ROUGH_TOOL_B0 = 'Q05' -- i - Q_BORE_ON_CORNER = 'Q06' -- i + Q_DEPTH_CHAMFER = 'Q01' -- d + Q_USE_MILL = 'Q02' -- i + Q_USE_ROUGH_TOOL = 'Q03' -- i + Q_USE_ROUGH_TOOL_B90 = 'Q04' -- i + Q_USE_ROUGH_TOOL_B0 = 'Q05' -- 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 + Q_BORE_ON_CORNER = 'Q01' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then - Q_CONTOUR_SMALL_TOOL = 'Q01' -- i - Q_ONLY_CONTOUR = 'Q02' -- i - Q_SIDE_ROUGH_TOOL = 'Q03' -- i - Q_ANTISPLINT_TYPE = 'Q06' -- i - Q_DEPTH_CHAMFER = 'Q07' -- d + Q_CONTOUR_SMALL_TOOL = 'Q01' -- i + Q_ONLY_CONTOUR = 'Q02' -- i + Q_SIDE_ROUGH_TOOL = 'Q03' -- i + Q_BLADE_ON_ALONG_FACE = 'Q04' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i + Q_DEPTH_CHAMFER = 'Q07' -- d elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then - Q_SIDE_ROUGH_TOOL = 'Q01' -- i - Q_CONTOUR_SMALL_TOOL = 'Q02' -- i - Q_ANTISPLINT_TYPE = 'Q06' -- i + Q_SIDE_ROUGH_TOOL = 'Q01' -- i + Q_CONTOUR_SMALL_TOOL = 'Q02' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then - Q_CONTOUR_SMALL_TOOL = 'Q01' -- i - Q_ANTISPLINT_TYPE = 'Q06' -- i + Q_CONTOUR_SMALL_TOOL = 'Q01' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i end -- le altre features gestite non hanno parametri Q end @@ -4967,11 +4970,13 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) AssignQIdent( Proc) -- se non forzate frese, uso la lama local bUseBlade = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') ~= 1 and EgtGetInfo( Proc.Id, Q_USE_MILL, 'i') ~= 1 + 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 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 -- se antischeggia di fresa o abilitato sgrossatore di fianco if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then bUseBlade = false @@ -4998,7 +5003,15 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) ( Proc.Box:getDimX() > 0.8 * b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then -- una faccia if Proc.Fct == 1 then - return LongCut.Make( Proc, nPhase, nRawId, nPartId) + if bUseBlade then + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end -- due facce elseif Proc.Fct == 2 then -- determino se due facce lunghe oppure una lunga e l'altra terminale @@ -5013,13 +5026,21 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- la faccia 0 deve essere quella lunga EgtSurfTmSwapFacets( Proc.Id, 0, 1) if bUseBlade then - return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + end else return LongCut.Make( Proc, nPhase, nRawId, nPartId) end elseif b3Fac2:getDimX() < 1 then if bUseBlade then - return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + end else return LongCut.Make( Proc, nPhase, nRawId, nPartId) end @@ -5030,7 +5051,32 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) end end - -- tre o più facce + -- tre facce + elseif Proc.Fct == 3 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD) + local bApplyBladeOnLongNotContinueFace + + if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then + bApplyBladeOnLongNotContinueFace = true + end + + if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + -- più facce else return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) end diff --git a/LuaLibs/ProcessLongCut.lua b/LuaLibs/ProcessLongCut.lua index 5e77af1..9d1c54e 100644 --- a/LuaLibs/ProcessLongCut.lua +++ b/LuaLibs/ProcessLongCut.lua @@ -1,7 +1,11 @@ --- ProcessLongCut.lua by Egaltech s.r.l. 2021/05/18 +-- ProcessLongCut.lua by Egaltech s.r.l. 2021/09/08 -- Gestione calcolo taglio longitudinale per Travi -- 2021/02/03 Corretto FaceUse con fresa orizzontale su taglio orizzontale. -- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto. +-- 2021/07/20 Possibile taglio con lama anche di fianco e da sotto su macchina con testa da sopra. +-- 2021/07/20 Con utensile di fianco e con determinati angoli e se altezza utensile è inferiore all'altezza faccia +-- è possibile fare doppio taglio opposto su tutte le facce(sopra, sotto e fianchi) +-- 2021/09/03 Gestione facce lunghe non passanti con taglio di lama -- Tabella per definizione modulo local ProcessLongCut = {} @@ -38,50 +42,230 @@ function ProcessLongCut.Classify( Proc) return true, false end ---------------------------------------------------------------------- -local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, bForcedLim) +----------------------------------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, bForcedLim, dDistToMachine, bUnderDir) -- inserisco la lavorazione - local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) - local nMchFId = EgtAddMachining( sNameF, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + local nM = 1 + local nP = 1 + local nFirstOverlap = 2 + -- calcolo il numero di passata che devo fare per coprire l'impronta dells lama + if dDistToMachine and abs(dDistToMachine) > 0 then + nP = ceil( ( abs(dDistToMachine) + EgtIf( bForcedLim, 2 + nFirstOverlap, 2)) / ( dToolDiam - 2)) + end + for i = 1, nP do + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- uso della faccia + local nFaceUse + if bForcedLim then + nFaceUse = MCH_MILL_FU.ORTHO_LEFT + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + nFaceUse = EgtIf( bUnderDir, MCH_MILL_FU.PARAL_TOP, MCH_MILL_FU.PARAL_DOWN) + if nSide == -2 then + nFaceUse = MCH_MILL_FU.PARAL_BACK + elseif nSide == 2 then + nFaceUse = MCH_MILL_FU.PARAL_FRONT + end + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- modifico offset radiale + if i < nP or i == 1 then + EgtSetMachiningParam( MCH_MP.OFFSR, ((dToolDiam-2)*(i-1)) + EgtIf( bForcedLim, -nFirstOverlap, 0)) + else + local dPrevStep = (dToolDiam-2)*(i-2) + EgtSetMachiningParam( MCH_MP.OFFSR, ( dDistToMachine + 2 - dToolDiam)) + end + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sMasterCutting) + -- Recupero la lavorazione di lama o prendo quella passata + local sCutting + if sMasterCutting and #sMasterCutting > 0 then + sCutting = sMasterCutting + else + sCutting = ML.FindCutting( 'HeadSide' .. EgtIf( bMillDown, '_H2', '')) + end + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' EgtOutLog( sErr) return false, sErr end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ nId, nFac}}) - -- uso della faccia - local nFaceUse - if bForcedLim then - nFaceUse = MCH_MILL_FU.ORTHO_LEFT - -- lato di lavoro e inversione - EgtSetMachiningParam( MCH_MP.INVERT, false) - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - else - nFaceUse = MCH_MILL_FU.PARAL_DOWN - if nSide == -2 then - nFaceUse = MCH_MILL_FU.PARAL_BACK - elseif nSide == 2 then - nFaceUse = MCH_MILL_FU.PARAL_FRONT + -- valuto l'angolo tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + local ptPm = (ptP1+ptP2)/2 + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia + -- laterale sul punto medio della linea in comune + local frFc = Frame3d( ptPm, vtN) ; + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + dDepth = b3BoxLoc:getDimZ() or 0 + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end - -- lato di lavoro e inversione - EgtSetMachiningParam( MCH_MP.INVERT, true) - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) end - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- annullo offset radiale - EgtSetMachiningParam( MCH_MP.OFFSR, 0) - -- attacco e uscita - EgtSetMachiningParam( MCH_MP.LIPERP, 0) - EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) - EgtSetMachiningParam( MCH_MP.LOPERP, 0) - EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) - -- eseguo - if not EgtApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr + local dExtraOffs = 0 + -- se profondità superiore al massimo lama modifico elevazione + if dDepth > dMaxDepth then + dExtraOffs = dMaxDepth - dDepth end + -- se devo ridurre l'affondamento + if bReduceDepth then + local dLimitDepth = 100 + -- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm) + if abs(dExtraOffs) > 0 then + if dMaxDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + end + else + if dDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + else + dExtraOffs = - (dDepth/2) + end + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if bMadeASbyBld then + sWarn = nil + if abs(dExtraOffs) > 0 then + sWarn = 'Warning : antisplint elevation is bigger than max tool depth' + end + end + return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs +end + +--------------------------------------------------------------------- +local function ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacet, nFacInd, sWarn, bMillDown, bReduceDepth, sCutting) + + local bMadeASbyBld = false + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + local nPrevSCC = nil + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + -- lavoro + local dSawThick = 0 + local dMaxDepth = 200 + local bAdj, dAng, dExtraOffs, sWarn2, nIdMach + bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sCutting) + if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- se antischeggia veramente inserito perchè necessario + if nIdMach then + -- verifico se da invertire + local bInvertMach = false + local dDepth = 0 + if bIsU then + if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then +-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + -- eseguo inversione + if bInvertMach then + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) + local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- assegno i parametri invertiti + EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + end + -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto + if not nPrevSCC then + nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) + else + EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) + end + -- rieseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, false, sErr + end + end + end + end + + return bMadeASbyBld, true, sWarn end --------------------------------------------------------------------- @@ -145,7 +329,7 @@ end --------------------------------------------------------------------- -- Applicazione della lavorazione -function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade, nCustForceUseBladeOnNCF) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) @@ -167,6 +351,7 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) end end -- Verifico lato di lavorazione (limite di lato a 45deg per pinze che schiacciano) + -- 14.07.2021 su richieste di alcuni clienti, se taglio di lato (assegnazione +/- 2) fare lo stesso con la lama lasciando il cordone centrale local nSide = 1 if vtN:getZ() < - 0.5 then nSide = -1 @@ -188,15 +373,83 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) -- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del rggio utensile). -- Questo viene fatto se Q07=1 o fresa da sotto ---------------------------------------------------------------------------------------------------------------------------------------- - local bUseBlade = ( EgtGetInfo( Proc.Id, 'Q05', 'i') == 1) or bCustUseBlade - local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q07', 'i') or 0 + local nUseBlade = EgtIf( bCustUseBlade, 1, EgtGetInfo( Proc.Id, 'Q05', 'i') or 0) + local bForceUseBladeOnNotThruFace + if nCustForceUseBladeOnNCF then + bForceUseBladeOnNotThruFace = nCustForceUseBladeOnNCF > 2 + nUseBlade = EgtIf( nCustForceUseBladeOnNCF > 2, nCustForceUseBladeOnNCF-2, nCustForceUseBladeOnNCF) + else + -- bForceUseBladeOnNotThruFace = EgtGetInfo( Proc.Id, 'Q06', 'b') or false + -- non viene più usato un nuovo Q (Q06) ma dipende dal valore del Q05 + -- con nuovi valori 3: come 1 ma con forza lama su facce chiuse; 4: come 2 ma con forza lama su facce chiuse + if nUseBlade > 2 then + nUseBlade = nUseBlade - 2 + bForceUseBladeOnNotThruFace = true + end + end + -- se ho il parametro settato dal LapJoint (per ora è questo componente che setta questo parametro) allora setto a false l'uso della lama + -- perchè se ha questo parametro a true significa che la lama è forzata ad essere usata + local nUseMillOnSide + if nCustForceUseBladeOnNCF then + nUseMillOnSide = 0 + else + nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q07', 'i') or 0 + end -- se entrambe i Q sono attivi, disabilito lama - if nUseMillOnSide > 0 then bUseBlade = false end + if nUseMillOnSide > 0 then + nUseBlade = 0 + bForceUseBladeOnNotThruFace = false + end - -- Se non limitato e da sopra e richiesto con doppio taglio di lama e superiore al limite minimo - if not bLimXmin and not bLimXmax and ( nSide == 1 or ( nSide ~= -1 and BD.DOWN_HEAD)) and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then + local bCanUseBlade = false + local bCanUseUnderBlade = false + -- se lama abilitata per lavorare sopra e faccia da sopra + if nUseBlade == 1 and nSide == 1 then + bCanUseBlade = true + end + -- se lama abilitata per lavorare anche i fianchi e da sotto e non c'è testa da sotto + if nUseBlade == 2 and not BD.DOWN_HEAD then + if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.0175 then + bCanUseBlade = true + end + end + -- se lama abilitata per lavorare i fianche e da sotto e c'è testa da sotto + if nUseBlade == 2 and BD.DOWN_HEAD then + -- se faccia da sotto o di lato ma con versore Z negativo che supera i 30° da Z- + if ( nSide == -1 or abs(nSide) == 2) and vtN:getZ() <= -0.5 then + bCanUseUnderBlade = true + end + -- se faccia di lato ma con versore Z negativo verifico che abbia un angolo compatibile per non avere extracorsa + if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.0175 then + bCanUseBlade = true + end + end + + -- introduco messaggi di errore in caso sia settata la lama ma impossibile utilizzarla + -- se si toglie questa parte il processo continua utilizzandi però la fresa ma per il vincolo del parametro Q non è possibile + if nUseBlade == 2 and not BD.DOWN_HEAD and not bCanUseBlade then + local sErr = 'Error, impossible use blade on negative side face' + EgtOutLog( sErr) + return false, sErr + elseif nUseBlade == 1 and not bCanUseBlade then + local sErr = 'Error, impossible use blade' + EgtOutLog( sErr) + return false, sErr + elseif nUseBlade == 2 and BD.DOWN_HEAD and not bCanUseBlade and not bCanUseUnderBlade then + local sErr = 'Error, impossible use blade' + EgtOutLog( sErr) + return false, sErr + end + + -- Se non limitato o forzato uso lama e da sopra e richiesto con doppio taglio di lama e superiore al limite minimo + if ( ( not bLimXmin and not bLimXmax) or bForceUseBladeOnNotThruFace) and ( bCanUseUnderBlade or bCanUseBlade) and nUseBlade > 0 and b3Solid:getDimX() > dLimMinPiece - 1 then -- recupero la lavorazione - local sCutting = ML.FindCutting( 'HeadSide') + local sCutting + if bCanUseUnderBlade then + sCutting = ML.FindCutting( 'HeadSide_H2') + else + sCutting = ML.FindCutting( 'HeadSide') + end if not sCutting then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' EgtOutLog( sErr) @@ -205,21 +458,54 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) -- recupero i dati dell'utensile local dToolDiam = 0 local dMaxDepth = 0 + local dThick = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThick dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end - -- se la distanza dal pezzo successivo è inferiore della metà lama, dò un warning - if dDistToNextPiece < dToolDiam/2 then - sWarn = 'Warning on saw cut : Cut machining can damage next piece' - EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo meno distante di metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and not bLimXmin then + if bForceUseBladeOnNotThruFace then + bForcedLim = true + bLimXmin = true + else + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + end + -- disabilitato la selezione del codolo, prende sempre quello più piccolo. Non cancellare quello disabiliato in caso di ripristino +-- local dDimStrip = EgtIf( abs(nSide) == 1, BD.DIM_STRIP_SMALL, BD.DIM_STRIP) * EgtIf( nSide == -1, -1, 1) + local dDimStrip = BD.DIM_STRIP_SMALL * EgtIf( nSide == -1, -1, 1) + -- determino gli estremi + local dStartAccDist = BD.LONGCUT_ENDLEN + local dStartDist = 0 + local bStartFixed + local dEndAccDist = BD.LONGCUT_ENDLEN + local dEndDist = 0 + local bEndFixed + if bForceUseBladeOnNotThruFace then + bStartFixed = true + if bLimXmax then + local dRadius = dToolDiam / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dStartDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + bEndFixed = true + if bLimXmin then + local dRadius = dToolDiam / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dEndDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end end -- determino numero di parti - local dStartAccDist = BD.LONGCUT_ENDLEN - local dEndAccDist = BD.LONGCUT_ENDLEN local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) local dC = 0 if nC > 0 then @@ -242,19 +528,145 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) end end -- determino l'utilizzo della faccia - local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) local nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) -- si percorrono i lati alto e basso della faccia - local dDimStrip = EgtIf( nSide == 1, BD.DIM_STRIP_SMALL, BD.DIM_STRIP) + -- calcolo quanto è l'affondamento del taglio + local dOffset = ( dWidth + dDimStrip) / 2 + -- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama + if nSide == -1 then + if (( dWidth - dDimStrip) / 2) > dMaxDepth then + local sErr = 'Error, side depth is bigger than underneath blade cut depth' + EgtOutLog( sErr) + return false, sErr + end + end local nM = 0 + -- se abilitata la lavorazione di lama su faccia chiusa, aggiungo le eventuali lavorazioni di antischeggia + -- e di asporto dell'impronta lama + if bForceUseBladeOnNotThruFace and ( bLimXmin or bLimXmax) then + local nCountMilHead = 0 + -- determino la massima elevazione + local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + -- recupero la lavorazione + local sMilling + if bCanUseUnderBlade then + sMilling = ML.FindMilling( 'Long2Cut_H2', dElev) + else + sMilling = ML.FindMilling( 'Long2Cut', dElev) + end + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se ho facce di chiusura, per prima cosa faccio antischeggia + -- come richiesto da Fabio Squaratti il 03/09/2021 + if ( bLimXmin and not bForcedLim) or bLimXmax then + local bOk, nFacet + bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, (( bLimXmin and not bForcedLim) and bLimXmax), vtN, nFacet, 0, sWarn, bCanUseUnderBlade, nil, sCutting) + if not bOk then return false, sWarn end + end + -- eventuale lavorazione della faccia limitante l'inizio + if not bStartFixed then + local vtIni = -X_AX() + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtIni * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, dStartDist, bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 1 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, dStartDist, bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + + -- eventuale lavorazione della faccia limitante la fine + if not bEndFixed then + local vtFin = X_AX() + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtFin * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, dEndDist, bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 2 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, dEndDist, bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + end + -- inserisco tagli di lama for i = 1, nC do -- Posizione braccio portatesta local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) -- ciclo sulle passate - local dOffset = ( dWidth + dDimStrip) / 2 ; local dLioTang = 0 - local dLioPerp = ( dWidth - dDimStrip) / 2 + BD.CUT_SIC ; + for k = 1, 2 do + local dLioPerp = ( dWidth - dDimStrip) / 2 + BD.CUT_SIC ; + local bAddOpposite = true + local dAddExtraPerp = 0 + -- se faccia da sotto e angolo inferiore ai 12° o faccia di fianco e angolo inferiore a 15° (al di sotto di questo angolo + -- l'attacco lama si comporta in modo diverso) allora calcolo il valore perpendicolare perpendicolare con la funzione CalcLeadInOutPerpGeom + if ( nSide == -1 and abs(vtN:getY()) >= 0.2079) or ( abs(nSide) == 2 and abs(vtN:getZ()) >= 0.2588) then + bAddOpposite = false + end + -- faccio in modo di calcolare il valore perpendicolare solo sulla faccia da sotto nel secondo passo o sulla faccia di fianco nel primo passo + if nSide == 1 or ( nSide == -1 and k == 1) or ( abs(nSide) == 2 and k == 2) then + bAddOpposite = false + end + if bAddOpposite then + -- controllo se devo aggiungere un extra all'attacco perpendicolare + if nSide == -1 then + if vtN:getY() > 0 then + dAddExtraPerp = Proc.Box:getMin():getY() - b3Solid:getMin():getY() + elseif vtN:getY() < 0 then + dAddExtraPerp = b3Solid:getMax():getY() - Proc.Box:getMax():getY() + end + elseif abs(nSide) == 2 then + dAddExtraPerp = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + end + dLioPerp = dLioPerp + dAddExtraPerp + ------------------------------------------------------------------------------------------------------- + -- disabilito questo calcolo dell'attacco perpendiclare perchè in alcune condizioni genera extra corsa + ------------------------------------------------------------------------------------------------------- + --[[ + -- parametri di attacco/uscita + local nOrthoOpposite = nFaceUse2 + local b3Box = BBox3d( b3Raw) + b3Box:expand( BD.CUT_SIC) + -- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach) + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth2 = EgtSurfTmFacetOppositeSide( Proc.Id, 0, BL.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + -- Versore di riferimento + local vtRef = Vector3d( vtTg) + local dCutExtra = 0 + vtRef:rotate( vtN, EgtIf( bInvert, -90, 90)) + local ptP1act = ptP1 + local ptP2act = ptP2 + _, dLioPerp, _, _ = BL.CalcLeadInOutPerpGeom( ptP1act, ptP2act, vtV1, vtV2, vtN, dToolDiam/2, vtRef, dCutExtra, b3Box) + ]]-- + end -- inserisco le parti di lavorazione nM = nM + 1 local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) @@ -267,15 +679,30 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, 0}}) -- limito opportunamente la lavorazione - local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) - local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + local dSal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC) if ( not bFront and k == 1) or ( bFront and k == 2) then dSal, dEal = dEal, dSal end + -- se faccia da sotto inverto direzione utensile e profondità + -- if nSide == -1 then + -- if k == 1 and abs( vtN:getY()) > 0.01 and abs( vtN:getY()) <= 0.866 and abs( vtN:getY()) > 0.707 then + -- -- imposto lato di correzione + -- EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- else + -- EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- EgtSetMachiningParam( MCH_MP.DEPTH, dThick) + -- end + -- end + + if bCanUseUnderBlade then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) -- imposto offset radiale - EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( nSide == -1, -dOffset, dOffset)) -- imposto attacco/uscita EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) @@ -495,7 +922,7 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) nCountMilHead = nCountMilHead + 1 end end - -- altrimenti è sotto ( lavorazione Long2CutDown) o da sopra ma con fresa di fianco ( lavorazione Long2CutSide) + -- altrimenti è da sotto ( lavorazione Long2CutDown) o abilitata lavorazione con fresa di fianco ( lavorazione Long2CutSide) else -- da Analisi con Fabio Squaratti 15/09/2020 -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco @@ -506,7 +933,9 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) local nExtendMach -- recupero la lavorazione local sMilling + local sMillingDn local sPrefix + local sPrefixDn if nSide ~= - 1 then sMilling = ML.FindMilling( 'Long2CutSide') sPrefix = 'L2CS_' @@ -514,6 +943,11 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) if nUseMillOnSide == 2 then bRemoveToolRadius = true end + -- se testa da sotto + if nSide ~= 1 and BD.DOWN_HEAD then + sMillingDn = ML.FindMilling( 'Long2CutSide_H2') + sPrefixDn = 'L2CSH2_' + end -- lavorazione da sotto else sMilling = ML.FindMilling( 'Long2CutDown') @@ -522,38 +956,75 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) if nUseMillOnSide ~= 1 then nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) end + -- se testa da sotto + if BD.DOWN_HEAD then + sMillingDn = ML.FindMilling( 'Long2CutDown_H2') + sPrefixDn = 'L2CDH2_' + end end if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) return false, sErr end + if nSide ~= 1 and BD.DOWN_HEAD and not sMillingDn then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling H2 not found in library' + EgtOutLog( sErr) + return false, sErr + end -- recupero i dati dell'utensile local dToolDiam = 0 + local dToolLength = 0 local dMaxDepth = 0 local dThDiam = 0 + local dThLen = 0 + local dExtraForSafety = EgtIf( BD.DOWN_HEAD, 8.5, 6.5) -- corrisponde al doppio valore di sicurezza dell'mlpe + 0.5 +-- local dExtraForSafetyDn = 8.5 -- 8.5 -- corrisponde al doppio valore di sicurezza dell'mlpe + 0.5 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth - dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + dThDiam = ( EgtTdbGetCurrToolThDiam() or dThDiam) + dThLen = EgtTdbGetCurrToolThLength() or dThLen end end - local dDistToEnd = dToolDiam / 2 + -- recupero i dati dell'utensile da sotto + local dToolDiamDn = 0 + local dToolLengthDn = 0 + local dMaxDepthDn = 0 + local dThDiamDn = 0 + local dThLenDn = 0 + if nSide ~= 1 and BD.DOWN_HEAD and EgtMdbSetCurrMachining( sMillingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dToolLengthDn = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLengthDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + dThDiamDn = (EgtTdbGetCurrToolThDiam() or dThDiamDn) + dThLenDn = EgtTdbGetCurrToolThLength() or dThLenDn + end + end + + local dDistToEnd = dToolDiam / 2 + local dDistToEndDn = dToolDiamDn / 2 + -- calcolo l'elevazione della faccia principale + local dFacElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile if nUseMillOnSide <= 1 or nSide == -1 then - -- calcolo l'elevazione della faccia principale - local dFacElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) if dFacElev < dDistToEnd then dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) end + if dFacElev < dDistToEndDn then + dDistToEndDn = sqrt( ( ( dToolDiamDn / 2) * ( dToolDiamDn / 2)) - ( ( dToolDiamDn / 2 - dFacElev) * (dToolDiamDn / 2 - dFacElev))) + end end -- se la fine è già limitata allora setto per arretrare del raggio utensile if bLimXmin then nExtendMach = 0 -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata - elseif dDistToNextPiece < dDistToEnd and nExtendMach ~= 1 then + elseif ( dDistToNextPiece < dDistToEnd or dDistToNextPiece < dDistToEndDn) and nExtendMach ~= 1 then bLimXmin = true end -- larghezza faccia @@ -622,86 +1093,393 @@ function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) dEndAccDist = 0 end end + -- verifico se posso farlo da due parti opposte o da solo una parte + local dCollSic + local dCollSicMin + local dCollSicDn + local dCollSicMinDn + local dDepth + local dDepthDn + local dDepth2 + local dDepth2Dn + local nPass = 1 + local dNz = EgtIf( abs(nSide) == 1, vtN:getY(), vtN:getZ()) + local dNzMin = EgtIf( abs(vtN:getY()) >= abs(vtN:getZ()), vtN:getY(), vtN:getZ()) + -- se faccia da sopra e angolo 45° o faccia da sotto e angolo 40° (con singola testa ) o faccia non da sopra e testa da sotto + -- permette di eseguire due lavorazioni opposte + if ( nSide == 1 and abs(vtN:getY()) <= 0.7072) or ( nSide == -1 and not BD.DOWN_HEAD and abs(vtN:getY()) < 0.6428) or ( nSide ~= 1 and BD.DOWN_HEAD) then + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione + local dSicOnRad + local dSicOnLegth + if ( abs(nSide) == 1 and abs(vtN:getZ()) >= abs(vtN:getY())) or ( abs(nSide) == 2 and abs(vtN:getY()) >= abs(vtN:getZ())) then + dSicOnRad = ( dThDiam + dExtraForSafety - dToolDiam) / 2 + dSicOnLegth = 0 + else + dSicOnRad = ( dThDiam - dToolDiam) / 2 + dSicOnLegth = dExtraForSafety / 2 + end + dCollSicMin = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNzMin) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN:getY()) >= abs(vtN:getZ()), vtN:getZ(), vtN:getY()) / dNzMin))) + dCollSic = max( BD.COLL_SIC, dSicOnRad * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(nSide) == 1, vtN:getZ(), vtN:getY()) / dNz)) + dSicOnLegth) + if nSide ~= 1 and BD.DOWN_HEAD then + local dSicOnRadDn + local dSicOnLegthDn + if ( abs(nSide) == 1 and abs(vtN:getZ()) >= abs(vtN:getY())) or ( abs(nSide) == 2 and abs(vtN:getY()) >= abs(vtN:getZ())) then + dSicOnRadDn = ( dThDiamDn + dExtraForSafety - dToolDiamDn) / 2 + dSicOnLegthDn = 0 + else + dSicOnRadDn = ( dThDiamDn - dToolDiamDn) / 2 + dSicOnLegthDn = dExtraForSafety / 2 + end + dCollSicMinDn = max( BD.COLL_SIC, ( dThDiamDn - dToolDiamDn) / 2 * EgtIf( abs(dNzMin) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN:getY()) >= abs(vtN:getZ()), vtN:getZ(), vtN:getY()) / dNzMin))) + dCollSicDn = max( BD.COLL_SIC, dSicOnRadDn * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(nSide) == 1, vtN:getZ(), vtN:getY()) / dNz)) + dSicOnLegthDn) + + if dWidth + dAgg > dMaxDepth - dCollSic then + nPass = 2 + dAgg = 1 + if ( 0.5 * dWidth) + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongCut : depth is bigger than max tool depth' + end + end + if nPass == 1 and dWidth + dAgg > dMaxDepthDn - dCollSicDn then + nPass = 2 + dAgg = 1 + if ( 0.5 * dWidth) + dAgg > dMaxDepthDn - dCollSicDn then + sWarn = 'Warning in LongCut_2 : depth is bigger than max tool depth' + end + end + else + if dWidth + dAgg > dMaxDepth - dCollSic then + nPass = 2 + dAgg = 1 + if ( 0.5 * dWidth) + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongCut : depth is bigger than max tool depth' + end + end + end + else + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione + local dSicOnRad + local dSicOnLegth + if ( abs(nSide) == 1 and abs(vtN:getZ()) >= abs(vtN:getY())) or ( abs(nSide) == 2 and abs(vtN:getY()) >= abs(vtN:getZ())) then + dSicOnRad = ( dThDiam + dExtraForSafety - dToolDiam) / 2 + dSicOnLegth = 0 + else + dSicOnRad = ( dThDiam - dToolDiam) / 2 + dSicOnLegth = dExtraForSafety / 2 + end + dCollSicMin = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNzMin) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN:getY()) >= abs(vtN:getZ()), vtN:getZ(), vtN:getY()) / dNzMin))) + dCollSic = max( BD.COLL_SIC, dSicOnRad * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(nSide) == 1, vtN:getY(), vtN:getZ()) / dNz)) + dSicOnLegth) + if dWidth + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongCut : depth is bigger than max tool depth' + end + end + -- profondità prima passata + dDepth = min( dMaxDepth - dCollSicMin, dWidth + dAgg) + -- profondità seconda passata + dDepth2 = dWidth + dAgg - dDepth + if nSide ~= 1 and BD.DOWN_HEAD then + dDepthDn = min( dMaxDepthDn - dCollSicMinDn, dWidth + dAgg) + dDepth2Dn = dWidth + dAgg - EgtIf( abs(nSide) == 2, dDepth, dDepthDn) + end + -- ciclo sulle parti local nM = 0 local bMakeMillHeadEnd local bMakeMillHeadStart + local dLioPerp1 = dFacElev + BD.COLL_SIC +-- local dLioPerp2 = dWidth + BD.COLL_SIC + local dLioPerp2 = dWidth * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, sqrt( 1 - dNz * dNz) / abs( dNz)) + BD.COLL_SIC + -- valore sovrapposizione tra passate + local dOverLapExtend = 2 for j = 1, nC do -- Limitazioni della lavorazione local nPos = EgtIf( bFront, j, nC - j + 1) - local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC) - local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC) + local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC + dOverLapExtend) + local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC + dOverLapExtend) -- Posizione braccio portatesta local nSCC - if bFront then - nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) - else - nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) - end - -- inserisco le parti di lavorazione - nM = nM + 1 - local sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) - local nMchFId = EgtAddMachining( sNameF, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, 0}}) - -- limito opportunamente la lavorazione - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) - -- imposto posizione braccio porta testa per non ingombrare agli estremi - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- imposto uso faccia - local nUseFace = MCH_MILL_FU.PARAL_DOWN - if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then nUseFace = MCH_MILL_FU.PARAL_BACK end - EgtSetMachiningParam( MCH_MP.FACEUSE, nUseFace) - -- imposto lato di lavoro e inversione - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - EgtSetMachiningParam( MCH_MP.INVERT, true) - -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) - -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione --- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN:getY() / vtN:getZ()) - 3) - local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN:getY() / vtN:getZ())) - if dWidth + dAgg > dMaxDepth - dCollSic then - sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dWidth + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' - end - local dDepth = min( dMaxDepth - dCollSic, dWidth + dAgg) - EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) - -- eseguo - if not EgtApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - -- eventuale lavorazione della faccia limitante la fine - if j == EgtIf( bFront , 1, nC) and not bEndFixed and bRemoveToolRadius then - local vtFin = EgtIf( bFront, -X_AX(), X_AX()) - for i = 1, Proc.Fct - 1 do - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) - if vtFin * vtN > 0 and not bMakeMillHeadEnd then - MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) - bMakeMillHeadEnd = true + for k = 1, nPass do + +-- if EgtIf( k == 1, bFront, not bFront) then + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF + local nMchFId + if BD.DOWN_HEAD and k == 2 and nSide ~= 1 then + sNameF = sPrefixDn .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMillingDn) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn + EgtOutLog( sErr) + return false, sErr + end + else + sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr end end - if bRemoveToolRadius and not bMakeMillHeadEnd then - MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + local nUseFace = MCH_MILL_FU.PARAL_DOWN + if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then nUseFace = MCH_MILL_FU.PARAL_BACK end + EgtSetMachiningParam( MCH_MP.FACEUSE, nUseFace) + -- imposto lato di lavoro e inversione + if k == 1 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + dSal, dEal = dEal, dSal end - end - -- eventuale lavorazione della faccia limitante l'inizio - if j == EgtIf( bFront , nC, 1) and not bStartFixed and bRemoveToolRadius then - local vtIni = EgtIf( bFront, X_AX(), -X_AX()) - for i = 1, Proc.Fct - 1 do - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) - if vtIni * vtN > 0 and not bMakeMillHeadStart then - MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) - bMakeMillHeadStart = true + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- assegno affondamento + local dExtraElev = 0 + local dExtraElevDn = 0 + + if not BD.DOWN_HEAD then + -- se prima lavorazione non da sotto o seconda lavorazione da sotto e componente Y <= 60° e > 0 + if ( ( k == 1 and nSide ~= -1) or ( k == 2 and nSide == -1)) and abs(vtN:getY()) <= 0.866 and abs(vtN:getY()) > GEO.EPS_SMALL then + -- verifico se può collidere in base alle dimensione del portapezzo + local dDistToolTh = (dToolLength - EgtIf( k == 1, dDepth, dDepth2) - dThLen) / abs(vtN:getZ()) + local dDistRadTh = dDistToolTh * abs(vtN:getY()) + local dDistSurf = EgtIf( bFront, b3Solid:getMax():getY() - Proc.Box:getMax():getY(), Proc.Box:getMin():getY() - b3Solid:getMin():getY()) + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurf > dDistToolTh and dDistRadTh < (( dThDiam - dToolDiam) / 2) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getY()) > abs(vtN:getZ()) then + dExtraElev = ((( dThDiam - dToolDiam) / 2) - dDistRadTh) * abs(vtN:getZ()) / abs(vtN:getY()) + ( 0.5 * dExtraForSafety) / abs(vtN:getY()) + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElev = ((( dThDiam + dExtraForSafety - dToolDiam) / 2) - dDistRadTh) * abs(vtN:getZ()) / abs(vtN:getY()) + end + elseif abs(dDistSurf) > GEO.EPS_SMALL then + if nSide ~= -1 then + dDistSurf = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ() + else + dDistSurf = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + end + if dDistSurf * abs(vtN:getZ()) > (( dThDiam + dToolDiam) * 0.5) then + dExtraElev = dDistSurf * abs(vtN:getY()) + end + end + -- altrimenti prima lavorazione di fianco con componente Z negativa + elseif k == 1 and abs(nSide) == 2 and vtN:getZ() > -0.866 and vtN:getZ() < - GEO.EPS_SMALL then + -- verifico se può collidere in base alle dimensione del portapezzo + local dDistToolTh = (dToolLength - dDepth - dThLen) / abs(vtN:getY()) + local dDistRadTh = dDistToolTh * abs(vtN:getZ()) + local dDistSurf = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ() + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurf > dDistToolTh and dDistRadTh < (( dThDiam - dToolDiam) / 2) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getY()) > abs(vtN:getZ()) then + dExtraElev = ((( dThDiam - dToolDiam) / 2) - dDistRadTh) * abs(vtN:getY()) / abs(vtN:getZ()) + ( 0.5 * dExtraForSafety) / abs(vtN:getZ()) + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElev = ((( dThDiam + dExtraForSafety - dToolDiam) / 2) - dDistRadTh) * abs(vtN:getY()) / abs(vtN:getZ()) + end + elseif abs( dDistSurf) < GEO.EPS_SMALL then + if bFront then + dDistSurf = Proc.Box:getMin():getY() - b3Solid:getMin():getY() + else + dDistSurf = b3Solid:getMax():getY() - Proc.Box:getMax():getY() + end + if dDistSurf * abs(vtN:getY()) > (( dThDiam + dToolDiam) * 0.5) then + dExtraElev = dDistSurf * abs(vtN:getZ()) + end + end + end + -- altrimenti con testa da sotto + else + -- se prima lavorazione non da sotto e componente y <= 60° e > 0 + if ( k == 1 and nSide ~= -1) and abs(vtN:getY()) <= 0.866 and abs(vtN:getY()) > GEO.EPS_SMALL then + -- verifico se può collidere in base alle dimensione del portapezzo + local dDistToolTh = (dToolLength - dDepth - dThLen) / abs(vtN:getZ()) + local dDistRadTh = dDistToolTh * abs(vtN:getY()) + local dDistSurf = EgtIf( bFront, b3Solid:getMax():getY() - Proc.Box:getMax():getY(), Proc.Box:getMin():getY() - b3Solid:getMin():getY()) + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurf > dDistToolTh and dDistRadTh < (( dThDiam - dToolDiam) * 0.5) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getZ()) > abs(vtN:getY()) then + dExtraElev = ((( dThDiam - dToolDiam) * 0.5) - dDistRadTh) * abs(vtN:getZ()) / abs(vtN:getY()) + ( 0.5 * dExtraForSafety) / abs(vtN:getY()) + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElev = ((( dThDiam + dExtraForSafety - dToolDiam) * 0.5) - dDistRadTh) * abs(vtN:getZ()) / abs(vtN:getY()) + end + elseif abs(dDistSurf) < GEO.EPS_SMALL then + dDistSurf = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ() + if dDistSurf * vtN:getZ() > (( dThDiam + dToolDiam) * 0.5) then + dExtraElev = dDistSurf * abs(vtN:getY()) + end + end + -- se seconda lavorazione sopra e componente Z > 0 + elseif k == 2 and nSide == 1 and vtN:getZ() > GEO.EPS_SMALL then + local dDistToolTh = (dToolLength - dDepth2 - dThLen) / abs(vtN:getY()) + local dDistRadTh = dDistToolTh * abs(vtN:getZ()) + local dDistSurf = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurf > dDistToolTh and dDistRadTh < (( dThDiam - dToolDiam) * 0.5) then + -- premio extra sicurezza su lunghezza utensile + if abs(vtN:getZ()) > abs(vtN:getY()) then + dExtraElev = ((( dThDiam - dToolDiam) * 0.5) - dDistRadTh) * abs(vtN:getY()) / abs(vtN:getZ()) + ( 0.5 * dExtraForSafety) / vtN:getZ() + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElev = ((( dThDiam + dExtraForSafety - dToolDiam) * 0.5) - dDistRadTh) * abs(vtN:getY()) / abs(vtN:getZ()) + end + end + -- se prima lavorazione di fianco e componente Z > 0 + elseif k == 1 and abs(nSide) == 2 and vtN:getZ() < GEO.EPS_SMALL then + local dDistToolTh = (dToolLength - dDepth - dThLen) / abs(vtN:getY()) + local dDistRadTh = dDistToolTh * abs(vtN:getZ()) + local dDistSurf = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ() + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurf > dDistToolTh and dDistRadTh < (( dThDiam - dToolDiam) * 0.5) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getY()) > abs(vtN:getZ()) then + dExtraElev = (dDistSurf - dDistToolTh + ( 0.5 * dExtraForSafety)) / abs(vtN:getY()) + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElev = (( dThDiam - dToolDiam) * 0.5) * abs(vtN:getY()) / abs(vtN:getZ()) - (dToolLength - dDepth - dThLen) + ( 0.5 * dExtraForSafety) / abs(vtN:getZ()) + end + elseif abs(dDistSurf) < GEO.EPS_SMALL then + if bFront then + dDistSurf = Proc.Box:getMin():getY() - b3Solid:getMin():getY() + else + dDistSurf = b3Solid:getMax():getY() - Proc.Box:getMax():getY() + end + if dDistSurf * abs(vtN:getY()) > (( dThDiam + dToolDiam) * 0.5) then + dExtraElev = dDistSurf * abs(vtN:getZ()) + end + end + -- se seconda lavorazione di fianco e componente Z > 0 + elseif k == 2 and abs(nSide) == 2 and vtN:getZ() > GEO.EPS_SMALL then + local dDistToolThDn = (dToolLengthDn - dDepth2Dn - dThLenDn) / abs(vtN:getY()) + local dDistRadThDn = dDistToolThDn * abs(vtN:getZ()) + local dDistSurfDn = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurfDn > dDistToolThDn and dDistRadThDn < (( dThDiamDn - dToolDiamDn) * 0.5) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getY()) > abs(vtN:getZ()) then + dExtraElevDn = ((( dThDiamDn - dToolDiamDn) * 0.5) - dDistRadThDn) * abs(vtN:getY()) / abs(vtN:getZ()) + ( 0.5 * dExtraForSafety) / vtN:getZ() + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElevDn = ((( dThDiamDn + dExtraForSafety - dToolDiamDn) * 0.5) - dDistRadThDn) * abs(vtN:getY()) / abs(vtN:getZ()) + end + elseif abs(dDistSurfDn) < GEO.EPS_SMALL then + if bFront then + dDistSurfDn = Proc.Box:getMin():getY() - b3Solid:getMin():getY() + else + dDistSurfDn = b3Solid:getMax():getY() - Proc.Box:getMax():getY() + end + if dDistSurfDn * abs(vtN:getY()) > (( dThDiamDn + dToolDiamDn) * 0.5) then + dExtraElevDn = dDistSurfDn * abs(vtN:getZ()) + end + end + -- se seconda lavorazione da sotto a componente Y < 60° e Y > 0 + elseif ( k == 2 and nSide == -1) and abs(vtN:getY()) <= 0.866 and abs(vtN:getY()) > GEO.EPS_SMALL then + -- verifico se può collidere in base alle dimensione del portapezzo + local dDistToolThDn = (dToolLengthDn - dDepth2Dn - dThLenDn) / abs(vtN:getY()) + local dDistRadThDn = dDistToolThDn * abs(vtN:getZ()) + local dDistSurfDn = EgtIf( bFront, b3Solid:getMax():getY() - Proc.Box:getMax():getY(), Proc.Box:getMin():getY() - b3Solid:getMin():getY()) + -- raggio portautensile e raggio utensile allora calcolo un arretramento profondità + if dDistSurfDn > dDistToolThDn and dDistRadThDn < (( dThDiamDn - dToolDiamDn) * 0.5) then + -- se devo premiare extra sicurezza su lunghezza utensile + if abs(vtN:getZ()) > abs(vtN:getY()) then + dExtraElevDn = ((( dThDiamDn - dToolDiamDn) * 0.5) - dDistRadThDn) * abs(vtN:getY()) / abs(vtN:getZ()) + ( 0.5 * dExtraForSafety) / abs(vtN:getY()) + -- altrimenti premio extra sicurezza su raggio utensile + else + dExtraElevDn = ((( dThDiamDn + dExtraForSafety - dToolDiamDn) * 0.5) - dDistRadThDn) * abs(vtN:getY()) / abs(vtN:getZ()) + end + elseif abs(dDistSurfDn) < GEO.EPS_SMALL then + dDistSurfDn = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + if dDistSurfDn * abs(vtN:getZ()) > (( dThDiamDn + dToolDiamDn) * 0.5) then + dExtraElevDn = dDistSurfDn * abs(vtN:getY()) + end + end end end - if bRemoveToolRadius and not bMakeMillHeadStart then - MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + + if BD.DOWN_HEAD and k == 2 and nSide ~= 1 then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth2Dn - dExtraElevDn) + if dExtraElevDn > 0 and sWarn and #sWarn < 1 then + sWarn = 'Warning in LongCut_2 : depth is bigger than max tool depth' + end + else + EgtSetMachiningParam( MCH_MP.DEPTH, EgtIf( k == 1, dDepth, dDepth2) - dExtraElev) + if dExtraElev > 0 and sWarn and #sWarn < 1 then + sWarn = 'Warning in LongCut : depth is bigger than max tool depth' + end + end + -- assegbo attacco perpendicolare + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp1) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp1) + -- eseguo + if not EgtApplyMachining( true, false) then + -- se feature orientata su faccia da sotto provo a cambiare l'attacco + if nSide == -1 then + EgtSetMachiningParam( MCH_MP.LIPERP, min( dLioPerp1, dLioPerp2)) + EgtSetMachiningParam( MCH_MP.LOPERP, min( dLioPerp1, dLioPerp2)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + -- esco se non sono nella seconda lavorazione o non nella faccia da sotto + if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then + return false, sErr + end + end + else + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + -- esco se non sono nella seconda lavorazione o non nella faccia da sotto + if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then + return false, sErr + end + end + end + -- eventuale lavorazione della faccia limitante la fine + if j == EgtIf( bFront , 1, nC) and not bEndFixed and bRemoveToolRadius then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtFin * vtN > 0 and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadEnd = true + end + end + if bRemoveToolRadius and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if j == EgtIf( bFront , nC, 1) and not bStartFixed and bRemoveToolRadius then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtIni * vtN > 0 and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadStart = true + end + end + if bRemoveToolRadius and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end end end end diff --git a/LuaLibs/ProcessLongDoubleCut.lua b/LuaLibs/ProcessLongDoubleCut.lua index 5835f33..b7f97cc 100644 --- a/LuaLibs/ProcessLongDoubleCut.lua +++ b/LuaLibs/ProcessLongDoubleCut.lua @@ -1,4 +1,4 @@ --- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2021/06/29 +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2021/09/08 -- Gestione calcolo doppio taglio longitudinale per Travi -- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto. -- 2021/06/29 Corretta gestione caso equivalente a due smussi. @@ -74,7 +74,7 @@ function ProcessLong2Cut.Classify( Proc) local nSide = 0 if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then nSide = 1 - elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + elseif vtN[1]:getZ() < 10 * GEO.EPS_SMALL and vtN[2]:getZ() < 10 * GEO.EPS_SMALL then nSide = -1 end -- angolo diedro per stabilire se taglio convesso @@ -86,11 +86,11 @@ function ProcessLong2Cut.Classify( Proc) bConvex = true end -- se feature di fianco e facce concave per lavorazione impossibile - if nSide == 0 and not bConvex then - -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra) - Proc.ErrMsg = 'Error : impossible to machinine with tool on side' - return false, false - end +-- if nSide == 0 and not bConvex then +-- -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra) +-- Proc.ErrMsg = 'Error : impossible to machinine with tool on side' +-- return false, false +-- end end return true, false @@ -217,7 +217,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster local nSide = 0 if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then nSide = 1 - elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + elseif vtN[1]:getZ() < 10 * GEO.EPS_SMALL and vtN[2]:getZ() < 10 * GEO.EPS_SMALL then nSide = -1 end @@ -288,10 +288,15 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster -- se entrambe i Q sono attivi, disabilito lama if nUseMillOnSide > 0 then bUseBlade = false end - -- Se senza facce limitanti, da sopra e richiesto con doppio taglio di lama - if nFaceLimit == 0 and ( nSide == 1 or ( nSide == 0 and BD.DOWN_HEAD)) and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then + -- Se senza facce limitanti, da sopra o ( da tutte i lati con testa da sotto) e taglio di lama e lunghezza facce maggiore del parametro lunghezza minima + if nFaceLimit == 0 and ( nSide == 1 or ( abs(nSide) >= 0 and BD.DOWN_HEAD)) and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then -- recupero la lavorazione - local sCutting = ML.FindCutting( 'HeadSide') + local sCutting + if nSide == -1 and BD.DOWN_HEAD then + sCutting = ML.FindCutting( 'HeadSide_H2') + else + sCutting = ML.FindCutting( 'HeadSide') + end if not sCutting then local sErr = 'Error : HeadSide not found in library' EgtOutLog( sErr) @@ -379,8 +384,15 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster if ( not bFront and k == 1) or ( bFront and k == 2) then dSal, dEal = dEal, dSal end - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + if nSide == -1 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, false) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + end -- imposto offset radiale EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) -- imposto attacco/uscita @@ -414,9 +426,16 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster for j = 1, #vOrd do -- determino se lavorazione da davanti o da dietro local bFront = ( vtN[vOrd[j]]:getY() < 0) - -- determino l'utilizzo della faccia - local nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) - local nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + local nFaceUse + local nFaceUse2 + if abs( nSide) == 1 then + -- determino l'utilizzo della faccia + nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + else + nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + nFaceUse2 = vFaceUse[vOrd[j]] + end -- ciclo sulle passate local dOffset local dLioPerp @@ -446,11 +465,16 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster -- limito opportunamente la lavorazione local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) - if ( bFront) then + if ( bFront and abs( nSide) == 1) or j == 2 then dSal, dEal = dEal, dSal end - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + if nSide == -1 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + end -- imposto offset radiale EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) -- imposto attacco/uscita @@ -461,7 +485,11 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster -- imposto posizione braccio porta testa per non ingombrare agli estremi EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto uso della faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse2) + if nSide == -1 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse2) + end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() @@ -472,7 +500,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster end end -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut - elseif ( nSide ~= - 1 or BD.DOWN_HEAD) and nUseMillOnSide == 0 then + elseif ( ( nSide ~= -1 or BD.DOWN_HEAD) or ( nSide == -1 and BD.DOWN_HEAD)) and nUseMillOnSide == 0 then -- determino la massima elevazione local dElev = 0 local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[1], nPartId) @@ -485,7 +513,13 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster dElev = max( dFacElev1, dFacElev2) end -- recupero la lavorazione - local sMilling = ML.FindMilling( 'Long2Cut', dElev) + local sMilling + if nSide == -1 and BD.DOWN_HEAD then + sMilling = ML.FindMilling( 'Long2Cut_H2', dElev) + else + sMilling = ML.FindMilling( 'Long2Cut', dElev) + end + if not sMilling then local sErr = 'Error : Long2Cut not found in library' EgtOutLog( sErr) @@ -636,17 +670,22 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster for j = 1, nC do -- su entrambe le facce for i = nIni, nFin do + -- valore sovrapposizione tra passate con fresa di fianco + local dOverLapExtend = 2 + -- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg) + local bSide = ( vtN[vOrd[i]]:getZ() < dLimitAngle and not ( nSide == -1 and BD.DOWN_HEAD)) -- Limitazioni della lavorazione local nPos = EgtIf( i == 1, j, nC - j + 1) - local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) - local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + EgtIf( bSide, dOverLapExtend, 0)) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + EgtIf( bSide, dOverLapExtend, 0)) -- Posizione braccio portatesta local nSCC = MCH_SCC.NONE if not BD.C_SIMM then nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) end - -- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg) - local bSide = ( vtN[vOrd[i]]:getZ() < dLimitAngle and not BD.DOWN_HEAD) + if bSide and not bConvex then + dSal, dEal = dEal, dSal + end -- ciclo sulle passate local nO = 1 local dStep = 0 @@ -671,8 +710,13 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) -- limito opportunamente la lavorazione - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + if ( nSide == -1 and BD.DOWN_HEAD) then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + end -- imposto posizione braccio porta testa per non ingombrare agli estremi EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto uso faccia @@ -686,8 +730,8 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster local dOffsR = EgtIf( k < nO, ( nO - k) * dStep, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) if bSide then dOffsR = 0 end EgtSetMachiningParam( MCH_MP.OFFSR, dOffsR) - -- se di lato, imposto offset longitudinale - if bSide then + -- se di lato e convesso, imposto offset longitudinale + if bSide and bConvex then EgtSetMachiningParam( MCH_MP.OFFSL, - BD.CUT_EXTRA) end -- attacco e uscita @@ -726,7 +770,9 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster local nExtendMach -- recupero la lavorazione local sMilling + local sMillingDn local sPrefix + local sPrefixDn if nSide ~= - 1 then sMilling = ML.FindMilling( 'Long2CutSide') sPrefix = 'L2CS_' @@ -735,20 +781,35 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster bRemoveToolRadius = true -- nExtendMach = 0 -- arretro la lavorazione del raggio utensile (se non ha facce limite) end + -- se testa da sotto + if nSide ~= 1 and BD.DOWN_HEAD then + sMillingDn = ML.FindMilling( 'Long2CutSide_H2') + sPrefixDn = 'L2CSH2_' + end -- lavorazione da sotto else - sMilling = ML.FindMilling( 'Long2CutDown') + sMilling = ML.FindMilling( 'Long2CutDown', nil, nil, EgtIf( nUseMillOnSide > 0, 150, 50)) sPrefix = 'L2CD_' nExtendMach = 1 if nUseMillOnSide ~= 1 then nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) end + -- se testa da sotto + if BD.DOWN_HEAD then + sMillingDn = ML.FindMilling( 'Long2CutDown_H2') + sPrefixDn = 'L2CDH2_' + end end if not sMilling then local sErr = 'Error : Long2CutSide or Long2CutDown not found in library' EgtOutLog( sErr) return false, sErr end + if nSide ~= 1 and BD.DOWN_HEAD and not sMillingDn then + local sErr = 'Error : Long2CutSide_H2 or Long2CutDown_H2 not found in library' + EgtOutLog( sErr) + return false, sErr + end -- se angolo compreso è inferiore ai 90 gradi do errore if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then local sErr = 'Error : Impossible use a mill with angle less than 90' @@ -757,32 +818,57 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster end -- recupero i dati dell'utensile local dToolDiam = 0 + local dToolLength = 0 local dMaxDepth = 0 local dThDiam = 0 + local dThLen = 0 + local dExtraForSafety = EgtIf( BD.DOWN_HEAD, 8.5, 6.5) -- corrisponde al doppio valore di sicurezza dell'mlpe + 0.5 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + dThLen = EgtTdbGetCurrToolThLength() or dThLen + end + end + -- recupero i dati dell'utensile da sotto + local dToolDiamDn = 0 + local dToolLengthDn = 0 + local dMaxDepthDn = 0 + local dThDiamDn = 0 + local dThLenDn = 0 + if nSide ~= 1 and BD.DOWN_HEAD and EgtMdbSetCurrMachining( sMillingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dToolLengthDn = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLengthDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + dThDiamDn = (EgtTdbGetCurrToolThDiam() or dThDiamDn) + dThLenDn = EgtTdbGetCurrToolThLength() or dThLenDn end end local dDistToEnd = dToolDiam / 2 + local dDistToEndDn = dToolDiamDn / 2 + -- calcolo l'elevazione della faccia principale + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId) -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile if nUseMillOnSide <= 1 or nSide == -1 then - -- calcolo l'elevazione della faccia principale - local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId) - local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId) local dFacElev = max( dFacElev1, dFacElev2) if dFacElev < dDistToEnd then dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) end + if dFacElev < dDistToEndDn then + dDistToEndDn = sqrt( ( ( dToolDiamDn / 2) * ( dToolDiamDn / 2)) - ( ( dToolDiamDn / 2 - dFacElev) * (dToolDiamDn / 2 - dFacElev))) + end end -- se la fine è già limitata allora setto per arretrare del raggio utensile if nFaceLimit >= 2 then nExtendMach = 0 -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata - elseif dDistToNextPiece < dDistToEnd and nExtendMach ~= 1 then + elseif ( dDistToNextPiece < dDistToEnd or dDistToNextPiece < dDistToEndDn) and nExtendMach ~= 1 then nFaceLimit = nFaceLimit + 2 end -- aggiuntivo sull'affondamento @@ -850,7 +936,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster local nDir = 1 -- se facce ortogonali (concave) controllo se con la lavorazione della prima faccia il diametro copre la seconda (e non la eseguo) if bOrtho then - -- se da sotto scelgo la faccia (lavorta col fianco utensile) con direzione più sottosquadra + -- se da sotto scelgo la faccia (lavorata col fianco utensile) con direzione più sottosquadra if nSide == -1 and vtN[vOrd[1]]:getZ() < -0.001 and vtN[vOrd[2]]:getZ() < -0.001 then -- se gli angoli delle due facce sono uguali ( sotto il grado di differenza) sgelgo la faccia più vicina a un fianco if abs(vtN[vOrd[1]]:getZ() - vtN[vOrd[2]]:getZ()) < 0.017 then @@ -905,22 +991,55 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster end end end - -- su entrambe le facce + -- ciclo sulle facce selezionate for i = nIni, nFin, nDir do + -- valore sovrapposizione tra passate + local dOverLapExtend = 2 -- Limitazioni della lavorazione local nPos = EgtIf( i == 1, j, nC - j + 1) - local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) - local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + dOverLapExtend) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + dOverLapExtend) -- Posizione braccio portatesta local nSCC = EgtIf( BD.C_SIMM, MCH_SCC.NONE, MCH_SCC.ADIR_XP) -- inserisco le parti di lavorazione nM = nM + 1 - local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) - local nMchFId = EgtAddMachining( sNameF, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr + local sNameF + local nMchFId + local bUseDownHead + local bFront = (vtN[vOrd[i]]:getY() < 0) + if BD.DOWN_HEAD and nSide ~= 1 then + local ptC3 = EgtSurfTmFacetCenter( Proc.Id, tFaceLong[vOrd[i]], GDB_ID.ROOT) + local ptDir = ptC3 - ptM ; ptDir:normalize() + -- se concave e dal versore Z della faccia (> -20°) o convesso e versore Z ( > -30°) decido se eseguire la lavoraione con la testa d a sopra o da sotto + if ( not bConvex and vtN[vOrd[i]]:getZ() > -0.9397 and ptDir:getZ() > 0) or + ( bConvex and vtN[vOrd[i]]:getZ() > -0.866 and ptDir:getZ() > 0) then + sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMilling) + bUseDownHead = false + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + else + sNameF = sPrefixDn .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMillingDn) + bUseDownHead = true + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn + EgtOutLog( sErr) + return false, sErr + end + end + else + sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMilling) + bUseDownHead = false + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) @@ -929,69 +1048,161 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) -- imposto posizione braccio porta testa per non ingombrare agli estremi EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- imposto uso faccia + -- se fresa di fianco e non da sotto if nUseMillOnSide > 0 and nSide ~= -1 then - if nSide == 1 then + -- se faccia da sopra o di fianco + if nSide >= 0 then if bConvex then - if vtN[vOrd[i]]:getZ() > 0.866 then - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + local vFaceUse2 + -- se da sopra + if nSide == 1 then + if vtN[vOrd[i]]:getZ() > 0.866 then + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 1, 2)], vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) +-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end + -- altrimenti è di fianco else - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + if vtN[vOrd[i]]:getY() > 0.866 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end end -- se concavo else - local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + local vFaceUse2 + -- se da sopra + if nSide == 1 then +-- vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)]) + -- altrimenti è di fianco + else + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + end EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) end - else + -- questa parte non viene mai eseguita + -- se faccia da sotto +-- else +-- if bConvex then +-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) +-- if vtN[vOrd[i]]:getZ() >= 0 then +-- EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) +-- EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) +-- end +-- else +-- -- lascio lo stesso le lavorazioni anche se viene intercettato l'errore +-- local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) +-- EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) +-- if vtN[vOrd[i]]:getZ() < 0 then +-- EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) +-- EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) +-- end +-- end + end + else + -- se con fresa di fianco + if nUseMillOnSide > 0 then if bConvex then EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) if vtN[vOrd[i]]:getZ() >= 0 then - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + if BD.DOWN_HEAD and nSide ~= 1 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end end else -- lascio lo stesso le lavorazioni anche se viene intercettato l'errore - local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) +-- local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)]) EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) if vtN[vOrd[i]]:getZ() < 0 then - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + if BD.DOWN_HEAD and nSide ~= 1 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end end end + else + -- se faccia da sotto + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) end - else - EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) end -- imposto lato di lavoro e inversione EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.INVERT, true) - local dNz = vtN[vOrd[i]]:getZ() + -- calcolo la componente dNz non in base alla classificazione della feature (sopra, sotto, fianchi) ma alla componente maggiore +-- local dNz = EgtIf( nSide == 0, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) +-- local dNz = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dNz = EgtIf( abs(nSide) == 1, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dNzMin = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dLioPerp1, dLioPerp2 -- nel caso concavo, devo impostare la lunghezza di attacco ortogonale if not bConvex then --- local dLioPerp = vWidth[vOrd[i]] * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, sqrt( 1 - dNz * dNz) / abs( dNz)) + BD.COLL_SIC - local dLioPerp = vWidth[ EgtIf( vOrd[i] == 1, 2,1)] + BD.COLL_SIC - EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) - EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + dLioPerp1 = EgtIf( i == 1, dFacElev1, dFacElev2) +-- dLioPerp1 = vWidth[vOrd[i]] * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, sqrt( 1 - dNz * dNz) / abs( dNz)) + BD.COLL_SIC + dLioPerp2 = vWidth[ EgtIf( vOrd[i] == 1, 2,1)] + BD.COLL_SIC + EgtSetMachiningParam( MCH_MP.LIPERP, max( dLioPerp1, dLioPerp2)) + EgtSetMachiningParam( MCH_MP.LOPERP, max( dLioPerp1, dLioPerp2)) end -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione -- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()) - 3) - local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( vtN[vOrd[i]]:getY() / dNz))) - if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then - sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' +-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( vtN[vOrd[i]]:getY() / dNz))) + local dCollSic + local dDepth + -- assegno affondamento + local dExtraElev = 0 + -- se uso testa da sotto + if bUseDownHead then + dCollSic = max( BD.COLL_SIC, ( dThDiamDn - dToolDiamDn) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz))) + if vWidth[vOrd[i]] + dAgg > dMaxDepthDn - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepthDn - dCollSic, 1) .. ')' + end + dDepth = min( dMaxDepthDn - dCollSic, vWidth[vOrd[i]] + dAgg) + dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev) + else + dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz))) + if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg) + dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev) end - local dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg) - EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- eseguo if not EgtApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr + -- se feature orientata su faccia da sotto e concave provo a cambiare l'attacco + if nSide == -1 and not bConvex then + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp1) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end end -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) if bConvex and j == 1 and not bStartFixed and bRemoveToolRadius then