-- ProcessDovetail.lua by Egaltech s.r.l. 2020/04/23 -- Gestione calcolo giunzione coda di rondine -- Tabella per definizione modulo local ProcessDovetail = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local DC = require( 'DiceCut') local Cut = require( 'ProcessCut') EgtOutLog( ' ProcessDovetail 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 --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessDovetail.Identify( Proc) return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 138) 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.Prc == 138 then sUseRoughTool = 'Q02' -- d end end --------------------------------------------------------------------- local function EvaluateQParam( Proc, sUseRoughTool) local nChamfer = 0 local bForceUseRough = false -- verifico se devo usare il truciolatore -- 2020-03-20 forzata disabilitazione uso truciolatore se parametro Q non è presente if #sUseRoughTool == 0 or EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 2 then bForceUseRough = true end return nChamfer, bForceUseRough end --------------------------------------------------------------------- local function OrderFaces( Proc, nFacetCnt, vtN) local dMinXFace = 1 local dPosXFace = 0 local dNegXFace = 0 local vFaceOrd = { 0, 0, 0} if nFacetCnt <= 2 then -- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia) for i = 1, nFacetCnt do if abs( vtN[i]:getX()) < dMinXFace then dMinXFace = abs( vtN[i]:getX()) vFaceOrd[3] = i end end if vFaceOrd[3] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' EgtOutLog( sErr) return false, sErr end for i = 1, nFacetCnt do if i ~= vFaceOrd[3] then local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) if bTouch and dAng < 0 then vFaceOrd[2] = i end end end elseif nFacetCnt == 3 then -- ordino le facce (1=altra intermedia, 2=interna, 3=intermedia) for i = 1, nFacetCnt do if abs( vtN[i]:getX()) < dMinXFace then dMinXFace = abs( vtN[i]:getX()) vFaceOrd[3] = i end if abs( vtN[i]:getX()) > dPosXFace then dPosXFace = abs( vtN[i]:getX()) vFaceOrd[2] = i end end if vFaceOrd[3] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' EgtOutLog( sErr) return false, sErr end if vFaceOrd[2] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' EgtOutLog( sErr) return false, sErr end for i = 1, nFacetCnt do if i ~= vFaceOrd[3] and i ~= vFaceOrd[2] then local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) if bTouch and dAng < 0 then vFaceOrd[1] = i end end end else -- ordino le facce (1=laterale positiva 2=altra intermedia, 3=intermedia, 4=laterale negativa) for i = 1, nFacetCnt do if vtN[i]:getX() > dPosXFace then dPosXFace = vtN[i]:getX() vFaceOrd[1] = i end if ( vtN[i]:getX()) < dNegXFace then dNegXFace = vtN[i]:getX() vFaceOrd[4] = i end end if vFaceOrd[1] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing side positive face' EgtOutLog( sErr) return false, sErr end if vFaceOrd[4] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing side negative face' EgtOutLog( sErr) return false, sErr end local nMidFace = 3 for i = 1, nFacetCnt do if i ~= vFaceOrd[1] and i ~= vFaceOrd[4] then vFaceOrd[nMidFace] = i nMidFace = nMidFace - 1 end end if vFaceOrd[2] == 0 or vFaceOrd[3] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing middle face' EgtOutLog( sErr) return false, sErr end local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) if bTouch and dAng < 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong angle between middle faces' EgtOutLog( sErr) return false, sErr end end return true, '', vFaceOrd end --------------------------------------------------------------------- local function VerifyIfRoughMill( dLargeface, vtN, bCalcElev, dAngOnSide) local bUseRoughMill = false local sMilling -- recupero la lavorazione if dAngOnSide then if bCalcElev then local dCollSic = BD.COLL_SIC -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end sMilling = ML.FindMilling( 'ProfTCone', dLargeface + dCollSic) else sMilling = ML.FindMilling( 'ProfTCone') end else if bCalcElev then local dCollSic = BD.COLL_SIC -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end sMilling = ML.FindMilling( 'Long2Cut', dLargeface + dCollSic) else sMilling = ML.FindMilling( 'Long2Cut') end dAngOnSide = 0 end if sMilling then -- recupero i dati dell'utensile local dToolDiam = 100 local dToolLength = 0 local dMaxDepth = 0 local dMaxMat = 50 local dSideAngle = 0 local dStepmach = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle -- ottengo il passo della lavorazione dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach end end if dStepmach <= 0.1 then dStepmach = dMaxMat * 0.5 end -- se ho già fatto la ricerca lavorazione considerando l'elevazione controllo solo l'angolo if bCalcElev then -- se angolo spoglia compatibile if abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL then return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach end else -- se altezza taglio utensile maggiore altezza faccia e angolo spoglia compatibile if ( dMaxDepth >= dLargeface + 10 * GEO.EPS_SMALL) and ( abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL) then return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach end end end return false end --------------------------------------------------------------------- -- Verifica se feature di testa function ProcessDovetail.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 ProcessDovetail.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 -- 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 ProcessDovetail.Classify( Proc, b3Raw) -- in base al tipo di feature attribuisco il significato dei parametri Q AssignQValues( Proc) -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore local _, bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) -- verifico le normali delle facce local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) local nFlatFaceNeg local bDown = false -- individuo se c'è faccia rastremata verso Z- for i = 1, nFacetCnt do local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) if vtN:getZ() < -1 + GEO.EPS_SMALL then nFlatFaceNeg = i-1 break end end -- se trovata faccia rastremata rivolta verso Z- -- verifico se lunghezza faccia piatta è compatibile con il taglio di lama if nFlatFaceNeg then -- se >= a 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli if nFacetCnt >= 3 then bDown = true -- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento -- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste) else -- prendo le dimensioni della faccia local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama e non fattibile con truciolatore -- quindi setto il ribaltamento if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then bDown = true else local dDist = dist( ptP1, ptP2) local dLargeface local dDeltadH = abs( dDist - dH) local dDeltadV = abs( dDist - dV) -- prendo la dimensione diversa dalla lunghezza di adiacenza if dDeltadH < dDeltadV then dLargeface = dV else dLargeface = dH end local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough = VerifyIfRoughMill( dLargeface, rfFac:getVersZ(), true) -- se forzato uso truciolatore if bForceUseRough then bDown = not bUseRough -- altrimenti uso misto tra lama e truciolatore else bDown = not bUseBlade and not bUseRough end end end -- altrimenti controllo la componente in Z delle facce else local vtN = {} for i = 1, nFacetCnt do _, vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end for i = 1, nFacetCnt do local nFacet = i-1 -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, if abs(vtN[i]:getZ()) > abs(vtN[i]:getX()) and abs(vtN[i]:getZ()) > abs(vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then -- se ho due facce e feature agli estremi verifico che la lunghezza faccia sia compatibile col taglio di lama -- o con truciolatore in base al valore del Q if nFacetCnt == 2 and ( Proc.Head or Proc.Tail) then -- prendo le dimensioni della faccia local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1) local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) -- se angolo interno acuto if dAng < 0 and dAng < -90 - 5 * GEO.EPS_SMALL then -- se forzato truciolatore allora controllo se posso fare con utensile tronco di cono local dLargeface = Proc.Box:getDimX() local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true, (90+dAng)) -- se forzato uso truciolatore if bForceUseRough then bDown = not bUseRough -- altrimenti uso misto tra lama e truciolatore else bDown = not bUseBlade and not bUseRough end -- altrimenti angolo interno a 90 else local dDist = dist( ptP1, ptP2) local dLargeface local dDeltadH = abs( dDist - dH) local dDeltadV = abs( dDist - dV) -- prendo la dimensione diversa dalla lunghezza di adiacenza if dDeltadH < dDeltadV then dLargeface = dV else dLargeface = dH end -- se (anche) la direzione in z dell'altra faccia è negativa verifico se posso farla di fresa (in base alle impostazioni del Q) if vtN[nOtherFace+1]:getZ() < -0.001 then -- se forzato uso truciolatore verifico se posso fare di truciolatore if bForceUseRough then local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) bDown = not bUseRough -- altrimenti posso usare lama, ma (anche) la direzione in z dell'altra faccia è negativa, quindi non è lavorabile, setto il ribaltamento else bDown = true end else local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) -- se forzato uso truciolatore if bForceUseRough then bDown = not bUseRough -- altrimenti uso misto tra lama e truciolatore else bDown = not bUseBlade and not bUseRough end end end elseif nFacetCnt == 3 and ( Proc.Head or Proc.Tail) then -- ordino le 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN) if not bOk1 then return bOk1 end -- se le due facce intermedie sono compatibili con la lunghezza lama da sotto -- prendo le dimensioni della facce local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[3]-1, GDB_ID.ROOT) local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3]-1, vFaceOrd[1]-1, GDB_ID.ROOT) -- prendo la dimensione uguale dalla lunghezza di adiacenza local dLargeface = dist( ptP1, ptP2) local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) -- se forzato uso truciolatore e non riesco a farlo if bForceUseRough then bDown = not bUseRough -- altrimenti uso misto tra lama e truciolatore else bDown = not bUseBlade and not bUseRough end elseif not Proc.Head and not Proc.Tail then bDown = true end end end end return true, bDown end --------------------------------------------------------------------- local function MakeCutsByDice( Proc, b3Raw, vCuts, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) -- sistemo posizione nel DB e nome for i = 1, #vCuts do for j = 1, #vCuts[i] do EgtRelocateGlob( vCuts[i][j], nAddGrpId) EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) end end -- calcolo secondo riferimento per testa o coda local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) -- eseguo for i = 1, #vCuts do local vtOrthoO if i % 2 == 1 then vtOrthoO = Vector3d( vtRef) else if #vCuts[i-1] > 0 then vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) else local vtO for j = 1, #vCuts[i-1] do _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) break end if vtO then vtOrthoO = Vector3d( vtO) else vtOrthoO = Y_AX() end end end local dExtraTrim = 0 -- lavoro la faccia for j = 1, #vCuts[i] do -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo -- cioè non i tagli intermedi, aggiungo extratrim minimo if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then dExtraTrim = dFinalExtraTrim -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim elseif i < (#vCuts-1) or (i == #vCuts) then dExtraTrim = dNullExtraTrim -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim else dExtraTrim = dMiddleExtraTrim end local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end end return true end --------------------------------------------------------------------- local function CutChainFacesByBlade( Proc, nCFaceSide, nCFaceInt1, nCFaceInt2, sCutting, bHead, vtRef, dTrim, dDepth) -- inserisco la lavorazione di taglio per la laterale negativa local sName = 'Cut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. EgtIf( nCFaceSide > 0, tostring( nCFaceSide) .. '_', '') .. tostring( nCFaceInt1) .. '-' .. tostring( nCFaceInt2) local nMchFId = EgtAddMachining( sName, sCutting) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nCFaceInt1 - 1},{ Proc.Id, nCFaceInt2 - 1}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) local nSCC = EgtIf( vtRef:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) -- imposto posizione braccio porta testa EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- affondamento aggiuntivo EgtSetMachiningParam( MCH_MP.OFFSR, -dTrim) -- offset longitudinale EgtSetMachiningParam( MCH_MP.OFFSL, 0) -- imposto inversione e lato correzione EgtSetMachiningParam( MCH_MP.INVERT, true) EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- imposto affondamento if dDepth then EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) else EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') end -- imposto attacco/uscita EgtSetMachiningParam( MCH_MP.LITANG, 0) EgtSetMachiningParam( MCH_MP.LIPERP, 100) EgtSetMachiningParam( MCH_MP.LOTANG, 0) EgtSetMachiningParam( MCH_MP.LOPERP, 100) local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt1 - 1, GDB_ID.ROOT) local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt2 - 1, GDB_ID.ROOT) local dNyMax = EgtIf( abs( vtN1:getY()) > abs( vtN2:getY()), vtN1:getY(), vtN2:getY()) local dNzMax = EgtIf( abs( vtN1:getZ()) > abs( vtN2:getZ()), vtN1:getZ(), vtN2:getZ()) if dNzMax < 0 and dNyMax < 0 then EgtSetMachiningParam( MCH_MP.LITANG, 340) EgtSetMachiningParam( MCH_MP.LIPERP, -100) elseif dNzMax < 0 and dNyMax > 0 then EgtSetMachiningParam( MCH_MP.LOTANG, 340) EgtSetMachiningParam( MCH_MP.LOPERP, -100) end -- imposto allungamenti iniziale e finale EgtSetMachiningParam( MCH_MP.STARTADDLEN, 50) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 50) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true end --------------------------------------------------------------------- local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) -- dati delle facce local ptC = {} local vtN = {} for i = 1, nFacetCnt do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end -- recupero la geometria ausiliaria local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id end -- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia) -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN) if not bOk1 then return bOk1, sErr1 end -- determino se di testa o di coda local bHead if vtN[vFaceOrd[2]] then bHead = ( vtN[vFaceOrd[2]]:getX() > 0) else if AuxId then local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) bHead = ( vtNx:getX() > 0) end end -- vettore di riferimento per le facce ortogonali all'asse trave local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) vtRef:normalize() local vtRef2nd if nFacetCnt > 2 and vFaceOrd[1] ~= 0 then vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) vtRef2nd:normalize() end -- recupero la lavorazione 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 dToolThick = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick 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 -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') -- taglio sulla faccia esterna if AuxId and not bAuxMachined then -- in generale va fatto local bCut = true local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) -- se di testa e coincide con inizio grezzo, non va fatto if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then bCut = false end -- se di coda e coincide con taglio di separazione, non va fatto if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then bCut = false end -- se va fatto, inserisco la lavorazione if bCut then local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta if bOk then bAuxMachined = true EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) else return bOk, sErr end end end -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli -- se angolo tra le due facce ottuso la distanza può essere messa a 0 local dTrim local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then dTrim = 0 else dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() end local dFinalExtraTrim = 0.1 local dMiddleExtraTrim = 0.3 local dNullExtraTrim = 0 -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti local vCuts = {} if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) elseif vFaceOrd[3] ~= 0 then vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) end if #vCuts > 0 then local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) if not bOk then return false, sErr end end if vFaceOrd[1] ~= 0 then bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[1] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then dTrim = 0 else dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() end end local vCuts2 = {} if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then vCuts2 = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) elseif vFaceOrd[1] ~= 0 then vCuts2 = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true) end if #vCuts2 > 0 then local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) if not bOk then return false, sErr end end -- se una parte non ha fatto tagli if #vCuts == 0 or #vCuts2 == 0 then -- taglio sulla faccia esterna if AuxId and not bAuxMachined then -- in generale va fatto local bCut = true local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) -- se di testa e coincide con inizio grezzo, non va fatto if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then bCut = false end -- se di coda e coincide con taglio di separazione, non va fatto if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then bCut = false end -- se va fatto, inserisco la lavorazione if bCut then local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta if bOk then bAuxMachined = true EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) else return bOk, sErr end end end local bIntCut = false -- se non ha fatto nessun taglio a cubetti e ho 3 facce -- taglio sulla faccia interna ( concatenando le due facce intermedie e lama che contorna queste) if #vCuts == 0 and #vCuts2 == 0 and nFacetCnt > 2 then -- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie local bOk, sErr = CutChainFacesByBlade( Proc, 0, vFaceOrd[3], vFaceOrd[1], sCutting, bHead, vtRef, ( dTrim + dFinalExtraTrim)) if not bOk then return false, sErr end -- taglio sulla faccia intermedia if vFaceOrd[3] ~= 0 then -- calcolo secondo testa o coda local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) -- inserisco la lavorazione local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- taglio sulla seconda faccia intermedia if vFaceOrd[1] ~= 0 then -- calcolo secondo testa o coda local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) -- inserisco la lavorazione local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end else if vFaceOrd[2] ~= 0 then -- inserisco la lavorazione local nDirVect = BL.GetNearestOrthoOpposite( vtRef) local bOk, sNameOrErr bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sNameOrErr end if #sNameOrErr > 0 then bIntCut = true end end -- taglio sulla faccia intermedia if vFaceOrd[3] ~= 0 then -- calcolo secondo testa o coda local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) -- se non ho il taglio sulla faccia interna if not bIntCut then local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) if DimV > DimH then vtRef2 = Vector3d( frHV:getVersX()) end end -- inserisco la lavorazione local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end end end -- aggiornamento ingombro di testa o coda if Proc.Head and AuxId then local dHCI = 00 -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end -- altrimenti di fianco else dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() end BL.UpdateHCING( nRawId, dHCI) elseif Proc.Tail and AuxId then local dTCI = 0 -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end -- altrimenti di fianco else dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() end BL.UpdateTCING( nRawId, dTCI) end return true end --------------------------------------------------------------------- local function MakeMillCut( Proc, i, j, k, sMilling, nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, bPrevByBlade, bUCut, bHead, vtRef) local sWarn = '' local bUnderCut = bUCut -- inserisco la lavorazione di fresatura -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente local s2ndName = EgtGetName( Proc.Id) or '' local sName = EgtIf( bUnderCut, 'MillTCone_', 'Mill_') .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) local kStep = k or 0 if kStep > 0 then sName = sName .. '_' .. tostring(k) end local nMchId = EgtAddMachining( sName, sMilling) if not nMchId then local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end local vtDirRef -- imposto i parametri lavorazione in base alle facce lavorate if vFaceOrd and #vFaceOrd > 0 then -- aggiungo geometria e imposto uso faccia EgtSetMachiningGeometry( {{ Proc.Id, vFaceOrd[3]-1},{ Proc.Id, vFaceOrd[1]-1}}) EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) -- setto vettore direzione per posizione braccio porta testa vtDirRef = vtRef -- imposto lato corezione e inversione percorso if kStep % 2 == 1 then -- imposto lato sinistro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- imposto inversione EgtSetMachiningParam( MCH_MP.INVERT, true) else -- imposto lato destro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- tolgo inversione EgtSetMachiningParam( MCH_MP.INVERT, false) end -- imposto affondamento EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH' .. EgtIf( dOffs < 0, '', '-') .. EgtNumToString( dOffs, 4)) else -- aggiungo geometria e imposto uso faccia EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) local nFaceUse = BL.GetNearestOrthoOpposite( Vector3d( TabNAD[j][1]:getX(), 0, 0)) EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- setto vettore direzione per posizione braccio porta testa vtDirRef = rfFac:getVersZ() -- imposto lato corezione e inversione percorso if kStep % 2 == 1 then -- imposto lato destro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- imposto inversione EgtSetMachiningParam( MCH_MP.INVERT, true) else -- imposto lato sinistro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- tolgo inversione EgtSetMachiningParam( MCH_MP.INVERT, false) end -- imposto affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) end -- imposto posizione braccio porta testa local nSCC = EgtIf( vtDirRef:getY() > (100 * GEO.EPS_ZERO), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) EgtSetMachiningParam( MCH_MP.SCC, nSCC) --imposto passo 0 EgtSetMachiningParam( MCH_MP.STEP, 0) -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale dOffrRad = dOffrRad + dAddOffsRad -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( bPrevByBlade and ( i < nStep) and ( kStep < 1), 0.5, 0)) -- imposto offset longotudinale a 0 EgtSetMachiningParam( MCH_MP.OFFSL, 0) -- imposto gli attacchi EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75)) -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale local sUserNotes if i < nStep then sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' else sUserNotes = 'VMRS=0;' sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' end EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr else _, sWarn = EgtGetMachMgrWarning( 0) if EgtIsMachiningEmpty() then EgtSetOperationMode( nMchId, false) end end return true, sWarn end --------------------------------------------------------------------- local function MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, vFaceOrd, bHead, sMillingMaster, dToolDiamMaster, dMaxMatMaster, dSideAngleMaster, dStepmachMaster, nMainFace, dElevMain) local sWarn = '' local sMilling local dToolDiam = 100 local dMaxMat = 50 local dSideAngle = 0 local dStepmach = 0 local bUCutMax -- dati della facce local vtN = {} local ptC = {} for i = 1, nFacetCnt do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end -- se non ho passato la lavorazione ( già verificata) if not sMillingMaster then -- se il flg del sottosquadra è nil, cerco se tra le facce c'è un angolo sottosquadra if bUCut == nil then for i = 1, nFacetCnt do for j = i+1, nFacetCnt do local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, (i-1), (j-1), GDB_ID.ROOT) if bAdj and dAng and dAng < -90 - ( 10 * GEO.EPS_SMALL) then bUCut = true break end end end end -- recupero l'angolo di spoglia dell'utensile a tronco di cono -- recupero la lavorazione local sMchFind = 'Long2Cut' if bUCut then sMchFind = 'ProfTCone' end sMilling = ML.FindMilling( sMchFind) if not sMilling then local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile dToolDiam = 100 dMaxMat = 50 dSideAngle = 0 dStepmach = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle -- ottengo il passo della lavorazione dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach end end if dStepmach <= 0.1 then dStepmach = dMaxMat * 0.5 end else sMilling = sMillingMaster dToolDiam = dToolDiamMaster dMaxMat = dMaxMatMaster dSideAngle = dSideAngleMaster dStepmach = dStepmachMaster end local nFacInd, dFacElev if nMainFace and dElevMain then nFacInd = nMainFace dFacElev = dElevMain else -- se devo lavorare facce concatenate if bJoinFaces then nFacInd = vFaceOrd[2] - 1 -- calcolo l'elevazione local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) if dLenIn > 0 then dFacElev = dLenIn elseif dLedOut then dFacElev = dLedOut end else -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) if not nFacInd or nFacInd < 0 then -- provo eliminando i sottosquadra nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) if not nFacInd or nFacInd < 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MachSideFaces could not find reference face' EgtOutLog( sErr) return false, sErr else bUCutMax = true end end end end local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) local TabNAD = {} local bPrevByBlade = false -- se non ho la forzatura a usare solo truciolatore e tagli lama consentiti -- inserisco tagli di lama come antischeggia sulle altre facce if not bForceUseRough and bUseBlade then -- recupero la lavorazione 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 dToolThick = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick end end -- controllo versore faccia di riferimento, è lungo l'asse trave local vtRef = Vector3d( vtN[nFacInd+1]) if not AreSameVectorApprox( vtN[nFacInd+1], X_AX()) and not AreSameVectorApprox( vtN[nFacInd+1], -X_AX()) then -- vettore di riferimento per le facce ortogonali all'asse trave vtRef = Vector3d( 0, vtN[nFacInd+1]:getY(), vtN[nFacInd+1]:getZ()) end vtRef:normalize() -- ciclo inserimento tagli antischeggia sulle facce for i = 1, nFacetCnt do if ( i - 1) == nFacInd then TabNAD[i] = { vtN[i]} else local dExtraZed = EgtIf( bForceMakeMill, 1, 0.1) -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli -- se angolo tra le due facce ottuso la distanza può essere messa a 0 local dTrim local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) if dAng then TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} end if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then dTrim = 0 dExtraZed = 0.1 else dTrim = ((dToolThick* vtN[nFacInd+1]) * vtN[i] * vtN[i]):len() end -- inserisco la lavorazione local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dExtraZed), BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sNameOrErr end bPrevByBlade = true end end -- altrimenti solo taglio truciolatore else for i = 1, nFacetCnt do if ( i - 1) == nFacInd then TabNAD[i] = { vtN[i]} else local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) if dAng then TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} end end end end local vtRef -- se devo lavorare facce concatenate if bJoinFaces then -- vettore di riferimento per le facce ortogonali all'asse trave vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) vtRef:normalize() end -- creo percorsi di lavorazione local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) local dStep = dFacElev / nStep local dLargeVal local nLenSideMax -- se non devo fare fresature if not bForceMakeMill then nStep = 0 end for i = 1, nStep do local dOffs = ( i * dStep) - dFacElev if i == nStep then dOffs = 0 end local dOffsSide = 0 local dDelta = 100000 local dElevface for j = 1, nFacetCnt do if (j-1) ~= nFacInd then local dParzElev = dOffs -- calcolo la larghezza (solo 1 volta) if i == 1 then -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then dParzElev = dFacElev end if bJoinFaces then -- calcolo l'elevazione di ogni singola faccia dal punto medio local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j]) if dLenIn > 0 then dElevface = dLenIn elseif dLedOut then dElevface = dLedOut end if not dLargeVal or dElevface > dLargeVal then dLargeVal = dElevface end else local dDeltadH = abs( TabNAD[j][3] - dH) local dDeltadV = abs( TabNAD[j][3] - dV) if dDeltadH < dDeltadV then if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then dDelta = dDeltadH dLargeVal = dV nLenSideMax = j end else if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then dDelta = dDeltadV dLargeVal = dH nLenSideMax = j end end end end -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) end end local dRefLarge -- se ho facce concatenate verifico che la massima larghezza sia comunque superiore al diametro utensile if bJoinFaces then dRefLarge = dToolDiam dLargeVal = EgtIf( dLargeVal > ( dToolDiam + dOffsSide), dLargeVal, dToolDiam + dOffsSide) else dRefLarge = EgtIf( nFacetCnt == 2, dToolDiam, ( 2 * dToolDiam)) end -- se ho 2 facce o la larghezza è più grande dell'utensile allora posso lavorare il passo if nFacetCnt == 2 or ( dLargeVal - dOffsSide) >= dToolDiam then -- se ho facce concatenate if bJoinFaces then local dOffrRad = 0 -- se larghezza faccia consente passi laterali extra if ( dLargeVal - dOffsSide) > dRefLarge then local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide for k = nStepSide, 1, -1 do local dAddOffsRad = ( k * dStepSide) -- inserisco la lavorazione di fresatura local bOk, sErr = MakeMillCut( Proc, i, 1, k, sMilling, nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, bPrevByBlade, bUCut, bHead, vtRef) if not bOk then return false, sErr end sWarn = sErr end end -- inserisco la lavorazione di fresatura a contatto con la faccia local bOk, sErr = MakeMillCut( Proc, i, 1, nil, sMilling, nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep, bPrevByBlade, bUCut, bHead, vtRef) if not bOk then return false, sErr end sWarn = sErr else for j = 1, nFacetCnt do if (j-1) ~= nFacInd then -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) end -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide for k = nStepSide, 1, -1 do local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) -- inserisco la lavorazione di fresatura local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, nil, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, bPrevByBlade, bUCut) if not bOk then return false, sErr end sWarn = sErr end end -- inserisco la lavorazione di fresatura a contatto con la faccia local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, nil, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep, bPrevByBlade, bUCut) if not bOk then return false, sErr end sWarn = sErr end end end -- altrimenti passo saltato esco con errore else local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' EgtOutLog( sErr) return false, sErr end end return true, sWarn end --------------------------------------------------------------------- local function Mach2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) -- verifico le normali delle facce -- individuo se c'è faccia rastremata verso Z- local nFlatFaceNeg local vtN = {} local ptC = {} for i = 1, nFacetCnt do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) if vtN[i]:getZ() < -1 + GEO.EPS_SMALL then nFlatFaceNeg = i-1 end end -- se trovata faccia rastremata rivolta verso Z- faccio controllo di lavorabilità da sotto if nFlatFaceNeg then -- prendo le dimensioni della faccia local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) local dDist = dist( ptP1, ptP2) local dLargeface local dDeltadH = abs( dDist - dH) local dDeltadV = abs( dDist - dV) -- prendo la dimensione diversa dalla lunghezza di adiacenza if dDeltadH < dDeltadV then dLargeface = dV else dLargeface = dH end local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough, sMilling = VerifyIfRoughMill( dLargeface, rfFac:getVersZ(), true) -- se non forzato truciolatore provo la lama if not bForceUseRough and bUseBlade then return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) -- altrimenti provo con il truciolatore else -- se non ho la lavorazione esco if not sMilling then local sErr = 'Error, machining or tool not found ' .. sName .. '-' .. sMilling 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 -- Calcolo uso faccia local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}}) -- 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) -- applico allungamento iniziale e finale EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) -- eseguo if not EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end -- altrimenti non ho faccia (antivento) da sotto else for i = 1, nFacetCnt do local nFacet = i-1 -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, if abs(vtN[i]:getZ()) > abs(vtN[i]:getX()) and abs(vtN[i]:getZ()) > abs(vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then -- lavoro con lama o truciolatore in base al Q -- prendo le dimensioni della faccia local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1) local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) local dLargeface = Proc.Box:getDimX() local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) local bForceMakeMill = bUCut or bForceUseRough -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) -- se devo farlo con fresatura if bForceMakeMill then -- se non ho lavorazione (se per esempio l'angolo di spoglia utensile non è uguale a quello tra le due facce) do errore if not sMilling then local sErr = 'Error, machining or tool not found ' .. sName EgtOutLog( sErr) return false, sErr end -- genero lavorazioni local bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, bUseBlade, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dStepmach, nOtherFace, dLargeface) if not bOk then return false, sErr end elseif bUseBlade then local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) -- se fallita di lama e di fresa è fattibile, eseguo con la fresa if not bOk and sMilling then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, bUseBlade, true, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dStepmach, nOtherFace, dLargeface) if not bOk then return false, sErr end else return false, sErr end end return true -- altrimenti non in Z negativa else -- se nessuna entità ha z negativa if i == nFacetCnt then -- verifico angolo tra le facce local nOtherFace = nFacet - 1 local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) local dLargeface = Proc.Box:getDimX() -- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia) local bOk, sErr, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN) if not bOk then return bOk, sErr end local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) local bForceMakeMill = bUCut or bForceUseRough -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) -- se devo farlo con fresatura if bForceMakeMill then local bOk, sErr bOk = false -- se angolo ( tra le due facce è) ottuso if bOCut then local ptPs = ( ptP1 + ptP2) / 2 -- calcolo l'elevazione di ogni singola faccia dal punto medio della linea di adiacenza -- prendo l'elevazione sul punto medio della prima faccia local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[2]]) if dLenIn > 0 then dLargeface = dLenIn elseif dLedOut then dLargeface = dLedOut end -- verifico la possibilità di lavorare con utensile local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, vtN[vFaceOrd[2]], true) -- se ho trovato lavorazione applicata a faccia definita if sMilling then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dStepmach, vFaceOrd[2]-1, dLargeface) end -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima if not bOk then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false) end if not bOk then return false, sErr end -- prendo l'elevazione sul punto medio della seconda faccia dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[3]]) if dLenIn > 0 then dLargeface = dLenIn elseif dLedOut then dLargeface = dLedOut end -- verifico la possibilità di lavorare con utensile bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, vtN[vFaceOrd[3]], true) -- se ho trovato lavorazione applicata a faccia definita if sMilling then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dStepmach, vFaceOrd[3]-1, dLargeface) end -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima if not bOk then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false) end if not bOk then return false, sErr end else -- verifico la possibilità di lavorare con utensile (orizzontale) local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) -- se ho trovato lavorazione applicata a faccia definita if sMilling then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dStepmach, vFaceOrd[2]-1, dLargeface) end -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima if not bOk then -- genero lavorazioni bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false) end if not bOk then return false, sErr end end else return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) end end end end end return true end --------------------------------------------------------------------- local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bSkipHead) -- settaggio flag adatti per il concatenamento delle facce intermedie local bUseBlade = false local bForceMakeMill = bForceUseRough local bUCut = false local bOCut = false local bJoinFaces = true local vFaceOrd local bHead -- dati delle facce local vtN = {} for i = 1, nFacetCnt do _, vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end if not bSkipHead then -- recupero la geometria ausiliaria local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id end -- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia) -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) local bOk1, sErr1 bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN) if not bOk1 then return bOk1, sErr1 end -- determino se di testa o di coda if vtN[vFaceOrd[2]] then bHead = ( vtN[vFaceOrd[2]]:getX() > 0) else if AuxId then local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) bHead = ( vtNx:getX() > 0) end end -- recupero la lavorazione per lavorare la geometria ausiliaria 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 dToolThick = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick 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 -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId or 0), 'b') -- taglio sulla faccia esterna if AuxId and not bAuxMachined then -- in generale va fatto local bCut = true local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) -- se di testa e coincide con inizio grezzo, non va fatto if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then bCut = false end -- se di coda e coincide con taglio di separazione, non va fatto if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then bCut = false end -- se va fatto, inserisco la lavorazione if bCut then local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta if bOk then bAuxMachined = true EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) else return bOk, sErr end end end -- altrimenti non sono di testa else -- abilito la lama per i tagli antischeggia bUseBlade = true -- abilito la fresatura bForceMakeMill = true -- disabilito il concatenamento delle facce intermedie bJoinFaces = false -- annullo il flag del sottosquadra per forzare la ricerca all'interno della funzione bUCut = nil end -- lavoro le restanti facce return MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, vFaceOrd, bHead) end --------------------------------------------------------------------- local function MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, nSidePosFct, nMiddleFct, nSideNegFct, vtRef, nFacetCnt) local sWarn = '' -- recupero la lavorazione local sMchFind = 'Long2Cut' local sMilling = ML.FindMilling( sMchFind) if not sMilling then local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dToolDiam = 100 local dMaxMat = 50 local dSideAngle = 0 local dStepmach = 0 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle -- ottengo il passo della lavorazione dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach end end if dStepmach <= 0.1 then dStepmach = dMaxMat * 0.5 end local nFacInd = nMiddleFct - 1 local dFacElev -- calcolo elevazione local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct]) if dLenIn > 0 then dFacElev = dLenIn elseif dLedOut then dFacElev = dLedOut end local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) local TabNAD = {} TabNAD[nMiddleFct] = { vtN[nMiddleFct]} local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSideNegFct-1), GDB_ID.ROOT) if dAng then TabNAD[nSideNegFct] = { vtN[nSideNegFct], dAng, dist( ptP1, ptP2)} end bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSidePosFct-1), GDB_ID.ROOT) if dAng then TabNAD[nSidePosFct] = { vtN[nSidePosFct], dAng, dist( ptP1, ptP2)} end -- creo percorsi di lavorazione local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) local dStep = dFacElev / nStep local dLargeVal local nLenSideMax for i = 1, nStep do local dOffs = ( i * dStep) - dFacElev if i == nStep then dOffs = 0 end local dOffsSide = 0 local dDelta = 100000 local dElevface for j = 1, nFacetCnt do if j == nSideNegFct or j == nSidePosFct then local dParzElev = dOffs -- calcolo la larghezza (solo 1 volta) if i == 1 then local dDeltadH = abs( TabNAD[j][3] - dH) local dDeltadV = abs( TabNAD[j][3] - dV) if dDeltadH < dDeltadV then if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then dDelta = dDeltadH dLargeVal = dV nLenSideMax = j end else if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then dDelta = dDeltadV dLargeVal = dH nLenSideMax = j end end end -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) end end local dRefLarge = ( 2 * dToolDiam) -- se la larghezza è più grande dell'utensile allora posso lavorare il passo if ( dLargeVal - dOffsSide) >= dToolDiam then for j = 1, nFacetCnt do if j == nSideNegFct or j == nSidePosFct then -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide for k = nStepSide, 1, -1 do local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) -- inserisco la lavorazione di fresatura local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, nil, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, true, false) if not bOk then return false, sErr end sWarn = sErr end end -- inserisco la lavorazione di fresatura a contatto con la faccia local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, nil, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep, true, false) if not bOk then return false, sErr end sWarn = sErr end end -- altrimenti passo saltato esco con errore else local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' EgtOutLog( sErr) return false, sErr end end return true, sWarn end --------------------------------------------------------------------- local function MakeMoreFces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bUseBlade) local ptC = {} local vtN = {} -- dati delle facce e ordinamento facce { } for i = 1, nFacetCnt do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end -- ordino le 4 facce: ( 1=laterale positiva 2=altra intermedia, 3=intermedia, 4=laterale negativa) local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN) if not bOk1 then return bOk1 end -- vettori di riferimento per le facce ortogonali all'asse trave local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) vtRef:normalize() local vtRef2nd = Vector3d( 0, vtN[vFaceOrd[2]]:getY(), vtN[vFaceOrd[2]]:getZ()) vtRef2nd:normalize() -- se non forzato uso truciolatore e abilitato il taglio di lama faccio le due pareti con antischeggia -- lavoro le facce laterali indirettamente lavorando le due facce intermedie if not bForceUseRough and bUseBlade then -- recupero la lavorazione con 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 dToolThick = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick end end local dTrim = -0.3 -- se ho la faccia laterale negativa if vFaceOrd[4] ~= 0 then -- inserisco la lavorazione di taglio per la faccia laterale negativa, faccio in modo che la testa rimanga nella stessa posizione per entrambe i tagli local bOk, sErr = CutChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[2], sCutting, true, vtRef, dTrim, dToolThick) if not bOk then return false, sErr end end -- se ho la faccia laterale positiva if vFaceOrd[1] ~= 0 then -- inserisco la lavorazione di taglio per la faccia laterale positiva local bOk, sErr = CutChainFacesByBlade( Proc, vFaceOrd[1], vFaceOrd[3], vFaceOrd[2], sCutting, true, vtRef, dTrim) if not bOk then return false, sErr end end end -- lavoro le facce intermedie if vFaceOrd[3] ~= 0 then -- inserisco la lavorazione di fresatura per la faccia intermedia local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[1], vFaceOrd[3], vFaceOrd[4], vtRef, nFacetCnt) if not bOk then return false, sErr end end if vFaceOrd[2] ~= 0 then -- inserisco la lavorazione di fresatura per la faccia intermedia local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[1], vFaceOrd[2], vFaceOrd[4], vtRef, nFacetCnt) if not bOk then return false, sErr end end return true end --------------------------------------------------------------------- local function Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRoughm, bSkipHead) -- se non sono in testa o coda if bSkipHead then local bUseBlade = true return MakeMoreFces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bUseBlade) else if bForceUseRough then return MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) else return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) end end end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- 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) -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore local _, bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) -- 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 on process ' .. tostring( Proc.Id) .. ' part box not found' EgtOutLog( sErr) return false, sErr end -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) if nFacetCnt < 2 then local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' EgtOutLog( sErr) return false, sErr end -- se ho due facce ( allora è di testa) if nFacetCnt == 2 then return Mach2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) -- altrimenti se ha 3 facce ma è di testa elseif nFacetCnt == 3 and ( Proc.Head or Proc.Tail) then return Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough) elseif nFacetCnt == 3 then return MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, true) else return Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, true) end return true end --------------------------------------------------------------------- return ProcessDovetail