Files
databeamnew/LuaLibs/FaceData.lua
T
luca.mazzoleni 716ebf7046 - in FaceData si calcolano i MainEdges solo per le facce che hanno esattamente 4 lati
- in STR0005 corretto calcolo dExtendAfterTail
- in FACEBYBLADE si i tagli troncanti in coda sono sempre dichiarati AfterTail; eliminata assegnazione a posteriori in BLADETOWASTE
2025-10-13 17:52:39 +02:00

687 lines
25 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')
local Logs = require( 'Logs')
---------------------------------------------------------------------
-- 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.nFct do
vAdj[i] = {}
for j = i + 1, Proc.nFct 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.nFct do
vAdj[i][i] = 0
for j = i + 1, Proc.nFct 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)
-- se la feature ha una sola faccia, esco subito
if Proc.nFct <= 1 then
return
end
local vTriangularFaces = {}
for i = 1, Proc.nFct do
if BeamLib.Is3EdgesApprox( Proc, i - 1) then
table.insert( vTriangularFaces, i - 1)
end
end
return vTriangularFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetNotAdjacentFaces( Proc, idFace)
local NotAdjacentFaces = {}
for i = 1, Proc.nFct do
if Proc.Faces[i].id ~= idFace then
local bIsAdjacent = false
for j = 1, #Proc.Faces[idFace + 1].Adjacencies do
if Proc.Faces[i].id == Proc.Faces[idFace + 1].Adjacencies[j] then
bIsAdjacent = true
end
end
if not bIsAdjacent then
table.insert( NotAdjacentFaces, Proc.Faces[i])
end
end
end
return NotAdjacentFaces
end
---------------------------------------------------------------------
-- restituisce una tabella che correla numero di adiacenze e id delle facce con quello stesso numero di adiacenze
function FaceData.GetFacesByAdjacencyNumber( Proc)
-- se la feature ha una sola faccia, esco subito
if Proc.nFct <= 1 then
return {}
end
local FacesByAdjacencyNumber = {}
for i = 1, 10 do
FacesByAdjacencyNumber[i] = {}
end
for i = 1, Proc.nFct do
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
end
return FacesByAdjacencyNumber
end
-------------------------------------------------------------------------------------------------------------
function FaceData.GetEdgesInfo( ProcOrId, idFace )
local Edges = {}
-- disambiguazione feature vs id trimesh
local Proc = {}
if type( ProcOrId) == "table" then
Proc = ProcOrId
elseif type( ProcOrId) == "number" then
Proc.id = ProcOrId
else
error( 'GetEdgesInfo : Only feature or trimesh supported')
end
local nFaceType, EdgesEgt = EgtSurfTmGetFacetOutlineInfo( Proc.id, idFace, GDB_ID.ROOT)
for i = 1, #EdgesEgt do
local nPreviousEdgeIndex = i - 1
if i == 1 then
nPreviousEdgeIndex = #EdgesEgt
end
local nNextEdgeIndex = i + 1
if i == #EdgesEgt then
nNextEdgeIndex = 1
end
-- l'elevazione si tiene sempre positiva e la normale sempre diretta verso l'interno della faccia
-- per sapere se il lato è aperto c'è la proprietà apposita bIsOpen
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = EdgesEgt[i].Adj
CurrentEdge.dLength = EdgesEgt[i].Len
CurrentEdge.dElevation = abs( EdgesEgt[i].Elev)
CurrentEdge.bIsOpen = EdgesEgt[i].Open
CurrentEdge.vtN = Vector3d( EdgesEgt[i].Norm)
if CurrentEdge.bIsOpen then
CurrentEdge.vtN = -CurrentEdge.vtN
end
CurrentEdge.bIsStartOpen = EdgesEgt[nPreviousEdgeIndex].Open
CurrentEdge.bIsEndOpen = EdgesEgt[nNextEdgeIndex].Open
CurrentEdge.sType = 'Standard'
CurrentEdge.id = i - 1
table.insert( Edges, CurrentEdge)
end
return nFaceType, Edges
end
-------------------------------------------------------------------------------------------------------------
function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
EgtOutLog( '---Faces START---')
local Faces = {}
local function FaceIsToGet( nIndex)
if not FacesToGet then return false end
for i = 1, #FacesToGet do
-- correggo indice perche' id delle facce è 0-based
if FacesToGet[i] == nIndex - 1 then
return true
end
end
return false
end
local vAdj
if Proc.AdjacencyMatrix then
vAdj = Proc.AdjacencyMatrix
else
vAdj = FaceData.GetAdjacencyMatrix( Proc)
end
if not Proc.nFct then
Proc.nFct = EgtSurfTmFacetCount( Proc.id) or 0
end
for i = 1, Proc.nFct do
Faces[i] = {}
Faces[i].id = i - 1
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT)
if Proc.nFct < 6 or FaceIsToGet( i) then
-- frame OCS faccia
Faces[i].vtFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
-- elevazione calcolata rispetto al box della parte
Faces[i].dElevation = EgtSurfTmFacetElevationInBBox( Proc.id, i - 1, Part.b3Part, true, GDB_ID.ROOT)
-- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo
local _, dLongDimension, dShortDimension = EgtSurfTmFacetMinAreaRectangle( Proc.id, i - 1, GDB_ID.ROOT)
Faces[i].dArea = dShortDimension * dLongDimension
Faces[i].dLMinRectangle = dLongDimension
Faces[i].dWMinRectangle = dShortDimension
local nFaceType, Edges = FaceData.GetEdgesInfo( Proc, i - 1)
Faces[i].bIsOkForMachining = nFaceType < 1
Faces[i].Edges = Edges
-- TODO valutare se fare un output unico alla fine o gestire log in altro modo
EgtOutLog( 'Facet ' .. Faces[i].id .. ' of ' .. Proc.nFct - 1)
EgtOutLog( ' vtN: ' .. tostring( Faces[i].vtN))
-- adiacenze della faccia
-- TODO chiamarle in modo che si capisca che sono solo gli id e non l'intero oggetto faccia
Faces[i].Adjacencies = {}
for j = 1, Proc.nFct do
if vAdj[i][j] and vAdj[i][j] ~= 0 and ( i ~= j) then
table.insert( Faces[i].Adjacencies, j - 1)
if EgtGetDebugLevel() >= 3 then
EgtOutLog( ' Adjacent to facet: ' .. j - 1)
end
end
end
end
end
EgtOutLog( '---Faces END---')
return Faces
end
-------------------------------------------------------------------------------------------------------------
function FaceData.IsFaceRectangular( Proc, idFace)
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
if nContourCnt > 1 then
error( 'IsFaceRectangular : too many loops')
end
local bIsRectangular = EgtCurveIsARectangle( nContourId)
-- elimino curve create
for i = 1, nContourCnt do
EgtErase( nContourId + i - 1)
end
return bIsRectangular
end
-------------------------------------------------------------------------------------------------------------
function FaceData.IsFaceRhomboid( Proc, idFace)
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
if nContourCnt > 1 then
error( 'IsFaceRectangular : too many loops')
end
local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId)
local bIsRhomboid = false
-- un parallelogramma è un trapezoide con i lati paralleli a due a due
if bIsTrapezoid
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[1].vtN, Proc.Faces[idFace + 1].Edges[3].vtN)
and AreOppositeVectorApprox( Proc.Faces[idFace + 1].Edges[2].vtN, Proc.Faces[idFace + 1].Edges[4].vtN) then
bIsRhomboid = true
end
-- elimino curve create
for i = 1, nContourCnt do
EgtErase( nContourId + i - 1)
end
return bIsRhomboid
end
-------------------------------------------------------------------------------------------------------------
local function CompareEdgesBottomFace( EdgeA, EdgeB)
-- prima i lati con facce adiacenti
if ( EdgeA.idAdjacentFace > -1) and ( EdgeB.idAdjacentFace < 0) then
return true
elseif ( EdgeA.idAdjacentFace < 0) and ( EdgeB.idAdjacentFace > -1) then
return false
-- se entrambi con facce adiacenti, si sceglie quello convesso (non chiuso)
else
if EdgeA.bIsOpen and not ( EdgeB.bIsOpen) then
return true
elseif not ( EdgeA.bIsOpen) and EdgeB.bIsOpen then
return false
-- se entrambi aperti o entrambi chiusi, si sceglie quello più lungo
else
if EdgeA.dLength > EdgeB.dLength then
return true
elseif EdgeA.dLength < EdgeB.dLength then
return false
end
end
end
end
-------------------------------------------------------------------------------------------------------------
-- TODO valutare refactoring per mettere i calcoli del tunnel in una funzione
-- TODO creare le facce tunnel solo se non ci sono già. Verirficare all'inizio se già presente in AddGrpId e nel caso riferire all'id di quella esistente e ricalcolare solo le informazioni della faccia.
-- TODO test iniziale replicato in GetMainFaces
local function GetTunnelFaces( Proc, Part)
local TunnelAddedFaces = {}
if not ( ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
or ( Proc.nFct == 1 ) or Proc.Topology.sName == 'Bevel-2-Blind') then
error( 'GetTunnelFaces : Topology not implemented')
end
-- direzione del tunnel
local vtTunnelDirection = V_NULL()
if Proc.nFct == 1 then
local EdgesSortedByElevation = BeamLib.TableCopyDeep( Proc.Faces[1].Edges)
table.sort( EdgesSortedByElevation, function (a, b) return a.dElevation > b.dElevation end )
vtTunnelDirection = Proc.Faces[1].vtN ^ EdgesSortedByElevation[1].vtN
else
vtTunnelDirection = Proc.Faces[1].vtN ^ Proc.Faces[ Proc.Faces[1].Adjacencies[1] + 1].vtN
end
-- centro del tunnel
local frTunnel = Frame3d( Proc.Faces[1].ptCenter, vtTunnelDirection)
local b3Tunnel = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, frTunnel)
local ptTunnelCenter = b3Tunnel:getCenter()
ptTunnelCenter:toGlob( frTunnel)
-- recupero gruppo per geometria addizionale
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
if not nAddGrpId then
-- TODO gestire meglio questo errore. Non conviene creare e verificare all'inizio se il gruppo esiste?
EgtOutLog( 'Error : missing AddGroup')
return TunnelAddedFaces
end
-- faccia centrale
local nMiddleTmId = EgtSurfTmPlaneInBBox( nAddGrpId, ptTunnelCenter, vtTunnelDirection, Part.b3Part, GDB_ID.ROOT)
-- TODO se non si riesce a costruire la faccia bisogna dare errore o semplicemente non ritornarla??
for i = 1, Proc.nFct do
EgtCutSurfTmPlane( nMiddleTmId, Proc.Faces[i].ptCenter, -Proc.Faces[i].vtN, false, GDB_ID.ROOT)
end
-- facce laterali
local nLateralTmId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
EgtCutSurfTmPlane( nLateralTmId, ptTunnelCenter, -vtTunnelDirection, false, GDB_ID.ROOT)
-- unione facce
-- TODO cambiare nome alla trimesh?? non contiene più solamente la faccia di mezzo
TunnelAddedFaces.MiddleFaceTm = {}
TunnelAddedFaces.MiddleFaceTm.id = EgtSurfTmBySewing( nAddGrpId, { nMiddleTmId, nLateralTmId}, true)
-- TODO c'è un modo più elegante per raccogliere le informazioni delle facce aggiunte
TunnelAddedFaces.MiddleFaceTm.sType = 'Tunnel'
TunnelAddedFaces.MiddleFaceTm.nFct = EgtSurfTmFacetCount( TunnelAddedFaces.MiddleFaceTm.id)
TunnelAddedFaces.MiddleFaceTm.Faces = FaceData.GetFacesInfo( TunnelAddedFaces.MiddleFaceTm, Part)
return TunnelAddedFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetBottomFaces( Proc)
local BottomFaces = {}
if Proc.Topology.sFamily == 'Tunnel' then
return nil
elseif not ( Proc.Topology.sFamily == 'Rabbet'
or Proc.Topology.sFamily == 'VGroove'
or Proc.Topology.sFamily == 'Groove'
or Proc.Topology.sFamily == 'Pocket'
or Proc.Topology.sFamily == 'Bevel'
or Proc.Topology.sFamily == 'DoubleBevel'
or Proc.Topology.sFamily == 'Cut') then
error( 'GetBottomFace : Topology not implemented')
end
if Proc.nFct == 1 then
return { Proc.Faces[1]}
end
-- la faccia di fondo ha sempre Fct - 1 adiacenze
local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
if FacesByAdjacencyNumber then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1]
-- si rimuovono le facce non adatte ad essere lavorate
local nBottomFaces = #BottomFaces
local nCurrentFace = 1
while nCurrentFace <= nBottomFaces do
if not BottomFaces[nCurrentFace].bIsOkForMachining then
table.remove( BottomFaces, nCurrentFace)
nBottomFaces = nBottomFaces - 1
end
nCurrentFace = nCurrentFace + 1
end
-- la BottomFace 1 è sempre quella con minor elevazione
table.sort( BottomFaces, function (a, b) return a.dElevation < b.dElevation end)
end
if #BottomFaces == 0 then
return nil
end
BottomFaces[1].sType = 'Bottom'
-- calcolo MainEdges implementato solo se 4 lati esatti
if #BottomFaces[1].Edges ~= 4 then
return BottomFaces
end
BottomFaces[1].MainEdges = {}
BottomFaces[1].MainEdges.LongEdges = {}
BottomFaces[1].MainEdges.SideEdges = {}
local EdgesSorted = {}
for i = 1, #BottomFaces[1].Edges do
table.insert( EdgesSorted, {})
EdgesSorted[#EdgesSorted].nIndex = i
EdgesSorted[#EdgesSorted].dLength = BottomFaces[1].Edges[i].dLength
EdgesSorted[#EdgesSorted].idAdjacentFace = BottomFaces[1].Edges[i].idAdjacentFace
end
table.sort( EdgesSorted, CompareEdgesBottomFace)
local nFirstLongEdgeIndex
if #EdgesSorted > 0 then
nFirstLongEdgeIndex = EdgesSorted[1].nIndex
end
for i = 1, #BottomFaces[1].Edges do
local nPreviousEdgeIndex = i - 1
if i == 1 then
nPreviousEdgeIndex = #BottomFaces[1].Edges
end
local nNextEdgeIndex = i + 1
if i == #BottomFaces[1].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = BottomFaces[1].Edges[i].idAdjacentFace
CurrentEdge.vtN = BottomFaces[1].Edges[i].vtN
CurrentEdge.dLength = BottomFaces[1].Edges[i].dLength
CurrentEdge.bIsOpen = BottomFaces[1].Edges[i].bIsOpen
CurrentEdge.dElevation = BottomFaces[1].Edges[i].dElevation
CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[i].bIsStartOpen
CurrentEdge.bIsEndOpen = BottomFaces[1].Edges[i].bIsEndOpen
if nFirstLongEdgeIndex then
if i == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.LongEdges[1] = CurrentEdge
BottomFaces[1].MainEdges.LongEdges[1].sType = 'Long'
elseif nNextEdgeIndex == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.SideEdges[1] = CurrentEdge
BottomFaces[1].MainEdges.SideEdges[1].sType = 'Side'
elseif nPreviousEdgeIndex == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.SideEdges[2] = CurrentEdge
BottomFaces[1].MainEdges.SideEdges[2].sType = 'Side'
else
BottomFaces[1].MainEdges.LongEdges[2] = CurrentEdge
BottomFaces[1].MainEdges.LongEdges[2].sType = 'Long'
end
end
end
return BottomFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetLongFaces( Proc, MainFaces)
local LongFaces = {}
if Proc.nFct > 5 then
error( 'GetLongFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
end
local BottomFace
local BottomFaces = MainFaces.BottomFaces or GetBottomFaces( Proc)
if BottomFaces and #BottomFaces > 0 then
BottomFace = BottomFaces[1]
end
local idFirstLongFace = GDB_ID.NULL
local idSecondLongFace = GDB_ID.NULL
if not BottomFace then
local FacesSortedByGreatestArea = {}
for i = 1, Proc.nFct do
FacesSortedByGreatestArea[i] = {}
FacesSortedByGreatestArea[i].id = Proc.Faces[i].id
FacesSortedByGreatestArea[i].dArea = Proc.Faces[i].dArea
end
table.sort( FacesSortedByGreatestArea, function (a, b) return a.dArea > b.dArea end)
idFirstLongFace = FacesSortedByGreatestArea[1].id
local FacesNotAdjacent = GetNotAdjacentFaces( Proc, idFirstLongFace)
idSecondLongFace = FacesNotAdjacent[1].id
elseif BottomFace.MainEdges then
if BottomFace.MainEdges.LongEdges[1].idAdjacentFace > -1 then
idFirstLongFace = BottomFace.MainEdges.LongEdges[1].idAdjacentFace
end
if BottomFace.MainEdges.LongEdges[2].idAdjacentFace > -1 then
idSecondLongFace = BottomFace.MainEdges.LongEdges[2].idAdjacentFace
end
end
if idFirstLongFace > -1 and Proc.Faces[idFirstLongFace + 1].bIsOkForMachining then
table.insert( LongFaces, Proc.Faces[idFirstLongFace + 1])
end
if idSecondLongFace > -1 and Proc.Faces[idSecondLongFace + 1].bIsOkForMachining then
table.insert( LongFaces, Proc.Faces[idSecondLongFace + 1])
end
for i = 1, #LongFaces do
LongFaces[i].sType = 'Long'
-- calcolo MainEdges possibile solo se 4 lati esatti
if #LongFaces[i].Edges ~= 4 then
break
end
LongFaces[i].MainEdges = {}
LongFaces[i].MainEdges.SideEdges = {}
LongFaces[i].MainEdges.OppositeEdges = {}
for j = 1, #LongFaces[i].Edges do
local nPreviousEdgeIndex = j - 1
if j == 1 then
nPreviousEdgeIndex = #LongFaces[1].Edges
end
local nNextEdgeIndex = j + 1
if j == #LongFaces[i].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = LongFaces[i].Edges[j].idAdjacentFace
CurrentEdge.vtN = LongFaces[i].Edges[j].vtN
CurrentEdge.dLength = LongFaces[i].Edges[j].dLength
CurrentEdge.bIsOpen = LongFaces[i].Edges[j].bIsOpen
CurrentEdge.dElevation = LongFaces[i].Edges[j].dElevation
CurrentEdge.bIsStartOpen = LongFaces[i].Edges[j].bIsStartOpen
CurrentEdge.bIsEndOpen = LongFaces[i].Edges[j].bIsEndOpen
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
table.insert( LongFaces[i].MainEdges.SideEdges, CurrentEdge)
LongFaces[i].MainEdges.SideEdges[#LongFaces[i].MainEdges.SideEdges].sType = 'Side'
else
table.insert( LongFaces[i].MainEdges.OppositeEdges, CurrentEdge)
LongFaces[i].MainEdges.OppositeEdges[#LongFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
else
if CurrentEdge.idAdjacentFace == BottomFace.id then
LongFaces[i].MainEdges.BottomEdge = CurrentEdge
LongFaces[i].MainEdges.BottomEdge.sType = 'Bottom'
elseif LongFaces[i].Edges[nNextEdgeIndex].idAdjacentFace == BottomFace.id then
LongFaces[i].MainEdges.SideEdges[1] = CurrentEdge
LongFaces[i].MainEdges.SideEdges[1].sType = 'Side'
elseif LongFaces[i].Edges[nPreviousEdgeIndex].idAdjacentFace == BottomFace.id then
LongFaces[i].MainEdges.SideEdges[2] = CurrentEdge
LongFaces[i].MainEdges.SideEdges[2].sType = 'Side'
else
table.insert( LongFaces[i].MainEdges.OppositeEdges, CurrentEdge)
LongFaces[i].MainEdges.OppositeEdges[#LongFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
end
end
end
return LongFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetSideFaces( Proc, MainFaces)
local SideFaces = {}
if Proc.nFct > 5 then
error( 'GetSideFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
end
local BottomFace
local BottomFaces = MainFaces.BottomFaces or GetBottomFaces( Proc)
if BottomFaces and #BottomFaces > 0 then
BottomFace = BottomFaces[1]
end
local LongFaces = MainFaces.LongFaces or GetLongFaces( Proc, MainFaces)
local idFirstSideFace = GDB_ID.NULL
local idSecondSideFace = GDB_ID.NULL
if LongFaces[1] and LongFaces[1].MainEdges then
if not LongFaces[1].MainEdges.SideEdges[1].bIsOpen then
idFirstSideFace = LongFaces[1].MainEdges.SideEdges[1].idAdjacentFace
end
if not LongFaces[1].MainEdges.SideEdges[2].bIsOpen then
idSecondSideFace = LongFaces[1].MainEdges.SideEdges[2].idAdjacentFace
end
end
if idFirstSideFace > -1 and Proc.Faces[idFirstSideFace + 1].bIsOkForMachining then
table.insert( SideFaces, Proc.Faces[idFirstSideFace + 1])
SideFaces[#SideFaces].sType = 'Side'
end
if idSecondSideFace > -1 and Proc.Faces[idSecondSideFace + 1].bIsOkForMachining then
table.insert( SideFaces, Proc.Faces[idSecondSideFace + 1])
SideFaces[#SideFaces].sType = 'Side'
end
for i = 1, #SideFaces do
SideFaces[i].sType = 'Side'
-- calcolo MainEdges possibile solo se 4 lati esatti
if #SideFaces[i].Edges ~= 4 then
break
end
SideFaces[i].MainEdges = {}
SideFaces[i].MainEdges.LongEdges = {}
SideFaces[i].MainEdges.OppositeEdges = {}
for j = 1, #SideFaces[i].Edges do
local nPreviousEdgeIndex = j - 1
if j == 1 then
nPreviousEdgeIndex = #SideFaces[1].Edges
end
local nNextEdgeIndex = j + 1
if j == #SideFaces[i].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = SideFaces[i].Edges[j].idAdjacentFace
CurrentEdge.vtN = SideFaces[i].Edges[j].vtN
CurrentEdge.dLength = SideFaces[i].Edges[j].dLength
CurrentEdge.bIsOpen = SideFaces[i].Edges[j].bIsOpen
CurrentEdge.dElevation = SideFaces[i].Edges[j].dElevation
CurrentEdge.bIsStartOpen = SideFaces[i].Edges[j].bIsStartOpen
CurrentEdge.bIsEndOpen = SideFaces[i].Edges[j].bIsEndOpen
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
table.insert( SideFaces[i].MainEdges.LongEdges, CurrentEdge)
else
table.insert( SideFaces[i].MainEdges.OppositeEdges, CurrentEdge)
end
else
if CurrentEdge.idAdjacentFace == BottomFace.id then
SideFaces[i].MainEdges.BottomEdge = CurrentEdge
SideFaces[i].MainEdges.BottomEdge.sType = 'Bottom'
elseif SideFaces[i].Edges[nNextEdgeIndex].idAdjacentFace == BottomFace.id then
SideFaces[i].MainEdges.LongEdges[1] = CurrentEdge
SideFaces[i].MainEdges.LongEdges[1].sType = 'Long'
elseif SideFaces[i].Edges[nPreviousEdgeIndex].idAdjacentFace == BottomFace.id then
SideFaces[i].MainEdges.LongEdges[2] = CurrentEdge
SideFaces[i].MainEdges.LongEdges[2].sType = 'Long'
else
table.insert( SideFaces[i].MainEdges.OppositeEdges, CurrentEdge)
SideFaces[i].MainEdges.OppositeEdges[#SideFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
end
end
end
return SideFaces
end
-------------------------------------------------------------------------------------------------------------
-- recupero facce principali della feature, in base alla topologia
-- TODO test iniziale replicato in GetTunnelFaces
function FaceData.GetMainFaces( Proc, Part)
EgtOutLog( '---MainFaces START---')
local MainFaces = {}
-- CASO 1 : Feature tipo LapJoint
if Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or
Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Bevel' or
Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sFamily == 'Cut' then
if ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind' then
MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part)
end
MainFaces.BottomFaces = GetBottomFaces( Proc)
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
-- scrivo informazioni delle facce nel log
if EgtGetDebugLevel() >= 3 then
Logs.WriteMainFacesLog( Proc, MainFaces)
end
else
MainFaces = nil
EgtOutLog( '---MainFaces NOT NEEDED---')
end
EgtOutLog( '---MainFaces END---')
return MainFaces
end
-------------------------------------------------------------------------------------------------------------
return FaceData