Files
databeamnew/LuaLibs/FaceData.lua
T
luca.mazzoleni 65fec1e05d - implementata parzialmente GetMainFaces e funzioni accessorie
- migliorie stilistiche e refactoring parziale
2024-04-18 18:34:09 +02:00

230 lines
7.7 KiB
Lua

-- 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