3138c6ffbc
- modifiche a GetNearestParalOpposite e GetNearestOrthoOpposite.
713 lines
27 KiB
Lua
713 lines
27 KiB
Lua
-- BeamLib.lua by Egaltech s.r.l. 2022/01/11
|
|
-- Libreria globale per Travi
|
|
-- 2020/07/28 Corretto calcolo attacchi e uscite di lame per non uscire dalla faccia sotto.
|
|
-- 2020/08/18 Aggiunto a GetNearestParalOpposite e GetNearestOrthoOpposite parametro opzionale vtNorm.
|
|
-- 2020/11/03 Aggiunta funzione IsEndOrEnd2Phase.
|
|
-- 2020/11/18 Correzioni a GetParallelOpposite e a GetFaceElevation.
|
|
-- 2021/06/27 Aggiunta funzione GetOtherFaceElevation.
|
|
-- 2021/07/01 In GetNearestOrthoOpposite premio direzioni destra/sinistra.
|
|
-- 2021/07/15 Aggiunta GetFaceElevationFromPointDir.
|
|
-- 2021/09/12 Aggiustamenti in GetNearestParalOpposite e GetNearestOrthoOpposite.
|
|
-- 2022/01/11 In GetNearest*Opposite ridotto vantaggio XY rispetto a Z da 1 -> 0.9 a 1 -> 0.99.
|
|
|
|
-- Tabella per definizione modulo
|
|
local BeamLib = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
|
|
EgtOutLog( ' BeamLib started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.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 BeamLib.CreateOrEmptyAddGroup( PartId)
|
|
-- recupero i dati del gruppo aggiuntivo
|
|
local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId)
|
|
if not sMchGrp then return false end
|
|
-- se esiste, aggiorno riferimento al gruppo di lavoro e lo svuoto
|
|
if AddGrpId then
|
|
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
|
|
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 BeamLib.AddPartStartFace( PartId, b3Solid)
|
|
-- recupero gruppo per geometria aggiuntiva
|
|
local AddGrpId = BeamLib.GetAddGroup( PartId)
|
|
if not AddGrpId then
|
|
local sErr = 'Error on process StartFace impossible to find AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo nuovo taglio iniziale
|
|
local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB)
|
|
if not nStmId then
|
|
local sErr = 'Error on process StartFace impossible to create Face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- applico gli opportuni attributi di feature
|
|
EgtSetName( nStmId, 'StartCut')
|
|
EgtSetInfo( nStmId, 'GRP', 1)
|
|
EgtSetInfo( nStmId, 'PRC', 340)
|
|
-- verifico se sostituisce un taglio di testa già presente
|
|
local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL)
|
|
while nProcId do
|
|
local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0
|
|
local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0
|
|
if ( nGrp == 1 or nGrp == 2) and nProc == 10 then
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT)
|
|
if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then
|
|
EgtSetInfo( nStmId, 'ORI', nProcId)
|
|
end
|
|
end
|
|
nProcId = EgtGetNext( nProcId)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.AddPartEndFace( PartId, b3Solid)
|
|
-- recupero gruppo per geometria aggiuntiva
|
|
local AddGrpId = BeamLib.GetAddGroup( PartId)
|
|
if not AddGrpId then
|
|
local sErr = 'Error on process EndFace impossible to find AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo nuovo taglio finale
|
|
local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB)
|
|
if not nStmId then
|
|
local sErr = 'Error on process EndFace impossible to create Face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- applico gli opportuni attributi di feature
|
|
EgtSetName( nStmId, 'EndCut')
|
|
EgtSetInfo( nStmId, 'GRP', 2)
|
|
EgtSetInfo( nStmId, 'PRC', 350)
|
|
-- verifico se sostituisce un taglio di coda già presente
|
|
local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL)
|
|
while nProcId do
|
|
local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0
|
|
local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0
|
|
if ( nGrp == 1 or nGrp == 2) and nProc == 10 then
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT)
|
|
if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then
|
|
EgtSetInfo( nStmId, 'ORI', nProcId)
|
|
end
|
|
end
|
|
nProcId = EgtGetNext( nProcId)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriXR, PosXR, dDeltaSucc)
|
|
EgtAddPhase()
|
|
local nRawId = nFirstRawId
|
|
local dRawMove = 0
|
|
while nRawId do
|
|
EgtKeepRawPart( nRawId)
|
|
EgtMoveToCornerRawPart( nRawId, OriXR, PosXR)
|
|
EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0))
|
|
if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end
|
|
dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX()
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.PutStartOnTop( nCrvId)
|
|
-- verifico che la curva sia chiusa
|
|
if not EgtCurveIsClosed( nCrvId) then return false end
|
|
-- cerco l'estremo più alto e lo imposto come inizio
|
|
local dUmax = 0
|
|
local dZmax = - GEO.INFINITO
|
|
local dUi, dUf = EgtCurveDomain( nCrvId)
|
|
for dU = dUi, dUf, 0.5 do
|
|
local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT)
|
|
if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then
|
|
dZmax = ptP:getZ()
|
|
dUmax = dU
|
|
end
|
|
end
|
|
if abs( dUmax - dUi) > GEO.EPS_ZERO then
|
|
EgtChangeClosedCurveStart( nCrvId, dUmax)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.PutStartOnLonger( nCrvId)
|
|
-- verifico che la curva sia chiusa
|
|
if not EgtCurveIsClosed( nCrvId) then return false end
|
|
-- cerco l'entità più lunga e la imposto come inizio
|
|
local dUmax = 0
|
|
local dLmax = - GEO.INFINITO
|
|
local dUi, dUf = EgtCurveDomain( nCrvId)
|
|
for dU = dUi, dUf - 1 do
|
|
local ptP1 = EgtUP( nCrvId, dU, GDB_ID.ROOT)
|
|
local ptP2 = EgtUP( nCrvId, dU + 0.5, GDB_ID.ROOT)
|
|
local ptP3 = EgtUP( nCrvId, dU + 1.0, GDB_ID.ROOT)
|
|
local dL = dist( ptP1, ptP2) + dist( ptP2, ptP3)
|
|
if dL > dLmax + GEO.EPS_SMALL then
|
|
dLmax = dL
|
|
dUmax = dU
|
|
end
|
|
end
|
|
if abs( dUmax - dUi) > GEO.EPS_ZERO then
|
|
EgtChangeClosedCurveStart( nCrvId, dUmax)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, bDown)
|
|
-- verifico che la curva sia chiusa
|
|
if not EgtCurveIsClosed( nCrvId) then return false end
|
|
-- recupero il versore normale al piano di lavoro o estrusione
|
|
local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT)
|
|
-- coefficienti per riportare la distanza nel piano di lavoro
|
|
local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX()))
|
|
local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY()))
|
|
local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ()))
|
|
-- cerco l'estremo più vicino al box e lo imposto come inizio (se da sotto escludo Zmax e viceversa)
|
|
local dUopt = 0
|
|
local dDopt = GEO.INFINITO
|
|
local dUi, dUf = EgtCurveDomain( nCrvId)
|
|
for dU = dUi, dUf, 0.5 do
|
|
local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT)
|
|
if ptP then
|
|
local vtMin = ptP - b3Raw:getMin()
|
|
local vtMax = ptP - b3Raw:getMax()
|
|
local dD = abs( vtMin:getX()) * dCoeffX
|
|
dD = min( abs( vtMax:getX()) * dCoeffX, dD)
|
|
dD = min( abs( vtMin:getY()) * dCoeffY, dD)
|
|
dD = min( abs( vtMax:getY()) * dCoeffY, dD)
|
|
if bDown then
|
|
dD = min( abs( vtMin:getZ()) * dCoeffZ, dD)
|
|
else
|
|
dD = min( abs( vtMax:getZ()) * dCoeffZ, dD)
|
|
end
|
|
if dD < dDopt + GEO.EPS_SMALL then
|
|
dDopt = dD
|
|
dUopt = dU
|
|
end
|
|
end
|
|
end
|
|
if abs( dUopt - dUi) > GEO.EPS_ZERO then
|
|
EgtChangeClosedCurveStart( nCrvId, dUopt)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetPointDirDepth( nPartId, ptP, vtDir)
|
|
-- recupero il solido del grezzo
|
|
local nSolId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, 'Box')
|
|
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 BeamLib.GetNearestParalOpposite( 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
|
|
-- se prevalente una componente orizzontale (con piccolissimo vantaggio)
|
|
if abs( vtMyRef:getX()) > 0.99 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.99 * abs( vtMyRef:getZ()) then
|
|
if abs( vtMyRef:getX()) > abs( vtMyRef:getY()) - GEO.EPS_SMALL then
|
|
if vtMyRef:getX() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.PARAL_LEFT
|
|
else
|
|
return MCH_MILL_FU.PARAL_RIGHT
|
|
end
|
|
else
|
|
if vtMyRef:getY() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.PARAL_FRONT
|
|
else
|
|
return MCH_MILL_FU.PARAL_BACK
|
|
end
|
|
end
|
|
-- altrimenti prevale la verticale
|
|
else
|
|
if vtMyRef:getZ() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.PARAL_DOWN
|
|
else
|
|
return MCH_MILL_FU.PARAL_TOP
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.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
|
|
-- se prevalente una componente orizzontale (con piccolissimo vantaggio)
|
|
if abs( vtMyRef:getX()) > 0.99 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.99 * abs( vtMyRef:getZ()) then
|
|
-- se prevale la componente destra/sinistra (con piccolo vantaggio)
|
|
if abs( vtMyRef:getX()) > 0.9 * abs( vtMyRef:getY()) then
|
|
if vtMyRef:getX() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.ORTHO_LEFT
|
|
else
|
|
return MCH_MILL_FU.ORTHO_RIGHT
|
|
end
|
|
else
|
|
if vtMyRef:getY() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.ORTHO_FRONT
|
|
else
|
|
return MCH_MILL_FU.ORTHO_BACK
|
|
end
|
|
end
|
|
-- altrimenti prevale la verticale
|
|
else
|
|
if vtMyRef:getZ() > -GEO.EPS_SMALL then
|
|
return MCH_MILL_FU.ORTHO_DOWN
|
|
else
|
|
return MCH_MILL_FU.ORTHO_TOP
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetOrtupOpposite( nOrthoOpposite)
|
|
if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then
|
|
return MCH_MILL_FU.ORTUP_LEFT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then
|
|
return MCH_MILL_FU.ORTUP_RIGHT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then
|
|
return MCH_MILL_FU.ORTUP_FRONT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then
|
|
return MCH_MILL_FU.ORTUP_BACK
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then
|
|
return MCH_MILL_FU.ORTUP_DOWN
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then
|
|
return MCH_MILL_FU.ORTUP_TOP
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetParallelOpposite( nOrthoOpposite)
|
|
if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then
|
|
return MCH_MILL_FU.PARAL_LEFT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then
|
|
return MCH_MILL_FU.PARAL_RIGHT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then
|
|
return MCH_MILL_FU.PARAL_FRONT
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then
|
|
return MCH_MILL_FU.PARAL_BACK
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then
|
|
return MCH_MILL_FU.PARAL_DOWN
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then
|
|
return MCH_MILL_FU.PARAL_TOP
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetVersRef( nOrthoOpposite)
|
|
if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then
|
|
return X_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then
|
|
return -X_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then
|
|
return Y_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then
|
|
return -Y_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then
|
|
return Z_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then
|
|
return -Z_AX()
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV)
|
|
local vtNx = V_NULL()
|
|
if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then
|
|
vtNx = -X_AX()
|
|
elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then
|
|
vtNx = X_AX()
|
|
end
|
|
local vtNy = V_NULL()
|
|
if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then
|
|
vtNy = -Y_AX()
|
|
elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then
|
|
vtNy = Y_AX()
|
|
end
|
|
local vtNz = V_NULL()
|
|
if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then
|
|
vtNz = -Z_AX()
|
|
elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then
|
|
vtNz = Z_AX()
|
|
end
|
|
local dNxDotV = vtNx * vtV
|
|
local dNyDotV = vtNy * vtV
|
|
local dNzDotV = vtNz * vtV
|
|
if dNxDotV > dNyDotV and dNxDotV > dNzDotV then
|
|
return vtNx
|
|
elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then
|
|
return vtNy
|
|
else
|
|
return vtNz
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetFaceElevation( nSurfId, nFac, nPartId)
|
|
-- centro e normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT)
|
|
if not ptC or not vtN then return 0 end
|
|
-- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie
|
|
local frOCS = Frame3d( ptC, vtN)
|
|
local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS)
|
|
local dElev = b3Box:getMax():getZ()
|
|
-- se definito identificativo di pezzo
|
|
if nPartId then
|
|
-- se superficie con più facce
|
|
if EgtSurfTmFacetCount( nSurfId) > 1 then
|
|
-- determino elevazione del centro faccia rispetto al box del pezzo
|
|
local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN)
|
|
if dCenElev and dCenElev > dElev then
|
|
dElev = dCenElev
|
|
end
|
|
-- altrimenti superficie ad una sola faccia
|
|
else
|
|
-- determino elevazione box del pezzo rispetto alla faccia
|
|
local b3Solid = EgtGetBBoxRef( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD, frOCS)
|
|
local dSolidElev = b3Solid:getMax():getZ()
|
|
if b3Solid and dSolidElev > dElev then
|
|
dElev = dSolidElev
|
|
end
|
|
end
|
|
end
|
|
return dElev
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetOtherFaceElevation( nSurfId, nOtherSurfId, nOtherFac, nPartId)
|
|
-- centro e normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nOtherSurfId, nOtherFac, GDB_ID.ROOT)
|
|
if not ptC or not vtN then return 0 end
|
|
-- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie
|
|
local frOCS = Frame3d( ptC, vtN)
|
|
local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS)
|
|
local dElev = b3Box:getMax():getZ()
|
|
-- se definito identificativo di pezzo
|
|
if nPartId then
|
|
-- determino elevazione del centro faccia rispetto al box del pezzo
|
|
local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN)
|
|
if dCenElev and dCenElev > dElev then
|
|
dElev = dCenElev
|
|
end
|
|
end
|
|
return dElev
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetFaceElevationFromPointDir( nSurfId, nPartId, ptC, vtN, nIdGeomMaster)
|
|
if not ptC or not vtN then return 0 end
|
|
-- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie
|
|
local frOCS = Frame3d( ptC, vtN)
|
|
local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS)
|
|
local dElev = b3Box:getMax():getZ()
|
|
-- se definito identificativo di pezzo
|
|
if nPartId then
|
|
-- se superficie con più facce
|
|
if EgtSurfTmFacetCount( nSurfId) > 1 then
|
|
_, dElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN)
|
|
else
|
|
local b3Solid = EgtGetBBoxRef( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD, frOCS)
|
|
if b3Solid and b3Solid:getMax():getZ() > dElev then
|
|
dElev = b3Solid:getMax():getZ()
|
|
end
|
|
end
|
|
end
|
|
return dElev
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.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 = EgtSurfTmFacetNormVersor( nSurfId, i - 1, GDB_ID.ROOT)
|
|
vvtN[i] = vtN ;
|
|
end
|
|
-- adiacenze e sottosquadra delle facce
|
|
local vAdj = {}
|
|
local vUcut = {}
|
|
local vOrtho = {}
|
|
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
|
|
vUcut[i] = bUcut
|
|
vOrtho[i] = bOrtho
|
|
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] then
|
|
if vAdj[i] > nMaxAdj then
|
|
nFacInd = {}
|
|
nFacInd[1] = i - 1
|
|
nMaxAdj = vAdj[i]
|
|
elseif vAdj[i] == nMaxAdj and nMaxAdj > 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 dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO
|
|
local dtElev = {}
|
|
for i = 1, #nFacInd do
|
|
local dElev = BeamLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId)
|
|
table.insert( dtElev, dElev)
|
|
if dElev < dMinElev then
|
|
if dMinElev < dMinElev2 then
|
|
nFacOpt2 = nFacOpt
|
|
dMinElev2 = dMinElev
|
|
end
|
|
nFacOpt = nFacInd[i]
|
|
dMinElev = dElev
|
|
elseif dElev < dMinElev2 then
|
|
nFacOpt2 = nFacInd[i]
|
|
dMinElev2 = dElev
|
|
end
|
|
end
|
|
-- faccio una ulteriore verifica
|
|
-- se le elevazioni di max 3 facce sono in un range minimo o al di sotto dell'elevazione ritenuta fattibile,
|
|
-- premio quella che non è sottosquadra e che ha la X minore
|
|
local bDiffSmall = true
|
|
for i = 1, #dtElev do
|
|
if dtElev[i] > dMinElev + 5 or dtElev[i] > 80 then
|
|
bDiffSmall = false
|
|
end
|
|
end
|
|
-- se tutte sono nel range minimo posso prendere la faccia che ha la componente Z magiore, e se sono uguali, prendo quella con componente X minore
|
|
local dMaxZ, dMaxZ2 = -1.1, -1.1
|
|
if bDiffSmall and #nFacInd <= 3 then
|
|
for i = 1, #nFacInd do
|
|
if vvtN[nFacInd[i]+1]:getZ() > dMaxZ then
|
|
if dMaxZ > dMaxZ2 then
|
|
nFacOpt2 = nFacOpt
|
|
dMinElev2 = dMinElev
|
|
dMaxZ2 = dMaxZ
|
|
end
|
|
nFacOpt = nFacInd[i]
|
|
dMinElev = dtElev[i]
|
|
dMaxZ = vvtN[nFacInd[i]+1]:getZ()
|
|
elseif vvtN[nFacInd[i]+1]:getZ() > dMaxZ2 then
|
|
nFacOpt2 = nFacInd[i]
|
|
dMinElev2 = dtElev[i]
|
|
dMaxZ2 = vvtN[nFacInd[i]+1]:getZ()
|
|
end
|
|
end
|
|
-- se hanno uguale Z premio quella con la componente X minore
|
|
if abs( dMaxZ - dMaxZ2) < 10*GEO.EPS_SMALL then
|
|
if abs(vvtN[nFacOpt+1]:getX()) > abs(vvtN[nFacOpt2+1]:getX()) then
|
|
nFacOpt, nFacOpt2 = nFacOpt2, nFacOpt
|
|
dMinElev, dMinElev2 = dMinElev2, dMinElev
|
|
end
|
|
end
|
|
end
|
|
|
|
return nFacOpt, dMinElev, nFacOpt2, dMinElev2
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.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)
|
|
-- restituisco i valori calcolati
|
|
return frHV, b3HV:getDimX(), b3HV:getDimY()
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.UpdateHCING( nRawId, dHCI, dDist)
|
|
local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') or 0
|
|
if dDist and dDist > dOldHCI + 0.1 then
|
|
return
|
|
end
|
|
if dHCI > dOldHCI then
|
|
EgtSetInfo( nRawId, 'HCING', dHCI)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.UpdateTCING( nRawId, dTCI)
|
|
local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') or 0
|
|
if dTCI > dOldTCI then
|
|
EgtSetInfo( nRawId, 'TCING', dTCI)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetNzLimDownUp( b3Raw, bFromTop)
|
|
if not BD.C_SIMM then
|
|
if bFromTop then
|
|
return EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM, -0.609, -0.383)
|
|
else
|
|
return EgtIf( b3Raw:getDimZ() < 200, -0.5, -0.258)
|
|
end
|
|
else
|
|
return -0.484
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.IsSplittedPartPhase( nPhase)
|
|
local sVal = BeamLib.GetPhaseType( nPhase)
|
|
return ( sVal == 'END' or sVal == 'MID2' or sVal == 'END2')
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.IsPartFinalPhase( nPhase)
|
|
local sVal = BeamLib.GetPhaseType( nPhase)
|
|
return ( sVal == 'END' or sVal == 'END2')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetPhaseType( nPhase)
|
|
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '')
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return BeamLib
|