-- ProcessFreeContour.lua by Egaltech s.r.l. 2022/11/03 -- Gestione calcolo profilo libero per Travi -- 2022/08/23 Aggiunta la funzione MakeByMark per la gestione del caso P13=10 -- 2022/09/21 In MakeByMill aggiunto messaggio per elevazione non raggiunta. -- 2022/11/03 In MakeByMill migliorata gestione lavorazione con fresa su testa da sotto. -- 2022/11/09 Aggiunta la gestione della chiamata della FreeContour da parte della SimpleScarf. -- 2022/11/24 In MakeByMill aggiunta la lavorazione sopra/sotto nel caso di testa sotto -- In MakeByMill se BeamData forza lettura codolo da Q questo viene sempre fatto indipendentemente dalle dimensioni della feature -- Tabella per definizione modulo local ProcessFreeContour = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') EgtOutLog( ' ProcessFreeContour started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') -- variabili assegnazione parametri Q local Q_DIM_STRIP = 'Q01' -- d local Q_DEPTH_CHAMFER = 'Q02' -- d local Q_OVERMAT_FOR_FINISH = 'Q03' -- d local Q_ONLY_CHAMFER = 'Q00' -- i --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessFreeContour.Identify( Proc) return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 250) end --------------------------------------------------------------------- -- Verifica se feature di testa function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) -- 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 la metà della lunghezza della trave if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then return false end -- se pocket, ne verifico la direzione di lavorazione local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) if bPocket then local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if not AuxId then return false end AuxId = AuxId + Proc.Id local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) return ( vtN:getX() >= 0.5) end -- deve occupare una buona parte dell'area if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then return true end -- non è di testa return false end --------------------------------------------------------------------- -- Verifica se feature di coda function ProcessFreeContour.IsTailFeature( Proc, b3Raw) -- 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 la metà della lunghezza della trave if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then return false end -- se pocket, ne verifico la direzione di lavorazione local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) if bPocket then local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if not AuxId then return false end AuxId = AuxId + Proc.Id local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) return ( vtN:getX() <= - 0.5) end -- deve occupare una buona parte dell'area if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then return true end -- non è di coda return false end --------------------------------------------------------------------- -- Classificazione della feature function ProcessFreeContour.Classify( Proc, b3Raw) -- verifico se di tipo pocket local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) -- recupero la curva associata local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if not AuxId then return false end AuxId = AuxId + Proc.Id local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- se tasca if bPocket then local bDown = ( vtN:getZ() < - 0.5) return true, bDown, false -- se altrimenti profilo orizzontale elseif abs( vtN:getZ()) < 0.5 then return true, false, false -- se altrimenti profilo verticale che non interessa tutta la sezione elseif Proc.Box:getDimZ() < 0.9 * b3Raw:getDimZ() then local bDown = ( vtN:getZ() < - 0.5) return true, bDown, false -- altrimenti è profilo verticale che interessa tutta la sezione else -- recupero la massima capacità di lavoro dell'utensile da utilizzare local sMilling, dMaxDepth = ML.FindMilling( 'FreeContour') if not sMilling then dMaxDepth = 0 end if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then return true, false, true else return true, false, false end end end --------------------------------------------------------------------- local function VerifyChamfer( Proc, AuxId, nRawId, bMakeVertCham, bDownHead) local nChamfer = 0 -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- verifico che lo smusso sia richiesto local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0 if dDepth > 0 then nChamfer = 1 end -- verifico se posso fare solo lo smusso if EgtGetInfo( Proc.Id, Q_ONLY_CHAMFER, 'i') == 1 then if dDepth > 0 then nChamfer = nChamfer + 1 -- altrimenti se non ho l'affondamento esco else local sErr = 'Error : no chamfer depth' EgtOutLog( sErr) return -1, dDepth, sErr end end -- recupero i dati della curva e del profilo local dWidth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato if abs( vtExtr:getZ()) > 0.1 then if not bMakeVertCham then if nChamfer == 2 then -- se devo fare solo smusso, genero errore local sErr = 'Error : not horizontal chamfer' EgtOutLog( sErr) return -1, dDepth, sErr else local sWarn = 'Warning : skipped not horizontal chamfer' EgtOutLog( sWarn) return 0, dDepth end end end -- recupero la lavorazione local sMilling if nChamfer > 0 then if bDownHead then sMilling = ML.FindMilling( 'Mark_H2', nil, nil, nil, nil, false, true) else sMilling = ML.FindMilling( 'Mark') end if not sMilling then local sErr = 'Error : Mark not found in library' EgtOutLog( sErr) return -1, 0, sErr end end return nChamfer, dDepth, sMilling end --------------------------------------------------------------------- local function CalcCollisionSafety( vtDir) local dCollSic = 10 * BD.COLL_SIC if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then dCollSic = 0 elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then dCollSic = 1 * BD.COLL_SIC elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then dCollSic = 2.5 * BD.COLL_SIC elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then dCollSic = 4 * BD.COLL_SIC elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then dCollSic = 5.5 * BD.COLL_SIC end return dCollSic end --------------------------------------------------------------------- local function CalcSpecialAdd( nCrv, bStartVsEnd, dToolDiam) -- recupero il dominio della curva local nUi, nUf = EgtCurveDomain( nCrv) if not nUi then return 0 end -- indici punti da analizzare local nOut = EgtIf( bStartVsEnd, nUi, nUf) local nIn = EgtIf( bStartVsEnd, nUi + 1, nUf - 1) -- tangenti prima e dopo il punto interno local vtPrev = EgtUV( nCrv, nIn, -1) local vtNext = EgtUV( nCrv, nIn, 1) -- se c'è perdita di tangenza (delta angolare oltre i 5 gradi) if vtPrev * vtNext < 0.996 then -- lunghezza del tratto local ptP0 = EgtUP( nCrv, nOut) local ptP1 = EgtUP( nCrv, nIn) local dDist = dist( ptP0, ptP1) -- se corto rispetto al raggio utensile, ritorno allugamento opportuno if dDist < 0.6 * dToolDiam then return ( 0.6 * dToolDiam - dDist + 1) end end return 0 end --------------------------------------------------------------------- local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- ingombro del pezzo local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error : part box not found' EgtOutLog( sErr) return false, sErr end -- recupero e verifico l'entità curva local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 if AuxId then AuxId = AuxId + Proc.Id end if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then local sErr = 'Error : missing profile geometry' EgtOutLog( sErr) return false, sErr end -- recupero i dati della curva e del profilo local dDepth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) -- verifico se in testa o coda local bHead = Proc.Head -- verifico i parametri Q per profondità smusso e per eseguirlo in esclusiva local nChamfer, dDepthCham, sChamfer = VerifyChamfer( Proc, AuxId, nRawId, true) -- recupero la lavorazione local bTopHead = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.1) local bDownHead = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.1) local sMilling, _, _, bH2 = ML.FindMilling( 'FreeContour', nil, nil, nil, nil, bTopHead, bDownHead) if not sMilling then local sErr = 'Error : FreeContour not found in library' EgtOutLog( sErr) return false, sErr end bDownHead = ( bDownHead and bH2) local bToolInv = ( not bDownHead and vtExtr:getZ() < -0.1 and b3Aux:getDimZ() > b3Raw:getDimZ() - 5) -- recupero i dati dell'utensile local dToolDiam = 10 local dMaxDepth = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end local dCollSic = CalcCollisionSafety( vtExtr) dMaxDepth = dMaxDepth - dCollSic -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio local nStep = 1 local dStep = 0 local dLenMax = BD.LONGCUT_ENDLEN if b3Aux:getDimX() > dLenMax then local dCrvLen = EgtCurveLength( AuxId) nStep = ceil( dCrvLen / dLenMax) dStep = dCrvLen / nStep EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) end -- eventuale spezzatura sul tratto più lungo se curva chiusa BL.PutStartOnLonger( AuxId) -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) local nSide = 0 -- verifiche per affondamento ( possibili lavorazioni in doppio) local bCross = false if abs( vtExtr:getX()) < 0.707 then if abs( vtExtr:getY()) > abs( vtExtr:getZ()) then if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then bCross = true dDepth = min( dDepth, b3Raw:getDimY() / abs( vtExtr:getY())) end if bDown then nSide = -1 else nSide = 1 end else if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then bCross = true dDepth = min( dDepth, b3Raw:getDimZ() / abs( vtExtr:getZ())) end end end local dOriDepth = dDepth local nDouble = 1 local bCanDouble = ( abs( vtExtr:getY()) > abs( vtExtr:getZ()) and bCross) or ( BD.DOWN_HEAD and bCross) local dDimStrip = BD.DIM_STRIP if dDimStrip < 0 then dDimStrip = EgtGetInfo( Proc.Id, Q_DIM_STRIP, 'd') or 0 end local bStripOnSide = false if bCross then -- se forzata da parametro Q il codolo è sempre attivo if dDimStrip > 10 * GEO.EPS_SMALL and ( BD.DIM_STRIP < 0 or nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX())) then -- devo lasciare un codolo local dExtraCham = EgtIf( nChamfer > 0, 2, 0) dDepth = EgtIf( Proc.Prc == 70, dDepth - dDimStrip - dDepthCham - dExtraCham, dDepth - dDimStrip) bStripOnSide = true else -- devo affondare un poco oltre dDepth = dDepth + BD.CUT_EXTRA end end local bIsDepthReduced = false -- se parametro beamdata forza codolo in centro e lavorazione orizzontale e se larghezza trave è sufficientemente larga -- se forzata da parametro Q il codolo è sempre attivo local dDepthWork = dDepth if BD.DIM_TO_CENTER_STRIP and BD.DIM_TO_CENTER_STRIP > 10 * GEO.EPS_SMALL and ( BD.DIM_STRIP < 0 or nStep > 1) and bCanDouble and b3Raw:getDimY() > BD.DIM_TO_CENTER_STRIP - 0.1 then nDouble = 2 dDepth = min( ( b3Raw:getDimY() - dDimStrip) * 0.5, dMaxDepth) else -- se altezza geometria supera capacità taglio utensile ed è orizzontale setto per eseguire codolo in centro if dDepth > dMaxDepth then if bCanDouble then nDouble = 2 dDepthWork = 0.5 * dDepth dDepth = min( dDepthWork, dMaxDepth) if dDepth < dDepthWork - 10 * GEO.EPS_SMALL then bIsDepthReduced = true end else dDepth = dMaxDepth bIsDepthReduced = true end end end local sWarn = '' -- se ho ridotto l'altezza emetto warning if bIsDepthReduced then sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' (Free Contour) : depth (' .. EgtNumToString( dDepthWork, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' EgtOutLog( sWarn) end -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then bToolInv = true end -- verifico se primo e ultimo tratti corti e con angolo local dStartAddSpec = 0 if Proc.Grp ~= 0 then dStartAddSpec = CalcSpecialAdd( AuxId, true, dToolDiam) end local dEndAddSpec = 0 if Proc.Grp ~= 0 then dEndAddSpec = CalcSpecialAdd( AuxId, false, dToolDiam) end -- se devo inserire il chamfer if nChamfer > 0 and Proc.Grp ~= 0 and dOriDepth > dDepthCham and Proc.Prc ~= 70 then local bDoubleCham = false local dExtra = 2 local sChamferDown, sChamferUp if nDouble > 1 and bCanDouble then if nSide == 0 then if BD.DOWN_HEAD then -- recupero la lavorazione local nChamferDown nChamferDown, _, sChamferDown = VerifyChamfer( Proc, AuxId, nRawId, true, true) if nChamferDown < 0 then sWarn = 'Warning : chamfer from bottom not found in library' sChamferDown = nil EgtOutLog( sWarn) end end local nChamferUp nChamferUp, _, sChamferUp = VerifyChamfer( Proc, AuxId, nRawId, true, false) if nChamferUp < 0 then sWarn = 'Warning : chamfer from bottom not found in library' sChamferUp = nil EgtOutLog( sWarn) end end end -- eseguo for i = 1, nStep do -- inserisco la lavorazione local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local sChamferSide1 = EgtIf( bDownHead, sChamferDown, sChamfer) local nMchId = EgtAddMachining( sNameCh, sChamferSide1) if not nMchId then local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- se lavorazione da sopra o da sotto if Proc.Grp == 3 then if not bToolInv then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) EgtSetMachiningParam( MCH_MP.INVERT, true) else if not bDownHead and vtExtr:getZ() < 0 then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.INVERT, true) EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) else EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.INVERT, true) end end end if Proc.Grp == 4 then if not bToolInv then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.INVERT, true) else if not bDownHead and vtExtr:getZ() < 0 then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) EgtSetMachiningParam( MCH_MP.INVERT, true) EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) else EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) end end end if nSide == 0 then bDoubleCham = EgtIf( sChamferDown and BD.DOWN_HEAD, true, false) else bDoubleCham = true end -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- eventuale accorciamento di testa if i > 1 then local dStartAddLen = - ( i - 1) * dStep EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) end -- eventuale accorciamento di coda if i < nStep then local dEndAddLen = - ( nStep - i) * dStep EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) else EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) end -- posizione braccio porta testa local nSCC = MCH_SCC.NONE if not BD.C_SIMM then if Proc.Head then nSCC = MCH_SCC.ADIR_XP elseif Proc.Tail then nSCC = MCH_SCC.ADIR_XM elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then nSCC = MCH_SCC.ADIR_YP elseif vtExtr:getY() > -0.01 then nSCC = MCH_SCC.ADIR_YP else nSCC = MCH_SCC.ADIR_YM end end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end -- se lavorazione da due parti, aggiungo la seconda if bDoubleCham then -- inserisco la lavorazione local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local sChamferSide2 if EgtEndsWith( sChamferSide1, 'H2') then sChamferSide2 = sChamferUp elseif nSide == 0 then sChamferSide2 = sChamferDown else sChamferSide2 = sChamfer end nMchId = EgtAddMachining( sName, sChamferSide2) if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) if Proc.Grp == 3 then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) EgtSetMachiningParam( MCH_MP.INVERT, true) elseif Proc.Grp == 4 then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) EgtSetMachiningParam( MCH_MP.INVERT, true) end -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- eventuale accorciamento di testa if i < nStep then local dEndAddLen = - ( nStep - i) * dStep EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) else EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) end -- eventuale accorciamento di coda if i > 1 then local dStartAddLen = - ( i - 1) * dStep EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) end -- posizione braccio porta testa local nSCC = MCH_SCC.NONE if not BD.C_SIMM then if Proc.Head then nSCC = MCH_SCC.ADIR_XP elseif Proc.Tail then nSCC = MCH_SCC.ADIR_XM elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then nSCC = MCH_SCC.ADIR_YP elseif vtExtr:getY() < 0.01 then nSCC = MCH_SCC.ADIR_YP else nSCC = MCH_SCC.ADIR_YM end end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end end end end -- verifico se devo fare sgrossatura più finitura local dOffsetPar = EgtGetInfo( Proc.Id, Q_OVERMAT_FOR_FINISH, 'i') or 0 -- nel caso di lavorazioni sopra/sotto cerco lavorazioni specifiche local sMillingDown, sMillingUp if nDouble > 1 and bCanDouble then if nSide == 0 then if BD.DOWN_HEAD then -- recupero la lavorazione sMillingDown = ML.FindMilling( 'FreeContour_H2', nil, nil, nil, nil, false, true) if not sMillingDown then nDouble = 1 dDepth = min( dOriDepth, dMaxDepth) sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' (Free Contour) : milling from bottom not found in library' .. '\n' .. '; depth (' .. EgtNumToString( dOriDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' EgtOutLog( sWarn) elseif sMillingDown and not bDownHead then bToolInv = true sMilling = sMillingDown end end sMillingUp = ML.FindMilling( 'FreeContour', nil, nil, nil, nil, true, false) if not sMillingUp then sWarn = 'Warning : milling not found in library' EgtOutLog( sWarn) end end end -- eseguo for i = 1, nStep do for j = 1, nDouble do local sName local nMchId local bEnableCham -- se ho smusso abilitato e profondità geometria minore della profondità smusso, -- applico lavorazione smusso if nChamfer > 0 and dOriDepth <= dDepthCham then -- inserisco la lavorazione sName = 'FreeCham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) nMchId = EgtAddMachining( sName, sChamfer) if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer EgtOutLog( sErr) return false, sErr end dOffsetPar = 0 -- assegno affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham) bEnableCham = true else -- inserisco la lavorazione sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) if EgtEndsWith( sMilling, '_H2') then nMchId = EgtAddMachining( sName, EgtIf( j == 2 and nSide == 0, sMillingUp, sMilling)) elseif sMillingDown then nMchId = EgtAddMachining( sName, EgtIf( j == 2 and nSide == 0, sMillingDown, sMilling)) else nMchId = EgtAddMachining( sName, sMilling) end if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- assegno affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- eventuale accorciamento di testa if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) else EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( j == 1, dStartAddSpec, dEndAddSpec)) end -- eventuale accorciamento di coda if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) else EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( j == 1, dEndAddSpec, dStartAddSpec)) end -- se estrusione da sotto, inverto direzione fresa if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) end -- se seconda passata, inverto direzione di lavoro if j == 2 then EgtSetMachiningParam( MCH_MP.INVERT, true) end -- assegno lato di lavoro if Proc.Grp == 0 then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) elseif ( Proc.Grp == 3 and not bToolInv) or ( Proc.Grp == 4 and bToolInv) or ( Proc.Grp == 1 and bToolInv) or ( Proc.Grp == 2 and bToolInv) then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) elseif ( Proc.Grp == 3 and bToolInv) or ( Proc.Grp == 4 and not bToolInv) or ( Proc.Grp == 1 and not bToolInv) or ( Proc.Grp == 2 and not bToolInv) then EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) end -- posizione braccio porta testa local nSCC = MCH_SCC.NONE if not BD.C_SIMM then if Proc.Head then nSCC = MCH_SCC.ADIR_XP elseif Proc.Tail then nSCC = MCH_SCC.ADIR_XM elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then nSCC = MCH_SCC.ADIR_YP elseif ( j == 1 and vtExtr:getY() > -0.01) or ( j == 2 and vtExtr:getY() < 0.01) then nSCC = MCH_SCC.ADIR_YP else nSCC = MCH_SCC.ADIR_YM end end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- acquisisco parametro sovramateriale local bFinish local dOriOffset = 0 -- se parametro sovramateriale è maggiore di 0 abilito la finitura extra if not bEnableCham and dOffsetPar > 0 then EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) bFinish = true elseif bEnableCham and Proc.Grp ~= 0 then EgtSetMachiningParam( MCH_MP.OFFSR, dDepthCham) end -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end -- se abilitata, aggiungo lavorazione di finitura if bFinish then -- inserisco la lavorazione local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) if not nMch2Id then local sErr = 'Error adding machining ' .. sNewName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr else -- riporto il sovramateriale originale e tolgo i passi EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) EgtSetMachiningParam( MCH_MP.STEP, 0) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMch2Id, false) return false, sErr end end end end end -- eventuale segnalazione ingombro di testa o coda local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) if Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then if Proc.Head then local dOffs = b3Raw:getMax():getX() - dOvmHead - 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, sWarn end --------------------------------------------------------------------- local function MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) -- recupero e verifico l'entità curva local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 if AuxId then AuxId = AuxId + Proc.Id end if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' EgtOutLog( sErr) return false, sErr end -- recupero i dati della curva e del profilo local dDepth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) --local bToolInv = ( vtExtr:getZ() < -0.1) -- recupero la lavorazione local sPocketing = ML.FindPocketing( 'Pocket', nil, dDepth) if not sPocketing then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dMillDiam = 20 local dMaxDepth = 0 if EgtMdbSetCurrMachining( sPocketing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth 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 false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- imposto posizione braccio porta testa if vtExtr:getY() <= 0 then EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) else EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) end -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then dDepth = dMaxDepth local sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' EgtOutLog( sWarn) end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- imposto elevazione EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';') -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true end --------------------------------------------------------------------- local function MakeByMark( Proc, nRawId, b3Raw, nPartId) -- ingombro del pezzo local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error : part box not found' EgtOutLog( sErr) return false, sErr end -- recupero e verifico l'entità curva local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 if AuxId then AuxId = AuxId + Proc.Id end if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then local sErr = 'Error : missing profile geometry' EgtOutLog( sErr) return false, sErr end -- recupero i dati della curva e del profilo local dDepth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) local bToolInv = ( vtExtr:getZ() < -0.1 and b3Aux:getDimZ() > b3Raw:getDimZ() - 5) -- verifico che la marcatura non sia orientata verso il basso (-5 deg) if vtExtr:getZ() < - 0.1 and not BD.DOWN_HEAD and not BD.TURN then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' EgtOutLog( sErr) return false, sErr end -- abilitazione lavorazione da sotto local bMillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174) -- recupero la lavorazione local sMillType = 'Text' --local sMchExt = EgtIf( bMillDown, '_H2', '') local sMilling = ML.FindMilling( sMillType, nil, nil, nil, nil, bMillUp, bMillDown) 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 local sName = 'FreeMark_' .. ( 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 EgtSetInfo( nMchId, 'Part', Proc.PartId) -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- se estrusione da sotto, inverto direzione fresa if bToolInv then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) end -- posizione braccio porta testa local nSCC = MCH_SCC.ADIR_ZP if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) end EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end return true end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessFreeContour.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- riassegno Q nel caso la funzione sia richiamata da un'altra make if Proc.Prc == 70 then Q_DEPTH_CHAMFER = 'Q01' Q_DIM_STRIP = 'Q02' elseif Proc.Prc == 30 then Q_DEPTH_CHAMFER = 'Q01' Q_DIM_STRIP = 'Q02' end -- recupero la tipologia local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) -- se svuotatura if bPocket then return MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) -- altrimenti contornatura else -- recupero il tipo di lavorazione local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 -- se marcatura if nCntType == 10 then return MakeByMark( Proc, nRawId, b3Raw, nPartId) -- se fresatura else return MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) end end end --------------------------------------------------------------------- return ProcessFreeContour