557 lines
22 KiB
Lua
557 lines
22 KiB
Lua
-- WallLib.lua by Egaltech s.r.l. 2023/10/16
|
|
-- Libreria globale per Pareti
|
|
-- 2023/06/26 Spostata qui Is3EdgesApprox da FreeContour. Ora cerca autonomamente il gruppo se non viene passato.
|
|
-- 2023/11/14 Aggiunte funzioni GetProcessAffectedFaces, GetProcessDistanceToNearestParts, GetProcessDistanceToRawPart.
|
|
-- 2023/12/11 Aggiunta funzione IsFeatureCuttingEntireSection (allineamento Topology con Beam).
|
|
|
|
-- Tabella per definizione modulo
|
|
local WallLib = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
|
|
EgtOutLog( ' WallLib started', 1)
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function WallLib.GetAddGroup( PartId)
|
|
-- recupero il nome del gruppo di lavoro corrente
|
|
local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL)
|
|
if not sMchGrp then return nil, nil end
|
|
-- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco
|
|
local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp)
|
|
-- restituisco Id e Nome
|
|
return AddGrpId, sMchGrp
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function WallLib.CreateOrEmptyAddGroup( PartId)
|
|
-- recupero i dati del gruppo aggiuntivo
|
|
local AddGrpId, sMchGrp = WallLib.GetAddGroup( PartId)
|
|
if not sMchGrp then return false end
|
|
-- se esiste lo svuoto
|
|
if AddGrpId then
|
|
return EgtEmptyGroup( AddGrpId)
|
|
end
|
|
-- altrimenti lo creo
|
|
AddGrpId = EgtGroup( PartId or GDB_ID.NULL)
|
|
if not AddGrpId then return false end
|
|
-- assegno nome, flag di layer per gruppo di lavoro e colore
|
|
EgtSetName( AddGrpId, sMchGrp)
|
|
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
|
|
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50))
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function WallLib.GetPointDirDepth( nRawId, ptP, vtDir)
|
|
-- recupero il solido del grezzo
|
|
local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid')
|
|
if not nSolId then return end
|
|
-- interseco con la retta
|
|
local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB)
|
|
if not bOk then return end
|
|
if not vPar or #vPar == 0 then return -2 end
|
|
local dLenIn, dLenOut
|
|
for i = 1, #vPar do
|
|
if vPar[i] < 0 then
|
|
if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then
|
|
dLenIn = -1
|
|
end
|
|
if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then
|
|
dLenIn = -2
|
|
end
|
|
else
|
|
if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then
|
|
dLenIn = vPar[i]
|
|
end
|
|
if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then
|
|
dLenOut = vPar[i]
|
|
end
|
|
end
|
|
end
|
|
return dLenIn, dLenOut
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.GetFaceElevation( nSurfId, nFac, nRawId)
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT)
|
|
if not ptC or not vtN then return 0 end
|
|
local frOCS = Frame3d( ptC, vtN) ;
|
|
local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS)
|
|
local dElev = b3Box:getMax():getZ()
|
|
if nRawId then
|
|
local _, dCenElev = WallLib.GetPointDirDepth( nRawId, ptC, vtN)
|
|
if dCenElev and dCenElev > dElev then dElev = dCenElev end
|
|
local dOffsX = min( 20, b3Box:getDimX() / 4)
|
|
local _, dP1Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsX * frOCS:getVersX(), vtN)
|
|
if dP1Elev and dP1Elev > dElev then dElev = dP1Elev end
|
|
local _, dP2Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsX * frOCS:getVersX(), vtN)
|
|
if dP2Elev and dP2Elev > dElev then dElev = dP2Elev end
|
|
local dOffsY = min( 20, b3Box:getDimY() / 4)
|
|
local _, dP3Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsY * frOCS:getVersY(), vtN)
|
|
if dP3Elev and dP3Elev > dElev then dElev = dP3Elev end
|
|
local _, dP4Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsY * frOCS:getVersY(), vtN)
|
|
if dP4Elev and dP4Elev > dElev then dElev = dP4Elev end
|
|
end
|
|
return dElev
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng)
|
|
-- recupero il numero di facce
|
|
local nFacCnt = EgtSurfTmFacetCount( nSurfId)
|
|
if not dCosSideAng then
|
|
dCosSideAng = -0.09
|
|
end
|
|
-- recupero le normali delle facce
|
|
local vvtN = {}
|
|
for i = 1, nFacCnt do
|
|
local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT)
|
|
vvtN[i] = vtN ;
|
|
end
|
|
-- adiacenze e sottosquadra delle facce
|
|
local vAdj = {}
|
|
local vUcut = {}
|
|
local vOrtho = {}
|
|
local vBlind = {}
|
|
for i = 1, nFacCnt do
|
|
-- recupero le adiacenze del loop esterno
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
vAdj[i] = nCount
|
|
-- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità
|
|
local bUcut = false
|
|
local bOrtho = true
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
local vtN = vvtN[i]
|
|
local vtN2 = vvtN[vFacAdj[j]+1]
|
|
local dResV = vtN * vtN2
|
|
if dResV < dCosSideAng - GEO.EPS_SMALL then
|
|
bUcut = true
|
|
end
|
|
if abs( dResV) > 2 * GEO.EPS_SMALL then
|
|
bOrtho = false
|
|
end
|
|
end
|
|
end
|
|
-- verifico se schermata da altra faccia
|
|
local bBlind = false
|
|
for j = 1, nFacCnt do
|
|
if i ~= j then
|
|
if vvtN[i] * vvtN[j] < -0.5 then
|
|
bBlind = true
|
|
end
|
|
end
|
|
end
|
|
-- assegno i risultati
|
|
vUcut[i] = bUcut
|
|
vOrtho[i] = bOrtho
|
|
vBlind[i] = bBlind
|
|
end
|
|
-- se 4 facce tutte con adiacenza 2, allora è un tunnel
|
|
if nFacCnt == 4 then
|
|
if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then
|
|
-- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà
|
|
if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then
|
|
return -1, GEO.INFINITO, true
|
|
else
|
|
return -1, GEO.INFINITO
|
|
end
|
|
end
|
|
end
|
|
-- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura
|
|
if bCompare3Fc and nFacCnt == 3 then
|
|
local nCount2Adc = 0
|
|
local nCount1Adc = 0
|
|
-- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] == 2 then
|
|
nCount2Adc = nCount2Adc + 1
|
|
elseif vAdj[i] == 1 then
|
|
nCount1Adc = nCount1Adc + 1
|
|
end
|
|
end
|
|
-- se il numero di adiacenze corrisponde
|
|
if nCount2Adc == 1 and nCount1Adc == 2 then
|
|
if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then
|
|
return -1, GEO.INFINITO, true
|
|
else
|
|
return -1, GEO.INFINITO
|
|
end
|
|
end
|
|
end
|
|
-- recupero le facce non in sottosquadra e con il maggior numero di adiacenze
|
|
local nFacInd = {}
|
|
local nMaxAdj = -1
|
|
local nSupAdj = -1
|
|
for i = 1, nFacCnt do
|
|
if not vUcut[i] and not vBlind[i] then
|
|
if vAdj[i] >= nMaxAdj and vAdj[i] > 0 then
|
|
table.insert( nFacInd, i - 1)
|
|
nMaxAdj = vAdj[i]
|
|
elseif vAdj[i] > 0 then
|
|
table.insert( nFacInd, i - 1)
|
|
end
|
|
end
|
|
if vAdj[i] > nSupAdj then
|
|
nSupAdj = vAdj[i]
|
|
end
|
|
end
|
|
-- verifico non ci sia una faccia in sottosquadra con adiacenza superiore
|
|
if nSupAdj > nMaxAdj then
|
|
return -2, GEO.INFINITO
|
|
end
|
|
-- premio la faccia con minore elevazione
|
|
local nFacOpt, nFacOpt2
|
|
local nOptAdj, nOptAdj2
|
|
local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO
|
|
for i = 1, #nFacInd do
|
|
local dElev = WallLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId)
|
|
if dElev < dMinElev and ( not nOptAdj or vAdj[nFacInd[i]+1] >= nOptAdj) then
|
|
if dMinElev < dMinElev2 then
|
|
nFacOpt2 = nFacOpt
|
|
nOptAdj2 = nOptAdj
|
|
dMinElev2 = dMinElev
|
|
end
|
|
nFacOpt = nFacInd[i]
|
|
nOptAdj = vAdj[nFacInd[i]+1]
|
|
dMinElev = dElev
|
|
elseif dElev < dMinElev2 and ( not nOptAdj2 or vAdj[nFacInd[i]+1] >= nOptAdj2) then
|
|
nFacOpt2 = nFacInd[i]
|
|
nOptAdj2 = vAdj[nFacInd[i]+1]
|
|
dMinElev2 = dElev
|
|
end
|
|
end
|
|
return nFacOpt, dMinElev, nFacOpt2, dMinElev2
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.GetFaceHvRefDim( nSurfId, nFacet)
|
|
-- recupero centro e normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT)
|
|
if not ptC or not vtN then return end
|
|
-- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale)
|
|
local frHV = Frame3d( ptC, vtN)
|
|
if frHV:getVersY():getZ() < 0 then
|
|
frHV:rotate( ptC, vtN, 180)
|
|
end
|
|
-- determino l'ingombro in questo riferimento
|
|
local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV)
|
|
-- aggiusto l'origine del riferimento per metterlo nel centro del box
|
|
local ptBoxCen = b3HV:getCenter()
|
|
frHV:move( ptBoxCen:getX() * frHV:getVersX() + ptBoxCen:getY() * frHV:getVersY())
|
|
-- restituisco i valori calcolati
|
|
return frHV, b3HV:getDimX(), b3HV:getDimY()
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.GetNearestParalOpposite( vtRef)
|
|
-- devo confrontare la componente orizzontale con quella verticale
|
|
local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY()
|
|
local dVertSq =vtRef:getZ() * vtRef:getZ()
|
|
-- se prevalente la componente orizzontale
|
|
if dHorSq >= dVertSq then
|
|
if abs( vtRef:getX()) > abs( vtRef:getY()) then
|
|
if vtRef:getX() > 0 then
|
|
return MCH_MILL_FU.PARAL_LEFT
|
|
else
|
|
return MCH_MILL_FU.PARAL_RIGHT
|
|
end
|
|
else
|
|
if vtRef:getY() > 0 then
|
|
return MCH_MILL_FU.PARAL_FRONT
|
|
else
|
|
return MCH_MILL_FU.PARAL_BACK
|
|
end
|
|
end
|
|
-- altrimenti prevale la verticale
|
|
else
|
|
if vtRef:getZ() > 0 then
|
|
return MCH_MILL_FU.PARAL_DOWN
|
|
else
|
|
return MCH_MILL_FU.PARAL_TOP
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.GetNearestOrthoOpposite( vtRef, vtNorm)
|
|
-- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa
|
|
local vtMyRef = Vector3d( vtRef)
|
|
if vtNorm then
|
|
vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm
|
|
vtMyRef:normalize()
|
|
end
|
|
-- devo confrontare la componente orizzontale con quella verticale
|
|
local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY()
|
|
local dVertSq = vtMyRef:getZ() * vtMyRef:getZ()
|
|
-- se prevalente la componente orizzontale
|
|
if dHorSq >= dVertSq then
|
|
if abs( vtMyRef:getX()) >= abs( vtMyRef:getY()) then
|
|
if vtMyRef:getX() > 0 then
|
|
return MCH_MILL_FU.ORTHO_LEFT
|
|
else
|
|
return MCH_MILL_FU.ORTHO_RIGHT
|
|
end
|
|
else
|
|
if vtMyRef:getY() > 0 then
|
|
return MCH_MILL_FU.ORTHO_FRONT
|
|
else
|
|
return MCH_MILL_FU.ORTHO_BACK
|
|
end
|
|
end
|
|
-- altrimenti prevale la verticale
|
|
else
|
|
if vtMyRef:getZ() > 0 then
|
|
return MCH_MILL_FU.ORTHO_DOWN
|
|
else
|
|
return MCH_MILL_FU.ORTHO_TOP
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.TestElleShape3( nIdGeom, nNumFacet)
|
|
-- valida solo nel caso di tre facce
|
|
if nNumFacet ~= 3 then return false end
|
|
-- determino se L con una faccia terminale o U con tre facce
|
|
local bIsL = true
|
|
for i = 1, 3 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
if nCount == 1 then
|
|
bIsL = false
|
|
break
|
|
end
|
|
end
|
|
return bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WallLib.TestElleShape4( nIdGeom, nNumFacet)
|
|
-- valida solo nel caso di quattro facce
|
|
if nNumFacet ~= 4 then return false end
|
|
-- determino se L con due facce terminali o O
|
|
local nFac3Adj = 0
|
|
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
|
|
local dMaxArea2 = 0
|
|
for i = 1, 4 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT)
|
|
local dArea = dH * dV
|
|
if nCount == 2 then
|
|
dMaxArea2 = max( dMaxArea2, dArea)
|
|
elseif nCount == 3 then
|
|
dMinArea3 = min( dMinArea3, dArea)
|
|
nFac3Adj = nFac3Adj + 1
|
|
end
|
|
end
|
|
if nFac3Adj ~= 2 then return false end
|
|
-- verifico se L profonda oppure lunga
|
|
if dMinArea3 < dMaxArea2 then
|
|
return 1
|
|
else
|
|
return 2
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
|
function WallLib.Is3EdgesApprox( Proc, nFacet, nAddGrpId)
|
|
nAddGrpId = nAddGrpId or WallLib.GetAddGroup( Proc.PartId)
|
|
-- recupero il contorno della faccia
|
|
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
|
|
if not nContourId then return false end
|
|
EgtMergeCurvesInCurveCompo( nContourId)
|
|
-- recupero il numero di lati del contorno
|
|
local _, nEntityCount = EgtCurveDomain( nContourId)
|
|
if not nEntityCount then return false end
|
|
-- se sono già tre, ho finito
|
|
if nEntityCount == 3 then return true end
|
|
-- rimuovo i lati molto corti dal conteggio totale
|
|
local nEdges = nEntityCount
|
|
for i = 1, nEntityCount do
|
|
local dLength = EgtCurveCompoLength( nContourId, i - 1)
|
|
if dLength < 15 then nEdges = nEdges - 1 end
|
|
end
|
|
-- verifico il numero significativo di lati
|
|
local bResult = ( nEdges == 3)
|
|
-- cancello tutti i contorni appena creati
|
|
EgtErase( EgtTableFill( nContourId, nContourCnt))
|
|
if bResult then
|
|
EgtOutLog( 'FreeContour : Face with ' .. tostring( nEntityCount) .. ' edges skipped (approx 3 edges)')
|
|
end
|
|
return bResult
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce le facce della parte interessate dalla feature Proc
|
|
function WallLib.GetProcessAffectedFaces( Proc)
|
|
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.PartId or GDB_ID.NULL, 'Box')
|
|
local b3Part = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
|
|
local vtFacesAffected = { Top = false, Bottom = false, Front = false, Back = false, Left = false, Right = false}
|
|
if Proc.Box and not Proc.Box:isEmpty() then
|
|
if Proc.Box:getMax():getZ() > b3Part:getMax():getZ() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Top = true
|
|
end
|
|
if Proc.Box:getMin():getZ() < b3Part:getMin():getZ() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Bottom = true
|
|
end
|
|
if Proc.Box:getMin():getY() < b3Part:getMin():getY() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Front = true
|
|
end
|
|
if Proc.Box:getMax():getY() > b3Part:getMax():getY() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Back = true
|
|
end
|
|
if Proc.Box:getMin():getX() < b3Part:getMin():getX() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Left = true
|
|
end
|
|
if Proc.Box:getMax():getX() > b3Part:getMax():getX() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.Right = true
|
|
end
|
|
end
|
|
|
|
return vtFacesAffected
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce le distanze XY tra la feature Proc e le altre parti più vicine, secondo le direzioni Y-/Y+/X-/X+
|
|
function WallLib.GetProcessDistanceToNearestParts( Proc)
|
|
local b3Proc = Proc.Box
|
|
local ptMinProc = b3Proc:getMin()
|
|
local ptMaxProc = b3Proc:getMax()
|
|
local vtDistances = { Front = 0, Back = 0, Left = 0, Right = 0}
|
|
if Proc.AffectedFaces.Front then
|
|
vtDistances.Front = GEO.INFINITO
|
|
end
|
|
if Proc.AffectedFaces.Back then
|
|
vtDistances.Back = GEO.INFINITO
|
|
end
|
|
if Proc.AffectedFaces.Left then
|
|
vtDistances.Left = GEO.INFINITO
|
|
end
|
|
if Proc.AffectedFaces.Right then
|
|
vtDistances.Right = GEO.INFINITO
|
|
end
|
|
local nRawId = EgtGetFirstRawPart()
|
|
local nPartId = EgtGetFirstPartInRawPart( nRawId)
|
|
while nPartId do
|
|
if Proc.PartId ~= nPartId then
|
|
local nBoxSolidId = EgtGetFirstNameInGroup( nPartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( nBoxSolidId or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
b3Solid:expand( - 10 * GEO.EPS_SMALL)
|
|
local ptMinPart = b3Solid:getMin()
|
|
local ptMaxPart = b3Solid:getMax()
|
|
if Proc.AffectedFaces.Front then
|
|
if OverlapsXY( b3Proc, b3Solid) then
|
|
vtDistances.Front = 0
|
|
elseif OverlapsX( b3Proc, b3Solid) then
|
|
if ptMaxPart:getY() < ptMinProc:getY() + 100 * GEO.EPS_SMALL then
|
|
vtDistances.Front = min( vtDistances.Front, max( 0, ptMinProc:getY() - ptMaxPart:getY()))
|
|
end
|
|
end
|
|
end
|
|
if Proc.AffectedFaces.Back then
|
|
if OverlapsXY( b3Proc, b3Solid) then
|
|
vtDistances.Back = 0
|
|
elseif OverlapsX( b3Proc, b3Solid) then
|
|
if ptMaxProc:getY() < ptMinPart:getY() + 100 * GEO.EPS_SMALL then
|
|
vtDistances.Back = min( vtDistances.Back, max( 0, ptMinPart:getY() - ptMaxProc:getY()))
|
|
end
|
|
end
|
|
end
|
|
if Proc.AffectedFaces.Left then
|
|
if OverlapsXY( b3Proc, b3Solid) then
|
|
vtDistances.Left = 0
|
|
elseif OverlapsY( b3Proc, b3Solid) then
|
|
if ptMaxPart:getX() < ptMinProc:getX() + 100 * GEO.EPS_SMALL then
|
|
vtDistances.Left = min( vtDistances.Left, max( 0, ptMinProc:getX() - ptMaxPart:getX()))
|
|
end
|
|
end
|
|
end
|
|
if Proc.AffectedFaces.Right then
|
|
if OverlapsXY( b3Proc, b3Solid) then
|
|
vtDistances.Right = 0
|
|
elseif OverlapsY( b3Proc, b3Solid) then
|
|
if ptMaxProc:getX() < ptMinPart:getX() + 100 * GEO.EPS_SMALL then
|
|
vtDistances.Right = min( vtDistances.Right, max( 0, ptMinPart:getX() - ptMaxProc:getX()))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
nPartId = EgtGetNextPartInRawPart( nPartId)
|
|
end
|
|
|
|
return vtDistances
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce le distanze XY tra la feature Proc e il termine del grezzo, secondo le direzioni Y-/Y+/X-/X+
|
|
function WallLib.GetProcessDistanceToRawPart( Proc, b3Raw)
|
|
local b3Proc = Proc.Box
|
|
local ptMinProc = b3Proc:getMin()
|
|
local ptMaxProc = b3Proc:getMax()
|
|
local ptMinRaw = b3Raw:getMin()
|
|
local ptMaxRaw = b3Raw:getMax()
|
|
local vtDistances = { Front = GEO.INFINITO, Back = GEO.INFINITO, Left = GEO.INFINITO, Right = GEO.INFINITO}
|
|
if EnclosesXY( b3Raw, b3Proc) then
|
|
vtDistances.Front = max( 0, ptMinProc:getY() - ptMinRaw:getY())
|
|
vtDistances.Back = max( 0, ptMaxRaw:getY() - ptMaxProc:getY())
|
|
vtDistances.Left = max( 0, ptMinProc:getX() - ptMinRaw:getX())
|
|
vtDistances.Right = max( 0, ptMaxRaw:getX() - ptMaxProc:getX())
|
|
end
|
|
|
|
return vtDistances
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function WallLib.GetNailLockOutAreas( vProc)
|
|
local vNLO = {}
|
|
for i = 1, #vProc do
|
|
if vProc[i].LockOut == 1 then
|
|
local AuxId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + vProc[i].Id end
|
|
if AuxId then
|
|
local nAddGrpId = WallLib.GetAddGroup( vProc[i].PartId)
|
|
local nSfrId = EgtSurfFlatRegion( nAddGrpId, {AuxId})
|
|
if nSfrId then
|
|
table.insert( vNLO, nSfrId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return vNLO
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della parete, rappresentata dalle sue dimensioni W, H e L
|
|
function WallLib.IsFeatureCuttingEntireSection( b3Proc, dRawW, dRawH, dRawL)
|
|
return ( ( ( abs( b3Proc:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or b3Proc:getDimY() > dRawW) or ( abs( b3Proc:getDimX() - dRawL) < 10 * GEO.EPS_SMALL or b3Proc:getDimX() > dRawL)) and (abs(b3Proc:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or b3Proc:getDimZ() > dRawH))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return WallLib
|