-- ProcessLapJoint.lua by Egaltech s.r.l. 2019/10/05 -- Gestione calcolo mezzo-legno per Travi -- 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') --------------------------------------------------------------------- -- 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 == 34) or ( Proc.Grp == 4 and Proc.Prc == 39)) end --------------------------------------------------------------------- -- Verifica se feature di testa function ProcessLapJoint.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 il massimo e 1/3 della lunghezza della trave if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.33 *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.5 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) -- 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 1/3 della lunghezza della trave if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.33 * b3Raw:getDimX()) then return false end -- se una o due facce ora è sicuramente di coda if Proc.Fct <= 2 then return true end -- deve avere la normale principale diretta verso la coda 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.5 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 -- 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 nFacInd < 0 then return false end -- 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 --------------------------------------------------------------------- local function TestElleShape( 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 --------------------------------------------------------------------- -- Lavorazione con fresa --------------------------------------------------------------------- local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- 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 return true end --------------------------------------------------------------------- local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- 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 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 local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) if not bOk then return bOk, sErr end elseif nCutFacet == 2 then local bOk, sErr = DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0) if not bOk then return bOk, sErr end end end end return true end --------------------------------------------------------------------- local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev) -- 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 local bOpenStart = false local bOpenEnd = false local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,')) 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 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 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( 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 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( bOpenEnd, 0, - dTDiam / 2)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true end --------------------------------------------------------------------- local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev) -- 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 local bOpenStart = false local bOpenEnd = false local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,')) 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 -- Se entrambi gli estremi sono aperti e fattibile con lama if bOpenStart and bOpenEnd and dElev <= BD.MAX_DIM_DICE 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 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 -- Calcolo uso faccia local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- Eseguo i tagli local nStep = ceil( ( dV - 0.5) / 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, nil, 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) local d3RotAng = EgtIf( abs( vtT:getZ()) < GEO.EPS_SMALL, 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 end -- Recupero i dati dell'utensile local dSawWidth = 75 local dSawThick = 8 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 end end -- Verifico se necessarie più passate local nStep = ceil( ( dV - 0.5) / 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) -- 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 end --------------------------------------------------------------------- local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId) -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- 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 local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMoreFaces could not find reference face' EgtOutLog( sErr) return false, sErr end -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) -- 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 local 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 dDiam = min( dH, dV) EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam)) local sPocketing = ML.FindPocketing( 'Mortise', dDiam, dFacElev) -- se non trova una svuotatura adatta if not sPocketing then -- verifico se due o tre facce a L con una faccia di terminazione local bIsL = ( Proc.Fct == 2 or TestElleShape( Proc)) -- se due facce o tre a L 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 return MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev) end end -- recupero i dati dell'utensile local dMaxDepth = 0 if EgtMdbSetCurrMachining( sPocketing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then 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( {{ Proc.Id, nFacInd}}) -- 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 elevazione superiore a massimo affondamento della fresa, riduco opportunamente local sWarn if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) dFacElev = 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( dFacElev, 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 false, sErr 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() / min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX())) 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 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, sErr = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId) if not bOk then return bOk, sErr end end return true, sErr end --------------------------------------------------------------------- -- Applicazione della lavorazione --------------------------------------------------------------------- function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- limiti di fresatura semplice local MAX_MILL_LIN = 80 local MAX_MILL_VOL = ( 80 * 240 * 20) / 2 -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- se lunghezza richiede spezzatura if Proc.Box:getDimX() > min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX()) 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 -- se piccola, con fresa if ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) or Proc.Box:getDimX() * Proc.Box:getDimY() * Proc.Box:getDimZ() < MAX_MILL_VOL 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 _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) -- se ortogonali e piccole, con fresa if 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)) or Proc.Box:getDimX() * Proc.Box:getDimY() * Proc.Box:getDimZ() < MAX_MILL_VOL) 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