242 lines
8.1 KiB
Lua
242 lines
8.1 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 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] = {}
|
|
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
|
|
if not FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies] then
|
|
FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies] = {}
|
|
end
|
|
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], i - 1)
|
|
end
|
|
|
|
return FacesByAdjacencyNumber
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function GetBottomFace( Proc)
|
|
local BottomFace = {}
|
|
|
|
if Proc.Topology.Family == 'Tunnel' then
|
|
return BottomFace
|
|
elseif not ( Proc.FeatureTopology.Family == 'Rabbet' or Proc.FeatureTopology.Family == 'VGroove' or Proc.FeatureTopology.Family == 'Groove' or Proc.FeatureTopology.Family == 'Pocket') then
|
|
error( 'GetBottomFace : Topology not implemented')
|
|
end
|
|
|
|
-- 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.Faces[j].Id then
|
|
if Proc.Faces[j].Elevation < dMinElevation then
|
|
dMinElevation = Proc.Faces[j].Elevation
|
|
nBottomFace = Proc.Faces[j].Id
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
nBottomFace = vBottomFace[1]
|
|
end
|
|
|
|
BottomFace.Id = nBottomFace
|
|
BottomFace.FrameHV = Proc.Faces[nBottomFace + 1].FrameHV
|
|
BottomFace.Width = Proc.Faces[nBottomFace + 1].Width
|
|
BottomFace.Height = Proc.Faces[nBottomFace + 1].Height
|
|
BottomFace.Elevation = Proc.Faces[nBottomFace + 1].Elevation
|
|
BottomFace.VtN = Proc.Faces[nBottomFace + 1].VtN
|
|
|
|
return BottomFace
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function GetLongFaces( Proc, MainFaces)
|
|
local LongFaces = {}
|
|
|
|
if Proc.Fct > 5 then
|
|
error( 'GetLongFaces : Topology not implemented')
|
|
end
|
|
|
|
local idBottomFace
|
|
if MainFaces.BottomFace then
|
|
idBottomFace = MainFaces.BottomFace.Id
|
|
else
|
|
local BottomFace = GetBottomFace( Proc)
|
|
idBottomFace = BottomFace.Id or GDB_ID.NULL
|
|
end
|
|
|
|
local FacesToAnalyze = {}
|
|
for i = 1, Proc.Fct do
|
|
if Proc.Faces[i].Id ~= idBottomFace then
|
|
FacesToAnalyze[i] = Proc.Faces[i]
|
|
end
|
|
end
|
|
|
|
|
|
if Proc.FeatureTopology.Family == 'Tunnel' then
|
|
|
|
else
|
|
-- facce adiacenti a quella di fondo, ordinate
|
|
FacesToAnalyze = GetAdjacentFaces( Proc, idBottomFace)
|
|
table.sort( FacesToAnalyze, function( a, b) return a.LengthOnMainFace > b.LengthOnMainFace end)
|
|
end
|
|
|
|
-- la prima faccia lunga è sempre la prima della lista
|
|
LongFaces[1].Id = FacesToAnalyze[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.Faces[i].Adjacences do
|
|
if Proc.Faces[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.Faces[j].Id then
|
|
LongFaces[i].Frame = Proc.Faces[j].FrameHV
|
|
LongFaces[i].Width = Proc.Faces[j].Width
|
|
LongFaces[i].Height = Proc.Faces[j].Height
|
|
LongFaces[i].Elevation = Proc.Faces[j].Elevation
|
|
LongFaces[i].VtN = Proc.Faces[j].VtN
|
|
end
|
|
end
|
|
end
|
|
|
|
return LongFaces
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function FaceData.GetFacesInfo( Proc, b3Raw)
|
|
local Faces = {}
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Proc.PartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
|
|
for i = 1, Proc.Fct do
|
|
Faces[i] = {}
|
|
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.Topology.Family == 'Rabbet' or Proc.Topology.Family == 'VGroove' or Proc.Topology.Family == 'Groove' or Proc.Topology.Family == 'Pocket' then
|
|
MainFaces.BottomFace = GetBottomFace( Proc)
|
|
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
|
|
end
|
|
|
|
return MainFaces
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return FaceData |