-- ProcessDovetail.lua by Egaltech s.r.l. 2021/02/04 -- Gestione calcolo giunzione coda di rondine -- 2022/06/10 Aggiunto il parametro dOvmTail per gestire sovramateriali in coda diversi da OVM_MID (sezioni alte e larghe) -- 2023/09/26 Modificata chiamata a GetFaceWithMostAdj. -- Tabella per definizione modulo local ProcessDovetail = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') 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 sUseRoughTool = '' -- 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 sUseRoughTool = '' if Proc.Prc == 138 then sUseRoughTool = 'Q02' -- d end end --------------------------------------------------------------------- local function EvaluateQParam( Proc, sUseRoughTool) 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 bForceUseRough end --------------------------------------------------------------------- local function OrderFaces( Proc, vtN) local dMinXFace = 0.99 local dPosXFace = 0 local dNegXFace = 0 local vFaceOrd = { 0, 0, 0} -- se 2 facce : ordine (1=0, 2=interna, 3=intermedia) if #vtN <= 2 then for i = 1, #vtN do local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) if dXVal < dMinXFace then dMinXFace = dXVal 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, #vtN 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 -- se 3 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia) elseif #vtN == 3 then for i = 1, #vtN do local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) if dXVal < dMinXFace then dMinXFace = dXVal vFaceOrd[3] = i end if dXVal > dPosXFace then dPosXFace = dXVal 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, #vtN 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 -- se 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) else for i = 1, #vtN do if vtN[i]:getX() > dPosXFace then dPosXFace = vtN[i]:getX() vFaceOrd[2] = i end if vtN[i]:getX() < dNegXFace then dNegXFace = vtN[i]:getX() vFaceOrd[4] = i end end if vFaceOrd[2] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' EgtOutLog( sErr) return false, sErr end if vFaceOrd[4] == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing external face' EgtOutLog( sErr) return false, sErr end local nMidFace = 3 for i = 1, #vtN do if i ~= vFaceOrd[2] and i ~= vFaceOrd[4] then vFaceOrd[nMidFace] = i nMidFace = 1 end end if vFaceOrd[1] == 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[1] - 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 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 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 dMachStep = 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 dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep end end if dMachStep <= 0.1 then dMachStep = 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, dMachStep 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, dMachStep end end end return false end --------------------------------------------------------------------- local function AddFaceToSurf( Proc, nPartId, b3Solid) -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error : missing AddGroup' EgtOutLog( sErr) return false, sErr end local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL -- punto medio sulla faccia local ptN = Point3d( b3Solid:getMin():getX(), ( b3Solid:getMin():getY() + b3Solid:getMax():getY())/2, ( b3Solid:getMin():getZ() + b3Solid:getMax():getZ())/2) -- creo superficie intermedia local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN, -X_AX(), b3Solid, GDB_ID.ROOT) -- se esiste la superfice aggiunta, la ritaglio la superficie con le facce if nSurfInt then -- inverto la normale EgtInvertSurf( nSurfInt) for i = 1, Proc.Fct do local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) end -- unisco la nuova superfice if nSurfInt then local bOk = EgtSurfTmAdd( nNewProc, nSurfInt) if bOk then EgtErase( nSurfInt) Proc.Id = nNewProc Proc.Fct = EgtSurfTmFacetCount( nNewProc) end end end 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, 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) -- recupero identificativo del pezzo local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) -- se una sola faccia if Proc.Fct == 1 then local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) if vtN0:getX() < -0.1 then -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione if b3Solid:getDimX() > BD.LEN_SHORT_PART then return true else -- aggiungo faccia AddFaceToSurf( Proc, nPartId, b3Solid) return false end 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 -- se due facce e interessa veramente la coda, allora di coda if Proc.Fct <= 2 then if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione if b3Solid:getDimX() > BD.LEN_SHORT_PART then return true else -- aggiungo faccia AddFaceToSurf( Proc, nPartId, b3Solid) return false end end end -- deve avere la normale principale diretta verso la coda local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc, 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 -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione if b3Solid:getDimX() > BD.LEN_SHORT_PART then return true else -- aggiungo faccia AddFaceToSurf( Proc, nPartId, b3Solid) return false end 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 nFlatFaceNeg local bDown = false -- individuo se c'è faccia rivolta verso Z- for i = 1, Proc.Fct do local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) if vtN:getZ() < -0.99 then nFlatFaceNeg = i - 1 break end end -- se trovata faccia rivolta verso Z- if nFlatFaceNeg then -- se 3 o più facce sicuramente è in mezzo, setto il ribaltamento senza ulteriori controlli if Proc.Fct >= 3 then bDown = true -- altrimenti è in testa o coda e verifico se lavorabile da sotto else -- prendo le dimensioni della faccia local nOtherFace = 1 - nFlatFaceNeg 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 if dAng > -89.99 and dAng < 0 then bDown = true -- altrimenti, verifico se lunghezza faccia piatta è compatibile con il taglio di lama else local dLargeFace = Proc.Box:getDimX() local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough = VerifyIfRoughMill( dLargeFace, -Z_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 -- altrimenti controllo la componente in Z delle facce else local vtN = {} for i = 1, Proc.Fct do vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) end for i = 1, Proc.Fct 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 Proc.Fct == 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 Proc.Fct == 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, 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, 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 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 vtOrthoO = Vector3d( vtRef2) 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 = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -( dTrim + dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end end return true end --------------------------------------------------------------------- local function MachChainFacesByBlade( 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, 180) EgtSetMachiningParam( MCH_MP.LOTANG, 0) EgtSetMachiningParam( MCH_MP.LOPERP, 180) 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 bHead == ( dNyMax < 0) then EgtSetMachiningParam( MCH_MP.LITANG, 340) EgtSetMachiningParam( MCH_MP.LIPERP, -100) elseif dNzMax < 0 and bHead == ( 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 ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end return true end --------------------------------------------------------------------- local function MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) -- dati delle facce local ptC = {} local vtN = {} for i = 1, Proc.Fct do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) if not bOk1 then return bOk1, sErr1 end ---- determino se di testa o di coda local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) -- 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 Proc.Fct > 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 -- calcolo la 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 > -89.9 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 -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error : missing AddGroup' EgtOutLog( sErr) return false, sErr end -- 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( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) elseif vFaceOrd[3] ~= 0 then vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) end if #vCuts > 0 then local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, 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 > -89.9 then dTrim = 0 else dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() end end -- se esistono faccia interna ed altra intermedia, verifico se richiedono taglio a cubetti local vCuts2 = {} if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) elseif vFaceOrd[1] ~= 0 then vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true) end if #vCuts2 > 0 then local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) if not bOk then return false, sErr end end -- se non ha fatto nessun taglio a cubetti e ho 3 facce if #vCuts == 0 and #vCuts2 == 0 and Proc.Fct > 2 then -- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie local bOk, sErr = MachChainFacesByBlade( 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- se altrimenti non ha fatto una parte dei tagli a cubetti elseif #vCuts == 0 and #vCuts2 == 0 then local bIntCut = false if vFaceOrd[2] ~= 0 then -- inserisco la lavorazione local nDirVect = BL.GetNearestOrthoOpposite( vtRef) local bOk, sNameOrErr bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end 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( TabNAD[j][1]) 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, ( 60 + 0.5 * dToolDiam)) EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( 60 + 0.5 * dToolDiam)) -- 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 ML.ApplyMachining( 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, dMachStepMaster, nMainFace, dElevMain) local sWarn = '' local sMilling local dToolDiam = 100 local dSideAngle = 0 local dMaxMat = 50 local dMaxDepth = 50 local dMachStep = 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 flag 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.1 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 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep end end if dMachStep <= 0.1 then dMachStep = dMaxMat * 0.5 end else sMilling = sMillingMaster dToolDiam = dToolDiamMaster dMaxMat = dMaxMatMaster dSideAngle = dSideAngleMaster dMachStep = dMachStepMaster 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, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) if dLenIn > 0 then dFacElev = dLenIn elseif dLenOut then dFacElev = dLenOut end else -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc, nPartId, false, sin(dSideAngle)) if not nFacInd or nFacInd < 0 then -- provo eliminando i sottosquadra nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc, 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 = Fbs.MakeOne( Proc.Id, ( i - 1), sCutting, dSawDiam, nOrthoOpposite, nil, -( dTrim + dExtraZed), BD.CUT_SIC, 0, 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) / dMachStep) 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, dLenOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j]) if dLenIn > 0 then dElevface = dLenIn elseif dLenOut then dElevface = dLenOut 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 Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) -- verifico le normali delle facce -- individuo se c'è faccia rivolta verso Z- local nFlatFaceNeg local vtN = {} local ptC = {} for i = 1, Proc.Fct do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) if vtN[i]:getZ() < -0.99 then nFlatFaceNeg = i - 1 end end -- se trovata faccia rivolta verso Z- faccio controllo di lavorabilità da sotto if nFlatFaceNeg then -- prendo le dimensioni della faccia local dLargeFace = Proc.Box:getDimX() local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) local bUseRough, sMilling = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) -- se non forzato truciolatore provo la lama if not bForceUseRough and bUseBlade then return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) -- altrimenti provo con il truciolatore else local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) -- se non ho la lavorazione esco if not sMilling then local sErr = 'Error, machining or tool not found ' .. sName EgtOutLog( sErr) return false, sErr end -- inserisco la lavorazione di fresatura 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 nOtherInd = 2 - nFlatFaceNeg local nFaceUse = BL.GetNearestParalOpposite( vtN[nOtherInd]) -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}}) -- imposto uso faccia EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- imposto inversione e lato correzione EgtSetMachiningParam( MCH_MP.INVERT, true) EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- annullo offset radiale EgtSetMachiningParam( MCH_MP.OFFSR, 0) -- applico allungamento iniziale e finale EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) -- imposto posizione braccio porta testa local nSCC = MCH_SCC.ADIR_YP EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- eseguo if not ML.ApplyMachining( 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, Proc.Fct 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 = 1 - nFacet 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, dMachStep = 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, Proc.Fct, bForceUseRough, bUseBlade, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dMachStep, nOtherFace, dLargeFace) if not bOk then return false, sErr end elseif bUseBlade then local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) -- 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, Proc.Fct, bForceUseRough, bUseBlade, true, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dMachStep, 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 == Proc.Fct 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=0, 2=interna, 3=intermedia) local bOk, sErr, vFaceOrd = OrderFaces( Proc, 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) -- 2021.02.04 FS ha chiesto di fare con lama anche i concavi (vecchio controllo : bUCut or bForceUseRough) local bForceMakeMill = bForceUseRough -- 2020.04.28 FS 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, dMachStep = 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, Proc.Fct, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dMachStep, 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, Proc.Fct, 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, dMachStep = 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, Proc.Fct, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dMachStep, 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, Proc.Fct, 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, dMachStep = 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, Proc.Fct, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false, nil, nil, sMilling, dToolDiam, dMaxMat, dSideAngle, dMachStep, 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, Proc.Fct, bForceUseRough, true, bForceMakeMill, bUCut, bOCut, false) end if not bOk then return false, sErr end end else return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) end end end end end return true end --------------------------------------------------------------------- local function MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail) -- recupero la geometria ausiliaria local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if not AuxId then return true end AuxId = AuxId + Proc.Id -- recupero il centro e la normale della faccia ausiliaria local ptC, vtN = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) if not vtN then local sErr = 'Error : wrong Normal of AuxSurface' EgtOutLog( sErr) return false, sErr end -- verifico se di testa o coda local bHead = ( vtN:getX() > 0) -- recupero la lavorazione per la geometria ausiliaria local sCutting = ML.FindCutting( 'HeadSide') if not sCutting then local sErr = 'Error : 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 : missing AddGroup' EgtOutLog( sErr) return false, sErr end -- verifico se già fatto con altro componente della stessa feature local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId), 'b') if bAuxMachined then return true end -- verifico se coincide con taglio di testa if bHead and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then return true end -- verifico se coincide con taglio di coda if not bHead and AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < dOvmTail + 10 * GEO.EPS_SMALL then return true end -- inserisco la lavorazione 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, PartId = Proc.PartId} CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc) local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) if not bOk then return bOk, sErr end -- imposto la nota nel gruppo aggiuntivo di lavorazione per evitare di tagliare una seconda volta EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) return true 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 dMachStep = 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 dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep end end if dMachStep <= 0.1 then dMachStep = dMaxMat * 0.5 end local nFacInd = nMiddleFct - 1 local dFacElev -- calcolo elevazione local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct]) if dLenIn > 0 then dFacElev = dLenIn elseif dLenOut then dFacElev = dLenOut 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 or 0) - 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) / dMachStep) 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 = EgtIf( nSideNegFct, ( 2 * dToolDiam), 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 * EgtIf( nSideNegFct, 0.5, 1)) 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 MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) local ptC = {} local vtN = {} -- dati delle facce e ordinamento facce { } for i = 1, Proc.Fct do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end -- ordino le 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) if not bOk1 then return bOk1, sErr1 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[1]]:getY(), vtN[vFaceOrd[1]]: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 = MachChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim, dToolThick) if not bOk then return false, sErr end end -- se ho la faccia laterale positiva if vFaceOrd[2] ~= 0 then -- inserisco la lavorazione di taglio per la faccia laterale positiva local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[2], vFaceOrd[3], vFaceOrd[1], 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[2], vFaceOrd[3], vFaceOrd[4], vtRef, Proc.Fct) if not bOk then return false, sErr end end if vFaceOrd[1] ~= 0 then -- inserisco la lavorazione di fresatura per la faccia intermedia local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[1], vFaceOrd[4], vtRef, Proc.Fct) if not bOk then return false, sErr end end return true end --------------------------------------------------------------------- local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bInMiddle) -- flag per lavorazioni sulla testa o coda local bUseBlade = false local bForceMakeMill = bForceUseRough local bUCut = false local bOCut = false local bJoinFaces = true -- modifiche ai flag per lavorazione in mezzo if bInMiddle then -- 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 -- dati delle facce local ptC = {} local vtN = {} for i = 1, Proc.Fct do ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) end -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) if not bOk1 then return bOk1, sErr1 end -- verifica se di testa o coda local bHead = false if not bInMiddle then bHead = ( vtN[vFaceOrd[2]]:getX() > 0) end -- se non in mezzo può essere necessario lavorare come in mezzo if not bInMiddle then -- calcolo l'elevazione local dSideElev = 0 local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) if dLenIn > 0 then dSideElev = dLenIn elseif dLenOut then dSideElev = dLenOut end -- determino il massimo affondamento con l'utensile 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 dMaxDepth = 10 if EgtMdbSetCurrMachining( sMilling) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end -- se l'elevazione supera l'affondamento, lavoro perpendicolare all'asse trave if dSideElev > dMaxDepth then return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) end end -- lavoro le restanti facce in modo standard return MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, vFaceOrd, bHead) end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, dOvmTail) -- sovramateriale di coda dOvmTail = dOvmTail or BD.OVM_MID -- 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) if Proc.Fct < 2 then local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' EgtOutLog( sErr) return false, sErr end -- se ha due facce ( allora è di testa o coda) if Proc.Fct == 2 then -- eventuale taglio di testa o coda local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail) if not bAuxOk then return bAuxOk, sAuxErr end -- lavorazione della feature local bOk, sErr = Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) if not bOk then return bOk, sErr end -- se ha 3 facce ed è di testa o coda elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then -- eventuale taglio di testa o coda local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail) if not bAuxOk then return bAuxOk, sAuxErr end -- lavorazione della feature if bForceUseRough then local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) if not bOk then return bOk, sErr end else local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) if not bOk then return bOk, sErr end end -- se ha 3 facce (e interna) elseif Proc.Fct == 3 then local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) if not bOk then return bOk, sErr end -- altrimenti 4 facce (e interna) else local bOk, sErr = MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) if not bOk then return bOk, sErr end end -- aggiornamento ingombro di testa o coda if Proc.Head then local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() BL.UpdateHCING( nRawId, dHCI) elseif Proc.Tail then local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() BL.UpdateTCING( nRawId, dTCI) end return true end --------------------------------------------------------------------- return ProcessDovetail