-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2022/03/21 -- Gestione calcolo giunzione tirolese -- 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 ProcessTyroleanDovetail = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') local DC = require( 'DiceCut') local Cut = require( 'ProcessCut') EgtOutLog( ' ProcessTyroleanDovetail started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') -- variabili assegnazione parametri Q local sDepthChamferMill = '' -- d --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessTyroleanDovetail.Identify( Proc) return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136) end --------------------------------------------------------------------- local function AssignQValues( Proc) -- reset delle variabili assegnazione parametri Q sDepthChamferMill = '' if Proc.Prc == 136 then sDepthChamferMill = 'Q01' -- d end end --------------------------------------------------------------------- local function TestElleShape3( Proc) -- valida solo nel caso di tre facce if Proc.Fct ~= 3 then return false end -- determino se L con una faccia terminale o U con tre facce local bIsL = true for i = 1, 3 do local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] -- le conto local nCount = 0 for j = 1, #vFacAdj do if vFacAdj[j] >= 0 then nCount = nCount + 1 end end if nCount == 1 then bIsL = false break end end return bIsL end --------------------------------------------------------------------- -- Classificazione della feature function ProcessTyroleanDovetail.Classify( Proc, b3Raw) -- 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 ho 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) local dDist = dist( ptP1, ptP2) local dLargeface local dDelta = 100000 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 lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento if dLargeface > BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then bDown = true end -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then bDown = true end end -- altrimenti controllo la componente in Z delle facce else for i = 1, nFacetCnt do local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) -- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then -- se con due facce e corto è fattibile if nFacetCnt < 3 and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then return true else return false end end end end return true, bDown end --------------------------------------------------------------------- local function EvaluateQParam( Proc, sDephtCham) local nChamfer = 0 -- verifico che lo smusso sia richiesto local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 if dDepth > 0 then nChamfer = 1 end return nChamfer, dDepth end --------------------------------------------------------------------- local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, dOvmTail) -- 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 (1=faccia ausiliaria, 2=interna, 3=intermedia) local vFaceOrd = { 0, 0, 0} local dMinZedFace = 1 for i = 1, nFacetCnt do local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) if dXVal < dMinZedFace then dMinZedFace = 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, 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 -- 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() -- 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 : 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()) < dOvmTail + 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, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId} CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc) local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) -- 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( 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 -- 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 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 = 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 else -- 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()) < dOvmTail + 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, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId} CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc) local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) -- 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 -- taglio sulla faccia interna local bIntCut = false if vFaceOrd[2] ~= 0 then -- inserisco la lavorazione local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, 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 -- 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, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) local sWarn = '' -- 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 = 'MillTCone_' .. ( 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 -- aggiungo geometria EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) -- imposto uso faccia local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) 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) if kStep % 2 == 1 then -- imposto lato destro EgtSetMachiningParam( MCH_MP.WORKSIDE, 2) -- imposto inversione EgtSetMachiningParam( MCH_MP.INVERT, true) else -- imposto lato sinistro EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) -- tolgo inversione EgtSetMachiningParam( MCH_MP.INVERT, false) end -- imposto affondamento in base al passo del ciclo EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) --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( ( 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 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 MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) local sWarn = '' -- 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 -- recupero l'angolo di spoglia dell'utensile a tronco di cono -- recupero la lavorazione local sMchFind = 'ProfTCone' local sMilling = ML.FindMilling( sMchFind) if not sMilling then local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. 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 local bUCutMax 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) end end if dStepmach <= 0.1 then dStepmach = dMaxMat * 0.5 end -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa local 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) .. ' MakeMachByMill could not find reference face' EgtOutLog( sErr) return false, sErr else bUCutMax = true end end -- verifico se sono presenti i parametri Q per la profondità smusso e -- per eseguire in esclusiva solo lo smusso local nChamfer, dDepthCham = EvaluateQParam( Proc, sDepthChamferMill) -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) -- verifico se U local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) -- verifico se due facce o L con una o due facce di terminazione local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc)) -- faccio tagli di lama come antischeggia sulle altre 2 facce -- 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 -- vettore di riferimento per le facce ortogonali all'asse trave local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ()) vtRef:normalize() local TabNAD = {} -- ciclo inserimento tagli antischeggia sulle facce for i = 1, nFacetCnt do if (i-1) ~= nFacInd then -- 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 _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT) local dTrim local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) if dAng then TabNAD[i] = { vtN2, dAng, dist( ptP1, ptP2)} end if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then dTrim = 0 else dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len() end -- inserisco la lavorazione local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) if not bOk then return bOk, sNameOrErr end end end -- creo percorsi di lavorazione -- local nCountSkipStep = 0 -- local nMaxSkippedStep = 0 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 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 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 -- se la larghezza è più grande dell'utensile allora posso lavorare il passo if ( dLargeVal - dOffsSide) >= dToolDiam then -- resetto il contatore skip -- nCountSkipStep = 0 for j = 1, nFacetCnt do if (j-1) ~= nFacInd then -- calcolo l'offset radiale in base all'affondamento 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 -- inserisco la lavorazione di fresatura local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep) if not bOk then return false, sErr else sWarn = sErr end -- se lato lavorato è il più lungo e la larghezza cava consente passi interni if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide for k = 1, nStepSide 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, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) if not bOk then return false, sErr else sWarn = sErr end end 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 -- se ho saltato più di un passo invalido le lavorazioni -- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then -- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' -- EgtOutLog( sErr) -- return false, sErr -- end return true, sWarn end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessTyroleanDovetail.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) -- 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 local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, dOvmTail) if not bOk then return bOk, sErr end else local bOk, sErr = MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) 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 ProcessTyroleanDovetail