-- FaceData.lua by Egalware s.r.l. 2024/04/18 -- Libreria lettura o calcolo dati e proprietà delle facce di una trimesh -- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE -- Tabella per definizione modulo local FaceData = {} -- Carico i dati globali local BD = require( 'BeamData') -- carico librerie local BeamLib = require( 'BeamLib') --------------------------------------------------------------------- -- restituisce la matrice delle adiacenze di Proc dove i e j sono le facce e a(ij) è l'angolo tra di esse; 0 se nessuna adiacenza function FaceData.GetAdjacencyMatrix( Proc) local vAdj = {} -- essendo la matrice simmetrica a diagonale nulla, ne calcolo solo la metà superiore for i = 1, Proc.Fct do vAdj[i] = {} for j = i + 1, Proc.Fct do _, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT) if not vAdj[i][j] then vAdj[i][j] = 0 end end end -- riempio di conseguenza il resto della matrice for i = 1, Proc.Fct do vAdj[i][i] = 0 for j = i + 1, Proc.Fct do vAdj[j][i] = vAdj[i][j] end end return vAdj end --------------------------------------------------------------------- -- restituisce un vettore con gli indici (0 based) delle facce triangolari (o quasi) di Proc function FaceData.GetTriangularFaces( Proc) local vTriangularFaces = {} for i = 1, Proc.Fct do if BeamLib.Is3EdgesApprox( Proc, i - 1) then table.insert( vTriangularFaces, i - 1) end end return vTriangularFaces end ------------------------------------------------------------------------------------------------------------- local function GetAdjacentFaces( Proc, idFace) local AdjacentFaces = {} local vAdj if Proc.AdjacencyMatrix then vAdj = Proc.AdjacencyMatrix else vAdj = FaceData.GetAdjacencyMatrix( Proc) end for i = 1, Proc.Fct do if vAdj[idFace + 1][i] and vAdj[idFace + 1][i] ~= 0 and ( idFace + 1 ~= i) then local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, idFace, i - 1, GDB_ID.ROOT) local dLength = dist( ptP1, ptP2) AdjacentFaces[i].Id = i - 1 AdjacentFaces[i].LengthOnMainFace = dLength end end return AdjacentFaces end --------------------------------------------------------------------- -- restituisce una tabella che correla numero di adiacenze e id delle facce con quello stesso numero di adiacenze function FaceData.GetFacesByAdjacencyNumber( Proc) local FacesByAdjacencyNumber = {} for i = 1, Proc.Fct do table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], i - 1) end return FacesByAdjacencyNumber end ------------------------------------------------------------------------------------------------------------- local function GetBottomFace( Proc) local BottomFace = {} -- la faccia di fondo ha sempre Fct - 1 adiacenze. Se si trovano più facce di fondo si sceglie quella con minor elevazione local vFacesByAdjNumber = FaceData.GetFacesByAdjacencyNumber( Proc) local vBottomFace = vFacesByAdjNumber[ Proc.Fct - 1] local nBottomFace if #vBottomFace > 1 then local dMinElevation = GEO.INFINITO for i = 1, #vBottomFace do for j = 1, Proc.Fct do if vBottomFace[i] == Proc.Face[j].Id then if Proc.Face[j].Elevation < dMinElevation then dMinElevation = Proc.Face[j].Elevation nBottomFace = Proc.Face[j].Id end end end end else nBottomFace = vBottomFace[1] end BottomFace.Id = nBottomFace BottomFace.FrameHV = Proc.Face[nBottomFace + 1].FrameHV BottomFace.Width = Proc.Face[nBottomFace + 1].Width BottomFace.Height = Proc.Face[nBottomFace + 1].Height BottomFace.Elevation = Proc.Face[nBottomFace + 1].Elevation BottomFace.VtN = Proc.Face[nBottomFace + 1].VtN return BottomFace end ------------------------------------------------------------------------------------------------------------- local function GetLongFaces( Proc) local LongFaces = {} if Proc.Fct > 5 then error( 'GetLongFaces : More than 5 faces not supported') end local idBottomFace = GDB_ID.NULL if Proc.MainFaces.BottomFace.Id then idBottomFace = Proc.MainFaces.BottomFace.Id else local BottomFace = GetBottomFace( Proc) idBottomFace = BottomFace.Id end -- facce adiacenti a quella di fondo, ordinate local FacesAdjacentToBottom = GetAdjacentFaces( Proc, idBottomFace) table.sort( FacesAdjacentToBottom, function( a, b) return a.LengthOnMainFace > b.LengthOnMainFace end) -- la prima faccia lunga è sempre la prima della lista LongFaces[1].Id = FacesAdjacentToBottom[1].Id -- si cerca l'eventuale seconda faccia lunga, ossia quella non adiacente alla prima if Proc.Fct > 3 then for i = 1, Proc.Fct do if ( i - 1) ~= idBottomFace and ( i - 1) ~= LongFaces[1].Id then local bIsAdjacent = false for j = 1, #Proc.Face[i].Adjacences do if Proc.Face[i].Adjacences[j].Id == LongFaces[i].Id then bIsAdjacent = true end end if not bIsAdjacent then LongFaces[2].Id = i - 1 break end end end end for i = 1, #LongFaces do for j = 1, Proc.Fct do if LongFaces[i].Id == Proc.Face[j].Id then LongFaces[i].Frame = Proc.Face[j].FrameHV LongFaces[i].Width = Proc.Face[j].Width LongFaces[i].Height = Proc.Face[j].Height LongFaces[i].Elevation = Proc.Face[j].Elevation LongFaces[i].VtN = Proc.Face[j].VtN end end end return LongFaces end ------------------------------------------------------------------------------------------------------------- function FaceData.GetFacesInfo( Proc, b3Raw) Faces = {} local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Proc.PartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) for i = 1, Proc.Fct do Faces[i].Id = i - 1 Faces[i].VtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT ) if Proc.Fct < 6 then local frHV, dFaceWidth, dFaceHeight = BeamLib.GetFaceHvRefDim( Proc.Id, i - 1, b3Raw) -- frame OCS faccia Faces[i].FrameHV = frHV -- larghezza OCS faccia Faces[i].Width = dFaceWidth -- altezza OCS faccia Faces[i].Height = dFaceHeight -- elevazione calcolata rispetto al box della parte Faces[i].Elevation = EgtSurfTmFacetElevationInBBox( Proc.Id, i - 1, b3Solid, true, GDB_ID.ROOT) -- adiacenze della faccia Faces[i].Adjacencies = GetAdjacentFaces( Proc, i - 1) end end return Faces end ------------------------------------------------------------------------------------------------------------- -- recupero facce principali della feature, in base alla topologia function FaceData.GetMainFaces( Proc) local MainFaces = {} -- faccia di fondo if Proc.FeatureTopology.Family == 'Rabbet' or Proc.FeatureTopology.Family == 'VGroove' or Proc.FeatureTopology.Family == 'Groove' or Proc.FeatureTopology.Family == 'Pocket' then MainFaces.BottomFace = GetBottomFace( Proc) end -- facce lunghe if Proc.FeatureTopology.Family == 'Rabbet' or Proc.FeatureTopology.Family == 'VGroove' or Proc.FeatureTopology.Family == 'Groove' or Proc.FeatureTopology.Family == 'Pocket' or Proc.FeatureTopology.Family == 'Tunnel' then MainFaces.LongFaces = GetLongFaces( Proc) end -- facce laterali return MainFaces end ------------------------------------------------------------------------------------------------------------- return FaceData