diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 474c150..4f56717 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -679,11 +679,13 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) end elseif Proc.Flg == 0 then bAllOk = false - table.insert( Stats, {Err = 1, Msg='Error : out of the part', CutId=Proc.CutId, TaskId=Proc.TaskId}) + Proc.ErrMsg = 'Error : out of the part' + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) else Proc.Flg = 0 bAllOk = false - table.insert( Stats, {Err = 1, Msg='Error : impossible to machine', CutId=Proc.CutId, TaskId=Proc.TaskId}) + if not Proc.ErrMsg then Proc.ErrMsg = 'Error : impossible to machine' end + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) end end -- se necessario ribaltamento, assegno intestatura alla fase ribaltata diff --git a/LuaLibs/ProcessCut.lua b/LuaLibs/ProcessCut.lua index ea81c37..44a7bc0 100644 --- a/LuaLibs/ProcessCut.lua +++ b/LuaLibs/ProcessCut.lua @@ -326,6 +326,9 @@ function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama elseif bOrthInv then dExtraCut = dSawThick + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i] then + dExtraCut = BD.CUT_EXTRA end end local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw) diff --git a/LuaLibs/ProcessLongDoubleCut.lua b/LuaLibs/ProcessLongDoubleCut.lua index dc8afa5..3d832b5 100644 --- a/LuaLibs/ProcessLongDoubleCut.lua +++ b/LuaLibs/ProcessLongDoubleCut.lua @@ -1,4 +1,4 @@ --- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2020/09/08 +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2020/09/26 -- Gestione calcolo doppio taglio longitudinale per Travi -- Tabella per definizione modulo @@ -14,31 +14,14 @@ EgtOutLog( ' ProcessLongDoubleCut started', 1) local BD = require( 'BeamData') local ML = require( 'MachiningLib') +local dLimMinPiece = BD.LEN_SHORT_PART or 1000 + --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessLong2Cut.Identify( Proc) return ( Proc.Grp == 0 and Proc.Prc == 12) end ---------------------------------------------------------------------- --- Classificazione della feature -function ProcessLong2Cut.Classify( Proc) - return true, false -end - ---------------------------------------------------------------------- -function ProcessLong2Cut.GetLongFacesCount( Proc) - local nLongFaces = 0 - local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) - for i = 1, nFacetCnt do - local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) - if abs( vtN:getX()) < GEO.EPS_SMALL then - nLongFaces = nLongFaces + 1 - end - end - return nLongFaces -end - --------------------------------------------------------------------- -- Identificazione delle facce della feature. -- Ritorna quattro valori : @@ -46,7 +29,7 @@ end -- vettore indici facce longitudinali -- vettore dei centri delle facce longitudinali -- vettore dei centri delle normali -function ProcessLong2Cut.IdentifyFaces( Proc) +local function IdentifyFaces( Proc) local nFaceLimit = 0 local tFaceLong = {} @@ -73,6 +56,57 @@ function ProcessLong2Cut.IdentifyFaces( Proc) return nFaceLimit, tFaceLong, tptC, tvtN end +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + + local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + + -- se richiesto utensile di fianco + if nUseMillOnSide > 0 then + + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, _, vtN = IdentifyFaces( Proc) + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + nSide = -1 + end + -- angolo diedro per stabilire se taglio convesso + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + if bAdj then + bConvex = ( dAng >= 0) + else + bConvex = true + end + -- se feature di fianco e facce concave per lavorazione impossibile + if nSide == 0 and not bConvex then + -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra) + Proc.ErrMsg = 'Error : impossible to machinine with tool on side' + return false, false + end + end + + return true, false +end + +--------------------------------------------------------------------- +function ProcessLong2Cut.GetLongFacesCount( Proc) + local nLongFaces = 0 + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN:getX()) < GEO.EPS_SMALL then + nLongFaces = nLongFaces + 1 + end + end + return nLongFaces +end + --------------------------------------------------------------------- local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam) -- inserisco la lavorazione @@ -167,8 +201,9 @@ end -- Applicazione della lavorazione function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) -- carico i dati delle face già inserite nelle opportune tabelle - local nFaceLimit, tFaceLong, ptC, vtN = ProcessLong2Cut.IdentifyFaces( Proc) + local nFaceLimit, tFaceLong, ptC, vtN = IdentifyFaces( Proc) local dLen = Proc.Box:getDimX() -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) @@ -217,9 +252,26 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) _, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[1]) _, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[2]) + -- per Dario: + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = 5 or 100000 -- qua deve ricevere la distanza dal pezzo successivo, nil in caso non c'è il pezzo + local bForcedLim local sWarn + ---------------------------------------------------------------------------------------------------------------------------------------- + -- 2020/09/17 Fabio Squaratti: se sono attivi entrambe i Q01 (lavorare con lama) e Q03 (lavorare con fresa di fianco anche da sopra) + -- allora vince il Q3, cioè si utilizza la fresa di fianco ( per i tagli da sopra) + + -- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce laterali, l'utensile deve arrivare + -- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del rggio utensile). + -- Questo viene fatto se Q03=1 o fresa da sotto + ---------------------------------------------------------------------------------------------------------------------------------------- + local bUseBlade = EgtGetInfo( Proc.Id, 'Q01', 'i') == 1 + local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + -- se entrambe i Q sono attivi, disabilito lama + if nUseMillOnSide > 0 then bUseBlade = false end + -- Se senza facce limitanti, da sopra e richiesto con doppio taglio di lama - if nFaceLimit == 0 and nSide == 1 and EgtGetInfo( Proc.Id, 'Q01', 'i') == 1 then + if nFaceLimit == 0 and nSide == 1 and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then -- recupero la lavorazione local sCutting = ML.FindCutting( 'HeadSide') if not sCutting then @@ -239,7 +291,11 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick end end - + -- se la distanza dal pezzo successivo è inferiore della metà lama, dò un warning + if dDistToNextPiece < dToolDiam/2 then + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end -- determino numero di parti local dStartAccDist = BD.LONGCUT_ENDLEN local dEndAccDist = BD.LONGCUT_ENDLEN @@ -382,10 +438,8 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) end end end - - -- Se non è sotto : lavorazione Long2Cut - elseif nSide ~= - 1 then - + -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut + elseif nSide ~= - 1 and nUseMillOnSide == 0 then -- recupero la lavorazione local sMilling = ML.FindMilling( 'Long2Cut') if not sMilling then @@ -403,6 +457,11 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo più distante da metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and nFaceLimit < 2 then + bForcedLim = true + nFaceLimit = nFaceLimit + 2 + end -- se chiuso e corto, applico svuotatura con fresa opportuna if nFaceLimit == 3 and Proc.Box:getDimX() < 2 * dToolDiam then -- svuotatura della prima faccia longitudinale @@ -418,7 +477,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) local dStartAccDist = BD.LONGCUT_ENDLEN local bStartFixed = true -- se ho faccia limite a destra - if nFaceLimit == 1 or nFaceLimit == 3 then + if nFaceLimit == 1 or nFaceLimit == 3 then dStartDist = dToolDiam / 2 dStartAccDist = BD.LONGCUT_MAXLEN bStartFixed = false @@ -427,7 +486,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) local dEndAccDist = BD.LONGCUT_ENDLEN local bEndFixed = true -- se ho faccia limite a sinistra - if nFaceLimit == 2 or nFaceLimit == 3 then + if nFaceLimit >= 2 then dEndDist = dToolDiam / 2 dEndAccDist = BD.LONGCUT_MAXLEN bEndFixed = false @@ -555,8 +614,33 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) end -- altrimenti è sotto : lavorazione Long2CutDown else + -- da Analisi con Fabio Squaratti 15/09/2020 + -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco + local bRemoveToolRadius + -- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile + -- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo + -- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite) + local nExtendMach -- recupero la lavorazione - local sMilling = ML.FindMilling( 'Long2CutDown') + local sMilling + local sPrefix + if nSide ~= - 1 then + sMilling = ML.FindMilling( 'Long2CutSide') + sPrefix = 'L2CS_' + nExtendMach = nUseMillOnSide + if nUseMillOnSide == 2 then + bRemoveToolRadius = true +-- nExtendMach = 0 -- arretro la lavorazione del raggio utensile (se non ha facce limite) + end + -- lavorazione da sotto + else + sMilling = ML.FindMilling( 'Long2CutDown') + sPrefix = 'L2CD_' + nExtendMach = 1 + if nUseMillOnSide ~= 1 then + nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) + end + end if not sMilling then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' EgtOutLog( sErr) @@ -574,6 +658,24 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam end end + local dDistToEnd = dToolDiam / 2 + -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile + if nUseMillOnSide <= 1 or nSide == -1 then + -- calcolo l'elevazione della faccia principale + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId) + local dFacElev = max( dFacElev1, dFacElev2) + if dFacElev < dDistToEnd then + dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) + end + end + -- se la fine è già limitata allora setto per arretrare del raggio utensile + if nFaceLimit >= 2 then + nExtendMach = 0 + -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata + elseif dDistToNextPiece < dDistToEnd and nExtendMach ~= 1 then + nFaceLimit = nFaceLimit + 2 + end -- aggiuntivo sull'affondamento local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0) -- determino gli estremi @@ -582,7 +684,7 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) local bStartFixed = true -- se ho facce limite a destra if nFaceLimit == 1 or nFaceLimit == 3 then - dStartDist = dToolDiam / 2 + dStartDist = dDistToEnd dStartAccDist = BD.LONGCUT_MAXLEN bStartFixed = false end @@ -590,8 +692,8 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) local dEndAccDist = BD.LONGCUT_ENDLEN local bEndFixed = true -- se ho facce limite a sinistra - if nFaceLimit == 2 or nFaceLimit == 3 then - dEndDist = dToolDiam / 2 + if nFaceLimit >= 2 then + dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) dEndAccDist = BD.LONGCUT_MAXLEN bEndFixed = false end @@ -660,7 +762,40 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) -- imposto posizione braccio porta testa per non ingombrare agli estremi EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + if nUseMillOnSide > 0 and nSide ~= -1 then + if nSide == 1 then + if bConvex then + if vtN[vOrd[i]]:getZ() > 0.866 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + else + if bConvex then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + if vtN[vOrd[i]]:getZ() >= 0 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + else + -- lascio lo stesso le lavorazioni anche se viene intercettato l'errore + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + if vtN[vOrd[i]]:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + end + end + else + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + end -- imposto lato di lavoro e inversione EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) EgtSetMachiningParam( MCH_MP.INVERT, true) @@ -686,6 +821,14 @@ function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) EgtSetOperationMode( nMchFId, false) return false, sErr end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam) + end end end end