-- ProcessLapJoint.lua by Egaltech s.r.l. 2020/03/20 -- Gestione calcolo mezzo-legno per Travi -- 2019/10/08 Agg. gestione OpenPocket. -- Tabella per definizione modulo local ProcessLapJoint = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Cut = require( 'ProcessCut') local DoubleCut = require( 'ProcessDoubleCut') local LongCut = require( 'ProcessLongCut') local Long2Cut = require( 'ProcessLongDoubleCut') local Fbs = require( 'FacesBySaw') EgtOutLog( ' ProcessLapJoint started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') -- variabili assegnazione parametri Q local sForceUseBlade = '' -- i local sDepthChamferMill = '' -- d local sPreemptiveChamfer = '' -- i local sUseMill = '' -- i local sUseRoughTool = '' -- i local sUseRoughToolWithBAxis90 = '' -- i local sUseRoughToolWithBAxis0 = '' -- i local sInsertBoreOnCorner = '' -- 1 local sMakeContourWithSmallTool = '' -- i local sMakeOnlyContourOrFullPocket = '' -- i local sMakeBySideRoughTool = '' -- i local sAntisplintMode = '' -- i -- Settaggi interni local bTrySidePocketAtFirst = true --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessLapJoint.Identify( Proc) return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or ( Proc.Grp == 4 and Proc.Prc == 37) or ( Proc.Grp == 4 and Proc.Prc == 39)) end --------------------------------------------------------------------- local function AssignQValues( Proc) -- reset delle variabili assegnazione parametri Q sForceUseBlade = '' sDepthChamferMill = '' sPreemptiveChamfer = '' sUseMill = '' sUseRoughTool = '' sUseRoughToolWithBAxis90 = '' sUseRoughToolWithBAxis0 = '' sInsertBoreOnCorner = '' sMakeContourWithSmallTool = '' sMakeOnlyContourOrFullPocket = '' sMakeBySideRoughTool = '' sAntisplintMode = '' if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then sForceUseBlade = 'Q01' -- i sDepthChamferMill = 'Q04' -- d sPreemptiveChamfer = 'Q05' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then sDepthChamferMill = 'Q01' -- d sPreemptiveChamfer = 'Q02' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then sDepthChamferMill = 'Q01' -- d sUseMill = 'Q02' -- i sUseRoughTool = 'Q03' -- i sUseRoughToolWithBAxis90 = 'Q04' -- i sUseRoughToolWithBAxis0 = 'Q05' -- i sInsertBoreOnCorner = 'Q06' -- i elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then sMakeContourWithSmallTool = 'Q01' -- i sMakeOnlyContourOrFullPocket = 'Q02' -- i sMakeBySideRoughTool = 'Q03' -- i sAntisplintMode = 'Q06' -- i sDepthChamferMill = 'Q07' -- d elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then sMakeBySideRoughTool = 'Q01' -- i end -- le altre features gestite non hanno parametri Q nei parametri globali end --------------------------------------------------------------------- local function TestElleShape3( Proc) -- valida solo nel caso di tre facce if Proc.Fct ~= 3 then return false end -- determino se L con una faccia terminale o U con tre facce local bIsL = true for i = 1, 3 do local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] -- le conto local nCount = 0 for j = 1, #vFacAdj do if vFacAdj[j] >= 0 then nCount = nCount + 1 end end if nCount == 1 then bIsL = false break end end return bIsL end --------------------------------------------------------------------- local function TestElleShape4( Proc) -- valida solo nel caso di quattro facce if Proc.Fct ~= 4 then return false end -- determino se L con due facce terminali o O local bIsL = false local dMinArea3 = GEO.INFINITO local dMaxArea2 = 0 for i = 1, 4 do local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] -- le conto local nCount = 0 for j = 1, #vFacAdj do if vFacAdj[j] >= 0 then nCount = nCount + 1 end end local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) local dArea = dH * dV if nCount == 2 then dMaxArea2 = max( dMaxArea2, dArea) elseif nCount == 3 then dMinArea3 = min( dMinArea3, dArea) bIsL = true end end if not bIsL then return false end -- verifico se L profona oppure lunga if dMinArea3 < dMaxArea2 then return 1 else return 2 end end --------------------------------------------------------------------- local function VerifySawChain( Proc, dMinDim, dMaxDim, vtOrtho) local bUseSawChain = false local sMchFind = 'Sawing' local sSawing = ML.FindSawing(sMchFind) local dMaxMat = 0 local dSawCornerRad = 0 local dSawThick = 0 -- se non trova una lavorazione di sawing esco if not sSawing then return bUseSawChain else -- recupero i dati dell'utensile local dToolLength = 0 local dSawWidth = 75 if EgtMdbSetCurrMachining( sSawing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad end if dSawThick <= dMinDim and dSawWidth <= dMaxDim then bUseSawChain = true end end end return bUseSawChain, sSawing, dMaxMat, dSawCornerRad, dSawThick end --------------------------------------------------------------------- local function VerifyIfPocket( Proc, dDiam, vtOrtho, sMchFindMaster) local bUsePocketing = false local sMchFind = 'Pocket' if sMchFindMaster and #sMchFindMaster > 0 then sMchFind = sMchFindMaster end -- local dCollSic = 2 * BD.COLL_SIC -- if abs( vtOrtho:getX()) > 0.996 or abs( vtOrtho:getY()) > 0.996 or abs( vtOrtho:getZ()) > 0.996 then dCollSic = BD.COLL_SIC end local sPocketing = ML.FindPocketing( sMchFind, dDiam) local dMaxMat = 0 -- se non trova una svuotatura adatta if not sPocketing then return bUsePocketing else -- recupero i dati dell'utensile if EgtMdbSetCurrMachining( sPocketing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat end bUsePocketing = true end end return bUsePocketing, sPocketing, dMaxMat end --------------------------------------------------------------------- local function VerifyIfByBHSideMill( Proc) local bUseBHSideMill = false local bHead = true local sMilling local dMaxMat = 10 -- se non abilitato parametro Q per lavorarlo di fianco esco local nUseSideTol = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0 if nUseSideTol == 0 then return false end -- verifico se U local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) -- se U e lunghezza non richiede spezzatura if bIsU and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then -- recupero la lavorazione sMilling = ML.FindMilling( 'BHSideMill') if sMilling then -- recupero i dati dell'utensile local dToolLength = 0 local dMaxDepth = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat end end -- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile -- recupero l'ingombro della trave local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if b3Solid then local dMinXF = Proc.Box:getMin():getX() local dMaxXF = Proc.Box:getMax():getX() local dMinT = b3Solid:getMin():getX() local dMaxT = b3Solid:getMax():getX() -- determino se è più vicino alla testa o al bordo bHead = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) -- determino se è compatibile con il massimo affondamento dell'utensile bUseBHSideMill = EgtIf( bHead, (dMaxT - dMinXF), (dMaxXF - dMinT)) < dMaxDepth end end end return bUseBHSideMill, bHead, sMilling, dMaxMat end --------------------------------------------------------------------- local function GetTunnelDimension( Proc, nPartId) -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel -- recupero il numero di facce local nFacCnt = EgtSurfTmFacetCount( Proc.Id) -- recupero l'ingombro della trave local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) -- variabili dimensioni fessura e id faccia lunga local dDimMin local dDimMax local nLongIdFace = 0 -- ottengo il versore ortogonale local ptN1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) local vtOrtho = vtN1 ^ vtN2 if vtOrtho:isSmall() then _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) vtOrtho = vtN1 ^ vtN2 end -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura local frFc = Frame3d( ptN1, vtOrtho) ; local bBoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) local dDepth = bBoxLoc:getDimZ() -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' EgtOutLog( sErr) return false, sErr end -- creeo superfice intermedia local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN1, vtOrtho, b3Solid, GDB_ID.ROOT) -- ritaglio la superfici con le facce della fessura for i = 1, nFacCnt do local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) end local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) dDimMin = min( DimH, DimV) dDimMax = max( DimH, DimV) _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacCnt-1, GDB_ID.ROOT) -- se faccia pari alla larghezza fessura if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then nLongIdFace = nFacCnt-1 -- altrimenti faccia pari allo spessore fessura else nLongIdFace = nFacCnt-2 end if not dDimMax then return dDimMin, dDimMax, dDepth, nil, nil end return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt end --------------------------------------------------------------------- -- Verifica se feature di testa function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) -- se una sola faccia if Proc.Fct == 1 then local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) if vtN0:getX() > 0.1 then return true end end -- verifico se è in testa if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then return false end -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then return false end -- se una o due facce ora è sicuramente di testa if Proc.Fct <= 2 then return true end -- deve avere la normale principale diretta verso la testa local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) if vtN:getZ() < BD.NZ_MINA and nFacInd2 then ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) nFacInd, nFacInd2 = nFacInd2, nFacInd end if vtN:getX() < 0.499 then return false elseif Proc.Fct >= 5 then return true end -- deve occupare la maggior parte dell'area if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then return true end -- non è di testa return false end --------------------------------------------------------------------- -- Verifica se feature di coda function ProcessLapJoint.IsTailFeature( Proc, b3Raw) -- se una sola faccia if Proc.Fct == 1 then local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) if vtN0:getX() < -0.1 then return true end end -- in base al tipo di feature attribuisco il significato dei parametri Q AssignQValues( Proc) -- se può essere fatto con utensile tipo lama local bUseBHSideMill, bHead = VerifyIfByBHSideMill( Proc) if bUseBHSideMill then return not bHead end -- verifico se è in coda if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then return false end -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then return false end -- recupero identificativo del pezzo local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) -- se due facce e interessa veramente la coda, allora di coda if Proc.Fct <= 2 then local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then return true end end -- deve avere la normale principale diretta verso la coda local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) if vtN:getZ() < BD.NZ_MINA and nFacInd2 then ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) nFacInd, nFacInd2 = nFacInd2, nFacInd end if vtN:getX() > -0.499 then return false else return true end end --------------------------------------------------------------------- -- Classificazione della feature function ProcessLapJoint.Classify( Proc) -- se 1 faccia if Proc.Fct == 1 then -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- verifico se è lavorabile solo dal basso --local bDown = ( vtN:getZ() < BD.NZ_MINA) --return true, bDown return true, false -- se 2 facce elseif Proc.Fct == 2 then -- dati delle facce local ptC = {} local vtN = {} ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) -- verifico se è lavorabile solo dal basso local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM) or ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM) local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) return true, bDown -- se più di 2 facce else local bClosedOrthoFaces -- recupero la faccia con il maggior numero di adiacenze e minor elevazione local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) if not nFacInd or nFacInd < 0 then if nFacInd == -1 then bClosedOrthoFaces = nFacInd2 else return false end end -- se facce formano un tunnel e sono ortogonali if bClosedOrthoFaces then -- ottengo le dimensioni del tunnel local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) EgtErase(nSurfInt) -- verifico se può essere fatto con svuotatura if VerifyIfPocket( Proc, dDimMin, vtOrtho) then return true, false elseif VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) then return true, false else return false end else local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) -- se può essere fatto con utensile tipo lama local bUseBHSideMill, _, _, dMaxMat = VerifyIfByBHSideMill( Proc) if bUseBHSideMill and ( dMaxMat <= dV) then return true, false -- altrimenti controllo se deve essere ruotato con le altre lavorazioni else -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) -- verifico se è lavorabile solo dal basso local bDown = ( vtN:getZ() < BD.NZ_MINA) -- se verso il basso, verifico se utilizzabile seconda faccia if bDown then if nFacInd2 and dElev2 < 2 * dElev then local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) bDown = ( vtN2:getZ() < BD.NZ_MINA) end end return true, bDown end end end end --------------------------------------------------------------------- -- Lavorazione con fresa --------------------------------------------------------------------- local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- recupero l'ingombro della trave local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' EgtOutLog( sErr) return false, sErr end -- verifico il numero di facce della tacca assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- verifico se orientata verso l'alto local bUp = ( vtN:getZ() >= BD.NZ_MINA) -- scelta faccia da lavorare local nFacInd = 0 -- recupero la lavorazione local sMilling = ML.FindMilling( 'BirdsMouth') if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) return false, sErr end -- inserisco la lavorazione di fresatura local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sMilling) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) -- imposto uso faccia e lato correzione if vtN:getX() > 0 then EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) else EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) end -- imposto lato di correzione EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end -- imposto posizione braccio porta testa if vtN:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end -- dichiaro non si generano sfridi per VMill EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end -- eventuale segnalazione ingombro di testa o coda local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then if Proc.Head then local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() BL.UpdateHCING( nRawId, dOffs) elseif Proc.Tail then local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() BL.UpdateTCING( nRawId, dOffs) end end return true end --------------------------------------------------------------------- local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- recupero l'ingombro della trave local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' EgtOutLog( sErr) return false, sErr end -- verifico il numero di facce della tacca assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') -- dati delle facce local ptC = {} local vtN = {} ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) -- dati medi local ptM = ( ptC[1] + ptC[2]) / 2 -- verifico non siano orientate verso il basso local bFaceOk = {} bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) if not bFaceOk[1] and not bFaceOk[2] then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' EgtOutLog( sErr) return false, sErr end -- scelta faccia da lavorare local nFacInd -- se entrambe possibili if bFaceOk[1] and bFaceOk[2] then -- se in testa, scelgo quella orientata verso la testa if Proc.Head then if vtN[1]:getX() > vtN[2]:getX() then nFacInd = 0 else nFacInd = 1 end -- se altrimenti in coda, scelgo quella orientata verso la coda elseif Proc.Tail then if vtN[1]:getX() < vtN[2]:getX() then nFacInd = 0 else nFacInd = 1 end -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) else if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then if ptM:getX() > b3Raw:getCenter():getX() then nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) else nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) end else nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) end end elseif bFaceOk[1] then nFacInd = 0 else nFacInd = 1 end local nOthInd = 1 - nFacInd -- recupero la lavorazione local sMilling = ML.FindMilling( 'BirdsMouth') if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) return false, sErr end -- inserisco la lavorazione di fresatura local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sMilling) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) -- imposto uso faccia e lato correzione local nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- imposto lato di correzione EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- imposto posizione braccio porta testa if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end -- dichiaro non si generano sfridi per VMill EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end -- eventuale segnalazione ingombro di testa o coda local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then if Proc.Head then local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() BL.UpdateHCING( nRawId, dOffs) elseif Proc.Tail then local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() BL.UpdateTCING( nRawId, dOffs) elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() BL.UpdateHCING( nRawId, dOffs, dDist) end end return true end --------------------------------------------------------------------- local function MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) -- se interessa l'intera sezione della trave, necessaria sgrossatura if Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' EgtOutLog( sErr) return false, sErr end -- aggiungo sgrossatura e la lavoro local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB) if AddId then EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) -- applico lavorazione local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} local nCutFacet = EgtSurfTmFacetCount( AddId) if nCutFacet == 1 then return Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) elseif nCutFacet == 2 then return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0) end end end return true end --------------------------------------------------------------------- local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bSpecialApp, sMillMaster, nFacInd2, dFacElev2) -- Recupero le facce adiacenti alla principale local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] if not vAdj or #vAdj == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies' EgtOutLog( sErr) return false, sErr end EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) -- Riordino le dimensioni per avere dH > dV if dH < dV then dH, dV = dV, dH end -- Cerco una faccia adiacente alla principale sul lato lungo local nFacAdj for i = 1, #vAdj do if vAdj[i] >= 0 then local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) local dLen = dist( ptP1, ptP2) if dLen > 0.5 * dH then nFacAdj = vAdj[i] EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) break end end end -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione local bOpenStart = false local bOpenEnd = false local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,')) local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) -- Riordino le dimensioni per avere dH > dV if dH2 < dV2 then dH2, dV2 = dV2, dH2 end local nFacAdj2 for j = 1, #vAdj2 do if vAdj2[j] == nFacInd then -- Se non esiste faccia adiacente a lato precedente -> inizio aperto local i = EgtIf( j > 1, j - 1, #vAdj2) while vAdj2[i] == nFacInd do i = EgtIf( i > 1, i - 1, #vAdj2) end bOpenStart = ( vAdj2[i] < 0) -- Se non esiste faccia adiacente a lato successivo -> fine aperto local k = EgtIf( j < #vAdj2, j + 1, 1) while vAdj2[k] == nFacInd do k = EgtIf( k < #vAdj2, k + 1, 1) end bOpenEnd = ( vAdj2[k] < 0) end -- decommentare questa parte per concatenare due facce --if bSpecialApp and vAdj2[j] >= 0 then -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) -- local dLen = dist( ptP1, ptP2) -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then -- nFacAdj2 = vAdj2[j] -- end --end end -- Recupero la lavorazione di fresa local sMilling if bSpecialApp then sMilling = sMillMaster else sMilling = ML.FindMilling( 'LongSmallCut') if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) return false, sErr end end -- recupero i dati dell'utensile local dTDiam = 50 local dMaxMat = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat end end -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning if dMaxMat > 0 and dMaxMat + 15 < dElev then sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' ,skipped milling; elevation bigger than max tool depth' return true, sWarn end -- Calcolo uso faccia local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) -- inserisco la lavorazione di fresatura local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sMilling) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria if nFacAdj2 then EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj},{ Proc.Id, nFacAdj2}}) else EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) end -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- imposto posizione braccio porta testa local nSCC = MCH_SCC.ADIR_YM if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then nSCC = MCH_SCC.ADIR_YP end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto accorciamento iniziale/finale per estremi aperti/chiusi if bSpecialApp then -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita if nFacAdj2 then EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) -- confronto la faccia applicata nella lavorazione(faccia adiacente) con la seconda faccia passata nella funzione -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente if nFacAdj == nFacInd2 then if not bOpenStart then EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2) end if not bOpenEnd then EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2) end end end -- applico elevazione local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true, '', dTDiam end --------------------------------------------------------------------- local function ChooseCorner( Proc, nFacInd) -- Recupero le facce adiacenti alla principale local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] local tFacAdj = {} for i = 1, #vAdj do if vAdj[i] >= 0 then for j = 1, #vAdj do if vAdj[j] >= 0 and j ~= i then local bInsert = true for k = 1, #tFacAdj do local nFace1 = tFacAdj[k][1] local nFace2 = tFacAdj[k][2] if ( nFace1 == vAdj[i] and nFace2 == vAdj[j]) or ( nFace1 == vAdj[j] and nFace2 == vAdj[i]) then bInsert = false end end if bInsert then local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) if ptP1 and ptP2 then local dLen = dist( ptP1, ptP2) table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2}) end end end end end end -- tra le linee prendo quella più lunga local dMaxLen = 0 local nIdLine for i = 1, #tFacAdj do if tFacAdj[i][3] > dMaxLen then nIdLine = i dMaxLen = tFacAdj[i][3] end end return dMaxLen, nIdLine, tFacAdj end --------------------------------------------------------------------- local function MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) local sMyWarn local pAuxId = {} local nAuxId local AuxId local ptApPoint local dLenTrimExt local sMilling local dMaxDepth = 0 -- ottengo l'angolo di riferimento dove applicare il percorso di pulitura local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) -- prendo il primo versore local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) local _, vtN3 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) if not tFacAdj then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry not found for clean corner' EgtOutLog( sErr) return false, sErr end -- trovo il punto sulla superfice di riferimento local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) local nIdIniPoint local nIdEndPoint if ptLocP1 and ptLocP2 then if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then nIdEndPoint = 4 nIdIniPoint = 5 elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then nIdEndPoint = 5 nIdIniPoint = 4 end end -- versore direzione local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] vtExtr:normalize() -- inserisco le prime tre linee if nIdIniPoint and nIdEndPoint then -- se fresatura da sotto salto la lavorazione if vtExtr:getZ() < BD.DRILL_VZ_MIN then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' clean corner milling from bottom impossible' EgtOutLog( sErr) return false, sErrLX end -- sommo i tre versori per avre una direzione media vtExtr = vtN1 + vtN2 + vtN3 vtExtr:normalize() -- recupero la lavorazione sMilling = ML.FindMilling( 'CleanCorner', (dDiam * 0.6)) if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' clean corner milling not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione) if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth end nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) table.insert( pAuxId, nAuxId) -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then ptApPoint = ptLocP2 else ptApPoint = ptLocP1 end nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta if dLenTrimExt > 10 * GEO.EPS_SMALL then EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) -- prendo il nuovo punto finale ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) end table.insert( pAuxId, nAuxId) -- creo linea di ritorno nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) table.insert( pAuxId, nAuxId) end -- inserisco le ultime tre linee -- trovo il secondo punto sulla superfice di riferimento _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) if ptLocP1 and ptLocP2 then -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then ptApPoint = ptLocP2 else ptApPoint = ptLocP1 end nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta if dLenTrimExt > 10 * GEO.EPS_SMALL then EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) -- prendo il nuovo punto finale ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) end table.insert( pAuxId, nAuxId) -- creo linea di ritorno nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) table.insert( pAuxId, nAuxId) -- ultima linea di risalita nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdIniPoint], GDB_RT.GLOB) table.insert( pAuxId, nAuxId) end -- trasformo in percorso if #pAuxId > 0 then AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) end -- se non c'é il percorso do errore if not AuxId then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' EgtOutLog( sErr) return false, sErr end -- modifico versore direzione EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) -- inserisco la lavorazione local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchId = EgtAddMachining( sName, sMilling) if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- imposto posizione braccio porta testa local nSCC = MCH_SCC.ADIR_YM if vtExtr:getY() > 100 * GEO.EPS_ZERO then nSCC = MCH_SCC.ADIR_YP end EgtSetMachiningParam( MCH_MP.SCC, nSCC) EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) -- allungo inizio e fine di 10mm EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) -- setto affondamento 0 EgtSetMachiningParam( MCH_MP.DEPTH, 0) -- Note utente con dichiarazione nessuna generazione sfridi per Vmill local sUserNotes = 'VMRS=0;' -- aggiungo alle note massima elevazione sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr else local _, sWarn = EgtGetMachMgrWarning( 0) if EgtIsMachiningEmpty() then EgtSetOperationMode( nMchId, false) return false, sWarn else return true, ( sMyWarn or sWarn) end end return true, sMyWarn end --------------------------------------------------------------------- local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach) local sMyWarn -- ottengo l'angolo dove applicare il foro local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) if not tFacAdj then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry not found for drilling' EgtOutLog( sErr) return false, sErr end -- trovo il punto sulla superfice di riferimento local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) local nIdIniPoint local nIdEndPoint if ptLocP1 and ptLocP2 then if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then nIdEndPoint = 4 nIdIniPoint = 5 elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then nIdEndPoint = 5 nIdIniPoint = 4 end end -- inserisco foro if nIdIniPoint and nIdEndPoint then local vtExtr if bSpecialMach then local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) vtExtr = vtN0 + vtN1 + vtN2 else -- versore direzione vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] end vtExtr:normalize() -- se foratura da sotto salto la lavorazione if vtExtr:getZ() < BD.DRILL_VZ_MIN then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling from bottom impossible' EgtOutLog( sErr) return false, sErr end -- recupero la lavorazione local sDrilling, nType = ML.FindDrilling( dDiam) if not sDrilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dMaxDepth = 20 local dDiamTool = 20 local dDiamTh = 35 local bIsDrilling if EgtMdbSetCurrMachining( sDrilling) then bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING) local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then if bIsDrilling then dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth else dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) dDiamTh = EgtTdbGetCurrToolThDiam() end end -- se foro inclinato, limito il massimo affondamento local CosB = abs( vtExtr:getX()) if CosB < BD.DRILL_VX_MAX then local TgA = CosB / sqrt( 1 - CosB * CosB) dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA else dMaxDepth = 0 end -- setto griglia if bSpecialMach then EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) else EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) end -- creo geometria local AuxId = EgtCircle( nAddGrpId, {0,0,0}, EgtIf( bIsDrilling, dDiamTool/2, ( dDiamTool/2) + 0.1), GDB_RT.GRID) -- riporto la griglia a globale EgtSetGridFrame() -- calcolo spessore local dDepthBore = dMaxLen if bSpecialMach then -- calcolo l'elevazione local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) if dLenIn > 0 then dDepthBore = dLenIn elseif dLedOut then dDepthBore = dLedOut end EgtModifyCurveThickness( AuxId, dDepthBore) else EgtModifyCurveThickness( AuxId, -dMaxLen) end -- inserisco la lavorazione local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchId = EgtAddMachining( sName, sDrilling) if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- imposto posizione braccio porta testa local nSCC = MCH_SCC.ADIR_YM if vtExtr:getY() > 100 * GEO.EPS_ZERO then nSCC = MCH_SCC.ADIR_YP end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- aggiusto l'affondamento local dDepth if bSpecialMach then dDepth = dDepthBore else dDepth = dMaxLen if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' dDepth = dMaxDepth EgtOutLog( sMyWarn .. ' (process ' .. tostring( Proc.Id) .. ')') end end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- Note utente con dichiarazione nessuna generazione sfridi per Vmill local sUserNotes = 'VMRS=0;' -- aggiungo alle note massima elevazione (coincide con affondamento) sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr else local _, sWarn = EgtGetMachMgrWarning( 0) if EgtIsMachiningEmpty() then EgtSetOperationMode( nMchId, false) return false, sWarn else return true, ( sMyWarn or sWarn) end end end return true, sMyWarn end --------------------------------------------------------------------- local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bForceUseBlade) -- Recupero le facce adiacenti alla principale local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] if not vAdj or #vAdj == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies' EgtOutLog( sErr) return false, sErr end EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) -- Cerco una faccia adiacente alla principale sul lato più lungo local nFacAdj local dMaxLen = 0 for i = 1, #vAdj do if vAdj[i] >= 0 then local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) local dLen = dist( ptP1, ptP2) if dLen > dMaxLen then nFacAdj = vAdj[i] dMaxLen = dLen EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) end end end if not nFacAdj then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' long adjacent face not found' EgtOutLog( sErr) return false, sErr end -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then dH, dV = dV, dH end -- Determino se estremi aperti o chiusi local bOpenStart = false local bOpenEnd = false local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) for j = 1, #vAdj2 do if vAdj2[j] == nFacInd then -- Se non esiste faccia adiacente a lato precedente -> inizio aperto local i = EgtIf( j > 1, j - 1, #vAdj2) while vAdj2[i] == nFacInd do i = EgtIf( i > 1, i - 1, #vAdj2) end bOpenStart = ( vAdj2[i] < 0) -- Se non esiste faccia adiacente a lato successivo -> fine aperto local k = EgtIf( j < #vAdj2, j + 1, 1) while vAdj2[k] == nFacInd do k = EgtIf( k < #vAdj2, k + 1, 1) end bOpenEnd = ( vAdj2[k] < 0) end end -- Recupero il massimo affondamento possibile con la lama local dSawMaxDepth = 0 local sCutting = ML.FindCutting( 'HeadSide') if sCutting then if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth end end end -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama if bOpenStart and bOpenEnd and bForceUseBlade and dElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then -- Recupero la lavorazione di lama local sCutting = ML.FindCutting( 'HeadSide') if not sCutting then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' EgtOutLog( sErr) return false, sErr, 'MNF' end -- recupero i dati dell'utensile local dSawDiam = 400 local dSawThick = 4 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 end end if dSawThick > dV + 10 * GEO.EPS_SMALL then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawblade too thick' EgtOutLog( sErr) return false, sErr end -- Calcolo uso faccia local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- Eseguo i tagli local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) local dStep = 0 if nStep > 1 then dStep = ( dV - dSawThick) / ( nStep - 1) end for i = 1, nStep do local dOffs = ( i - 1) * dStep local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- altrimenti con sega a catena else -- Calcolo uso faccia local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) -- Calcolo angolo 3° asse rot (da direz. utensile) local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) local ptP1, ptP2 = EgtSurfTmFacetOppositeSide( Proc.Id, nFacAdj, rfFac:getVersZ(), GDB_ID.ROOT) local vtT = vtN ^ (ptP2 - ptP1) vtT:normalize() local d3RotAng = EgtIf( abs( vtT:getZ()) < 0.1, 0, 90) -- Recupero la lavorazione local sSawing = ML.FindSawing( 'Sawing') if not sSawing then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chainsawing not found in library' EgtOutLog( sErr) return false, sErr, 'MNF' end -- Recupero i dati dell'utensile local dSawWidth = 75 local dSawThick = 8 local dMaxDepth = 200 if EgtMdbSetCurrMachining( sSawing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end if dSawThick > dV + 10 * GEO.EPS_SMALL then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chainsaw too thick' EgtOutLog( sErr) return false, sErr end -- Verifico se necessarie più passate local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) local dStep = 0 if nStep > 1 then dStep = ( dV - dSawThick) / ( nStep - 1) end for i = 1, nStep do -- Applico la lavorazione con sega a catena a questa faccia local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) local nMchFId = EgtAddMachining( sName, sSawing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- imposto accorciamento iniziale/finale per estremi aperti/chiusi EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) -- imposto angolo 3° asse rot EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=' .. EgtNumToString( d3RotAng)) -- imposto offset radiale local dOffs = ( i - 1) * dStep EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) -- se necessario, limito l'affondamento if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' dDepth = dMaxDepth - dElev EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) end -- imposto elevazione local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr elseif EgtIsMachiningEmpty() then local _, sWarn = EgtGetMachMgrWarning( 0) EgtSetOperationMode( nMchFId, false) return false, sWarn end end end return true, sWarn end --------------------------------------------------------------------- local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) -- Recupero la lavorazione di lama local sCutting = ML.FindCutting( 'HeadSide') if not sCutting then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dSawDiam = 400 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam end end -- eseguo il taglio return BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) end --------------------------------------------------------------------- local function EvaluateQParam( Proc, nRawId, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade) local nChamfer = 0 local bForceUseBlade = false local sErr -- verifico che lo smusso sia richiesto local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 if dDepth > 0 then nChamfer = 1 end -- verifico se posso fare solo lo smusso if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then if dDepth > 0 then nChamfer = nChamfer + 1 -- altrimenti se non ho l'affondamento esco else sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' EgtOutLog( sErr) return -1, dDepth, sErr end end -- verifico se devo usare lama invece della sega-catena -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente if #sUseBlade == 0 or EgtGetInfo( Proc.Id, sUseBlade, 'i') == 1 then bForceUseBlade = true end return nChamfer, dDepth, sErr, bForceUseBlade end --------------------------------------------------------------------- local function MakePocket( Proc, nPartId, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) -- calcolo l'elevazione dal punto medio local dElev local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) if dLenIn > 0 then dElev = dLenIn elseif dLedOut then dElev = dLedOut end local dCollSic = 2 * BD.COLL_SIC -- calcolo il diametro utensile local dDiamTool if nUseRoughTool == 1 and tDimAndRef then dDiamTool = max( 80, min( tDimAndRef[2][1], tDimAndRef[2][2])) elseif tDimAndRef then -- se non uso truciolatore prendo il valore dalle dimensioni minime delle facce dDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) end -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione if dPrevFaceElev and dPrevFaceElev > 0 and dAng then dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin(dAng)) end local sPocketing if sMasterPocket then sPocketing = sMasterPocket else sPocketing = ML.FindPocketing( sMchFind, dDiamTool, dElev + dCollSic) end if not sPocketing then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' EgtOutLog( sErr) return false, sErr end dDiamTool = 20 local dMaxDepth = 0 local sTuuidPk if EgtMdbSetCurrMachining( sPocketing) then sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) end end -- inserisco la lavorazione di svuotatura local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) local nMchFId = EgtAddMachining( sName, sPocketing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, (nFaceRef)}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) -- imposto posizione braccio porta testa if tvtN[2]:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end -- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) end -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente local sWarn if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dElev) dElev = dMaxDepth sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' EgtOutLog( sWarn) end -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) if not EgtApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end return true, sWarn, sTuuidPk, dDiamTool end --------------------------------------------------------------------- local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) local sMchFind = 'Pocket' local dAngLimit = 30 -- se feature é larga come trave imposto openpocket if nDiffWidth == 0 then sMchFind = 'OpenPocket' -- altrimenti non è passante disabilito il truciolatore e amplio il limite angolare -- per la differenza di lunghezza tra il truciolatore e la fresa più lunga else nUseRoughTool = 0 dAngLimit = 40 end -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto if ( 180 + dAng) > 90.1 then -- se la normale della faccia corta si discosta dalla trave di più di 45° utilizzo la svutatura altrimenti la contornatura if abs( tvtN[2]:getX()) < cos(dAngLimit) then -- se si discosta di più di 30° applico svuotatura -- applico la svuotatura return MakePocket( Proc, nPartId, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) -- altrimenti contornatura else local bOpenStart = false local bOpenEnd = false if nDiffWidth == 0 then bOpenStart = true bOpenEnd = true else local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] for j = 1, #vAdj2 do if vAdj2[j] == (nSideFace) then -- Se non esiste faccia adiacente a lato precedente -> inizio aperto local i = EgtIf( j > 1, j - 1, #vAdj2) while vAdj2[i] == (nSideFace) do i = EgtIf( i > 1, i - 1, #vAdj2) end bOpenStart = ( vAdj2[i] < 0) -- Se non esiste faccia adiacente a lato successivo -> fine aperto local k = EgtIf( j < #vAdj2, j + 1, 1) while vAdj2[k] == (nSideFace) do k = EgtIf( k < #vAdj2, k + 1, 1) end bOpenEnd = ( vAdj2[k] < 0) end end end local sMilling if nUseRoughTool > 0 then sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) else sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) 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 dTDiam = 50 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam end end -- Calcolo uso faccia local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) -- inserisco la lavorazione di fresatura local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sMilling) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- setto inversione del percorso EgtSetMachiningParam( MCH_MP.INVERT, true) -- setto a 0 eventuali offset EgtSetMachiningParam( MCH_MP.OFFSR, 0) -- calcolo elevazione per allungamenti attacchi con fianchi chiusi local dElev local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) if dLenIn > 0 then dElev = dLenIn elseif dLedOut then dElev = dLedOut end -- applico gli allungamenti o accorciamenti if bOpenStart then EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) if dElev > 0 then EgtSetMachiningParam( MCH_MP.LIPERP, dElev) end end if bOpenEnd then EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) else EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) if dElev > 0 then EgtSetMachiningParam( MCH_MP.LOPERP, dElev) end end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end end return true end --------------------------------------------------------------------- local function SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId, bStartPoint) -- fondo tra loro le curve compatibili EgtMergeCurvesInCurveCompo( nPathInt) local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) local pLastPIni, pLastPEnd -- faccio una copia della curva e la esplodo if nStartIdEnt then -- prendo i punti for i = 1, nNumEnt do local pPini = EgtUP( nPathInt, (i-1), GDB_RT.GLOB) local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) -- Se normale lungo la Z considero il box in X e Y if abs(vtOrtho:getZ()) > 0.999 then -- se corrisponde a X if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend -- altrimenti se corrisponde a Y elseif ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend end -- altrimenti se normale lungo la Y considero il box in X e Z elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.999 then -- se corrisponde a X if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend -- altrimenti se corrisponde a Z elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend end -- caso che non dovrebbe mai capitare ma gestito per completezza -- altrimenti se normale lungo la X considero il box in Y e Z elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.999 then -- se corrisponde a Y if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend -- altrimenti se corrisponde a Z elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then -- setto l'entità open local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' if #sActInfo > 0 then EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) else EgtSetInfo( nPathInt, 'OPEN', (i-1)) end -- prendo i punti per eventuale modifica del punto di inizio percorso pLastPIni = pPini pLastPEnd = pPend end end end -- se devo cambiare il punto di partenza if bStartPoint and pLastPIni and pLastPEnd then -- calcolo il punto medio con gli ultimi punti utilizzati local ptPs = ( pLastPIni + pLastPEnd) / 2 EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) end end end --------------------------------------------------------------------- local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, b3FacesUsed, b3Solid, bOrthoFacesMaster) local bOrthoFaces local sWarn local sMchFind = 'Pocket' local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt if sMchFindMaster and #sMchFindMaster > 0 then sMchFind = sMchFindMaster end if b3FacesUsed then -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed) if not nFacInd or nFacInd < 0 then if nFacInd == -1 then bOrthoFaces = nFacInd2 else local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeByPockets could not find reference face' EgtOutLog( sErr) return -1, sErr end end else bOrthoFaces = bOrthoFacesMaster end -- se è un tunnel provo a vedere se è possibile lavorarlo di con la svuotatura o con la sega catena if bOrthoFaces then -- ottengo le dimensioni del tunnel dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) -- verifico la direzione -- se devo inserire il chamfer if nChamfer > 0 then -- recupero la lavorazione local sMilling = ML.FindMilling( 'Mark') if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' EgtOutLog( sErr) return -1, sErr end -- ottengo le curve di contorno libero local nAuxId1, nNumIdAux if b3FacesUsed then nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, true) nNumIdAux = 2 else nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) end if nAuxId1 then local dExtra = 2 for i = 1, nNumIdAux do local AuxId if b3FacesUsed then if i == 1 then AuxId = nAuxId1 else -- faccio la copia del percorso AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) end else AuxId = nAuxId1 + i - 1 end local vtExtr, _, _ = EgtCurveArea( AuxId) local fFrCurve = EgtGetGlobFrame( AuxId) if vtExtr then vtExtr:toGlob( fFrCurve) if b3FacesUsed and i == nNumIdAux then vtExtr = -vtExtr end if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then -- inserisco la lavorazione local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) local nMchId = EgtAddMachining( sNameCh, sMilling) if not nMchId then local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling EgtOutLog( sErr) return -1, sErr end -- modifico estrusione percorso EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- imposto posizione braccio porta testa if vtExtr:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - EgtIf( b3FacesUsed, (dDepth / 2), 0)) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione if b3FacesUsed and i == nNumIdAux then EgtSetMachiningParam( MCH_MP.INVERT, true) end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return -1, sErr end -- se non perpendicolare emetto un warning -- else -- sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : chamfer skipped because not perpendicular to face or from bottom' -- EgtOutLog( sWarn) end --emetto un warning -- else -- sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : chamfer skipped because not perpendicular to face' -- EgtOutLog( sWarn) end end end end -- se smusso non è esclusivo if nChamfer < 2 then -- verifico se può essere fatto con svuotatura local bMakePocket, sPocketing, dMaxMat = VerifyIfPocket( Proc, dDimMin, vtOrtho, sMchFind) if bMakePocket then -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura -- e assegno l'estrusione local nPathInt, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) -- se ho 3 facce, ciclo sulle entià del percorso per segnare quelle che sono aperte if b3FacesUsed then SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId) end -- variabili per parametri lavorazione local dMachDepth local dElev = 0 local bDoubleSide -- se possibile svuotare completamente da una sola parte if dMaxMat > ( dDepth + 2) then dMachDepth = (dDepth / 2) + 2 dElev = dDepth else -- se direzione verso la verticale setto max affondamento possibile ed -- emetto messaggio di warning perché non lavorabile interamente if abs(vtOrtho:getZ()) >= 0.707 then dMachDepth = dMaxMat - (dDepth / 2) dElev = dMaxMat sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' EgtOutLog( sWarn) -- altrimenti setto il flag per fare la svuotatura da due parti else if dMaxMat > (dDepth / 2) then dMachDepth = 1 dElev = (dDepth / 2) + 1 else dMachDepth = dMaxMat - (dDepth / 2) dElev = dMaxMat end bDoubleSide = true end end -- inserisco la lavorazione di svuotatura local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sPocketing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing EgtOutLog( sErr) return -1, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ nPathInt, -1}}) -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) local bInvertMach if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) bInvertMach = true -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) bInvertMach = true end -- imposto posizione braccio porta testa if vtOrtho:getY() < GEO.EPS_SMALL then if bInvertMach then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) end else if bInvertMach then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end end -- se tasca aperta, imposto opportuno attacco if sMchFind == 'OpenPocket' then EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) end -- inverto il percorso di lavorazione per lavorare sinistro EgtSetMachiningParam( MCH_MP.INVERT, true) -- imposto affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not EgtApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return -1, sErr end end -- se posso applicare la svuotatura sul lato opposto if bDoubleSide then -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura -- setto i parametri affondamento ed emetto warning if dMaxMat*2 < dDepth then dMachDepth = dMaxMat - (dDepth / 2) dElev = dMaxMat sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' EgtOutLog( sWarn) end -- inserisco la lavorazione di svuotatura local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sPocketing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing EgtOutLog( sErr) return -1, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ nPathInt, -1}}) -- imposto direzione utensile opposta EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) -- imposto posizione braccio porta testa if vtOrtho:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) end -- se tasca aperta, imposto opportuno attacco if sMchFind == 'OpenPocket' then EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) end -- inverto il percorso di lavorazione per lavorare sinistro EgtSetMachiningParam( MCH_MP.INVERT, true) -- imposo affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not EgtApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return -1, sErr end end end return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace end end end return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace end --------------------------------------------------------------------- local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId) local sWarn -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- recupero l'ingombro della trave local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' EgtOutLog( sErr) return false, sErr end local bClosedOrthoFaces -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) if not nFacInd or nFacInd < 0 then if nFacInd == -1 then bClosedOrthoFaces = nFacInd2 else local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMoreFaces could not find reference face' EgtOutLog( sErr) return false, sErr end end -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' EgtOutLog( sErr) return false, sErr end -- verifico se sono presenti i parametri Q per la profondità smusso e -- per eseguire in esclusiva solo lo smusso local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc, nRawId, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer -- genero errore e non faccio nulla if nChamfer < 0 then return false, sErrCham end -- se è un tunnel provo a vedere se è possibile lavorarlo di con la svuotatura o con la sega catena if bClosedOrthoFaces then local bTryWithBlades = true -- lavoro fessura con svuotature (singola o doppia contrapposta) local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, 'Pocket', false, b3Solid, bClosedOrthoFaces) if nOk < 0 then return false, sErr elseif nOk > 0 then bTryWithBlades = false end -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena if bTryWithBlades and nChamfer < 2 then -- verifico se posso farlo con la sega-catena local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) if bMakeChainSaw then -- Verifico se necessarie più passate local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) local dStep = 0 if nStep > 1 then dStep = ( dDimMin - dSawThick) / ( nStep - 1) end for i = 1, nStep do -- inserisco la lavorazione di sawing local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) local nMchFId = EgtAddMachining( sName, sSawing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) -- imposto uso del lato faccia -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X if abs(vtOrtho:getZ()) >= 0.707 then EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) --elseif abs(vtOrtho:getZ()) < 0.707 and abs(vtOrtho:getY()) > 0.707 then else EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) --elseif abs(vtOrtho:getZ()) <= 0.707 and vtOrtho:getY() < -0.707 then -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) --elseif abs(vtOrtho:getZ()) < 0.707 and vtOrtho:getX() > 0.707 then -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) --else -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) end -- imposto offset radiale local dOffs = ( i - 1) * dStep EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) -- se possibile aumento l'affondamento pari al raggio corner + 1 if dMaxMat > (dDepth + dSawCornerRad + 1) then EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning elseif dMaxMat < dDepth then EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' EgtOutLog( sWarn) end -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr elseif EgtIsMachiningEmpty() then _, sWarn = EgtGetMachMgrWarning( 0) EgtSetOperationMode( nMchFId, false) return false, sWarn end end end end -- altrimenti non è una fessura else -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) -- verifico se U local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) -- verifico se due facce o L con una o due facce di terminazione local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia local bMakeBySideMill, bHead, sMilling, dMaxMat = VerifyIfByBHSideMill( Proc) if bMakeBySideMill and ( dMaxMat <= dV) then -- se smusso non è esclusivo if nChamfer < 2 then -- inserisco la lavorazione di fresatura local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sMilling) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) -- imposto uso del lato faccia EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) -- calcolo step effettivo ed elevazione local dVcalc = dV - dMaxMat local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat local nStep = ceil( dVcalc / dStep) dStep = dVcalc / nStep EgtSetMachiningParam( MCH_MP.STEP, dStep) -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end -- altrimenti lavoro con svuotatura else -- se smusso non è esclusivo if nChamfer < 2 then local bSpecial3faces = false -- verifico se sono nel caso in cui la faccia esclusa ha elevazione più alta -- in ogni caso a parità di adiacenze la funzione BL.GetFaceWithMostAdj restituisce le facce con minore elevazione -- if not bIsU and bIsL and Proc.Fct <= 3 and nFacInd ~= 0 and nFacInd2 ~= 0 then if not bIsU and bIsL and Proc.Fct <= 3 then -- verifico se l'elevazione della faccia esclusa è maggiore dell'elevazione delle altre due facce local nFaceMaxElev = 0 if Proc.Fct == 3 then for i = 1, Proc.Fct do if (i-1) ~= nFacInd and (i-1) ~= nFacInd2 then nFaceMaxElev = (i-1) end end end local rfFac0 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceMaxElev, GDB_ID.ROOT) -- ottengo il box con la normale della faccia 0 local bBoxF0 = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac0) local dElevF0 = bBoxF0:getDimZ() -- se effettivamente l'elevazione della faccia esclusa è maggiore delle altre elevazioni segno il flag per le 3 facce speciali if dElevF0 > dFacElev and dElevF0 > dFacElev2 then bSpecial3faces = true end end -- se lavorazioni di svuotatura e contornatura if bSpecial3faces then -- entrambe le facce non devono essere orientate verso il basso local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) -- se orientata verso il basso, verifico l'alternativa if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' special LapJoint from bottom impossible' EgtOutLog( sErr) return false, sErr end rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) -- eventuali tagli preliminari do local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) if not bOk then return false, sErr end end -- Recupero la lavorazione di fresa local sMilling = ML.FindMilling( 'LongSmallCut') if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) return false, sErr end -- Recupero la lavorazione di svuotatura local sMchFind = 'OpenPocket' local dDiam = min( dH, dV) local dDiam2 = min( dH2, dV2) local dCollSic = 2 * BD.COLL_SIC local dCollSic2 = 2 * BD.COLL_SIC if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia if not sPocketing then dDiam, dDiam2 = dDiam2, dDiam dCollSic, dCollSic2 = dCollSic2, dCollSic nFacInd, nFacInd2 = nFacInd2, nFacInd dH, dH2 = dH2, dH dV, dV2 = dV2, dV dFacElev, dFacElev2 = dFacElev2, dFacElev rfFac, rfFac2 = rfFac2, rfFac vtN, vtN2 = vtN2, vtN sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) if not sPocketing then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' EgtOutLog( sErr) return false, sErr end end -- provo con contornatura local dDiamTool = 20 if bIsL then local bOk, sErr bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, true, sMilling, nFacInd2, dFacElev2) if not bOk then return bOk, sWarn end else local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Impossible mill special LapJoint' EgtOutLog( sErr) return false, sErr end -- inserisco la lavorazione di svuotatura local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sPocketing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacInd2}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) -- imposto posizione braccio porta testa if vtN:getY() < GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end -- se tasca aperta, imposto opportuno attacco if sMchFind == 'OpenPocket' then EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) end -- imposto elevazione local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev2, 1) .. ';' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not EgtApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end -- se abilitato dal parametro Q inserisco foro sullo spigolo if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then local bOk bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true) if not bOk then return false, sWarn end end -- altrimenti lavorazione di svuotatura o contornatura else -- se orientata verso il basso, verifico l'alternativa if vtN:getZ() < BD.NZ_MINA and nFacInd2 then ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) nFacInd, nFacInd2 = nFacInd2, nFacInd dFacElev, dFacElev2 = dFacElev2, dFacElev end rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) -- verifico non sia orientata verso il basso local bFaceOk = ( vtN:getZ() >= BD.NZ_MINA) if not bFaceOk then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' EgtOutLog( sErr) return false, sErr end -- eventuali tagli preliminari do local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) if not bOk then return false, sErr end end -- recupero la lavorazione local nUseRoughTool = 0 local sMchFind = 'Pocket' if Proc.Fct < 3 or bIsU or bIsL then sMchFind = 'OpenPocket' -- abilito il truciolatore nUseRoughTool = 1 end local dDiam = min( dH, dV) local dCollSic = 2 * BD.COLL_SIC if abs( vtN:getX()) > 0.996 or abs( vtN:getY()) > 0.996 or abs( vtN:getZ()) > 0.996 then dCollSic = 0 end --EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam)) local sPocketing = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) -- se non trova una svuotatura adatta if not sPocketing then -- provo con contornatura if bIsL then return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev) -- altrimenti provo con la sega a catena o lama else local bTryWithBlades = true local nOk, bOk, sErr, sStat -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e -- se non è possibile allora provo in seguito con lama o segacatena -- o passare subito dalla lavorazione con lama/sega catena if bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then nOk, sWarn = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, 'OpenPocket', true, b3Solid) if nOk < 0 then return false, sWarn elseif nOk > 0 then bTryWithBlades = false end bOk = true end -- Se la svuotatura precedente non è stata fatta provo con le lame if bTryWithBlades then bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, bForceUseBlade) if not bOk and sStat == 'MNF' then sPocketing = ML.FindPocketing( sMchFind, dDiam) if not sPocketing then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' EgtOutLog( sErr) return false, sErr end else return bOk, sWarn end -- altrimenti ho già svuotato dal fianco, esco else return bOk, sWarn end end end -- se richiesti antischeggia con lama su U trasversale -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa local bMadeASbyBld = false if EgtGetInfo( Proc.Id, sAntisplintMode, 'i') == 1 and bIsU and ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) then -- va eseguito sulle facce diverse dalla principale for nFacet = 0, 2 do if nFacet ~= nFacInd then bMadeASbyBld, sWarn = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) if not bMadeASbyBld then return false, sWarn end end end end -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale local tvtNx = {} tvtNx[2] = vtN local bOk bOk, sWarn, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev) if not bOk then return false, sWarn end -- se ho più di 3 facce e non di forma ad u oppure ho 3 facce e di forma ad u -- e non sono stati inseriti antischeggia di lama -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then -- Recupero le facce adiacenti alla principale local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] if not vAdj or #vAdj == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies' EgtOutLog( sErr) return false, sErr end -- Cerco una faccia adiacente alla principale con angolo > 90 local nFacAdj local tDimAndRef = {} tvtNx = {} tvtNx[1] = vtN tDimAndRef[1] = {dH, dV, rfFac} for i = 1, #vAdj do if vAdj[i] >= 0 then local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) if bAdj and dAng < 0 and 180 + dAng > 90.1 then local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) tDimAndRef[2] = {dH2, dV2, rfFac2} local ptPs = ( ptP1 + ptP2) / 2 local bOk bOk, sWarn = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef, b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev) if not bOk then return bOk, sWarn end end end end end -- se abilitato dal parametro Q inserisco foro sullo spigolo if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then local bOk bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) if not bOk then return false, sWarn end elseif EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 2 then local bOk bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) if not bOk then return false, sWarn end end end end end end return true, sWarn end --------------------------------------------------------------------- local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' EgtOutLog( sErr) return false, sErr end -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- la divido in parti lungo X local vAddId = {} local nPart = ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN) local dPartLen = Proc.Box:getDimX() / nPart local Xmin = Proc.Box:getMin():getX() for i = 1, nPart do -- eseguo divisione local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) if i > 1 then local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) end if i < nPart then local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) end table.insert( vAddId, AddId) end -- applico le lavorazioni sulle diverse parti local sWarn for i = 1, #vAddId do local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) local nFct = EgtSurfTmFacetCount( vAddId[i]) local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, Fct = nFct, Flg = Proc.Flg} local bOk, sMyWarn = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId) if not bOk then return bOk, sWarn end if not sWarn then sWarn = sMyWarn end end return true, sWarn end --------------------------------------------------------------------- -- Applicazione della lavorazione --------------------------------------------------------------------- function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- limiti di fresatura semplice local MAX_MILL_LIN = 80 -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- in base al tipo di feature attribuisco il significato dei parametri Q AssignQValues( Proc) -- se lunghezza richiede spezzatura if Proc.Box:getDimX() > BD.LONGCUT_MAXLEN then -- una faccia if Proc.Fct == 1 then return LongCut.Make( Proc, nPhase, nRawId, nPartId) -- due facce elseif Proc.Fct == 2 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) if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then return Long2Cut.Make( Proc, nPhase, nRawId, nPartId) elseif b3Fac1:getDimX() < 1 then -- la faccia 0 deve essere quella lunga EgtSurfTmSwapFacets( Proc.Id, 0, 1) return LongCut.Make( Proc, nPhase, nRawId, nPartId) elseif b3Fac2:getDimX() < 1 then return LongCut.Make( Proc, nPhase, nRawId, nPartId) else return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) end -- tre o più facce else return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) end -- altrimenti lavorazione unica else -- una faccia if Proc.Fct == 1 then local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1 -- se piccola, con fresa if not bForcedBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) -- altrimenti, con lama else return Cut.Make( Proc, nPhase, nRawId, nPartId, 0) end -- due facce elseif Proc.Fct == 2 then -- determino l'angolo tra le facce local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1 -- se ortogonali e piccole, con fresa if not bForcedBlade and bAdj and abs( dAng + 90) < 1 and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) -- altrimenti, con lama else return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') end -- tre o più facce else return MakeMoreFaces( Proc, nPhase, nRawId, nPartId) end end end --------------------------------------------------------------------- return ProcessLapJoint