-- ProcessBlockHausFront.lua by Egaltech s.r.l. 2020/08/03 -- Gestione calcolo giunzione block house in testa -- 2022/06/10 Aggiunto il parametro dOvmTail per gestire sovramateriali in coda diversi da OVM_MID (sezioni alte e larghe) -- Tabella per definizione modulo local ProcessBlockHausFront = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') local DC = require( 'DiceCut') local Cut = require( 'ProcessCut') EgtOutLog( ' ProcessBlockHausFront started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessBlockHausFront.Identify( Proc) return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 38) end --------------------------------------------------------------------- -- Classificazione della feature function ProcessBlockHausFront.Classify( Proc) -- verifico le normali delle facce local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) for i = 1, nFacetCnt do local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, -- do errore perchè non è ancora gestita la rotazione di 90° -- 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 return false end end return true, false end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessBlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, dOvmTail) if not dOvmTail then dOvmTail = BD.OVM_MID end -- recupero l'ingombro del grezzo di appartenenza local b3Raw = EgtGetRawPartBBox( nRawId) -- 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 -- 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 -- ordino le facce (1=esterna, 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[1] = i elseif 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 bHead = ( vtN[vFaceOrd[1]]:getX() > 0) 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 la geometria ausiliaria local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id 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 local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() 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 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 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, 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 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 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, 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 --------------------------------------------------------------------- return ProcessBlockHausFront