1405 lines
57 KiB
Lua
1405 lines
57 KiB
Lua
-- BeamLib.lua by Egaltech s.r.l. 2023/12/15
|
|
-- 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.
|
|
-- 2022/04/05 Modifiche a GetNzLimDownUp per FAST.
|
|
-- 2022/05/03 Ulteriore limitazione a GetNzLimDownUp per FAST.
|
|
-- 2022/05/18 Correzioni e migliorie a PutStartNearestToEdge.
|
|
-- 2022/06/25 Rese globali le funzioni GetChainSawBlockedAxis e GetChainSawInitAngs prima in ProcessLapJpoint.
|
|
-- 2022/07/12 A GetFaceHvRefDim aggiunta possibilità di confronto e limitazione dimensioni con grezzo/pezzo (conta solo la sezione).
|
|
-- 2022/07/26 Aggiunta la funzione FindFaceBestOrientedAsAxis, precedentemente in ProcessLapJoint
|
|
-- 2022/07/26 Alla funzione FindFaceBestOrientedAsAxis aggiunta la possibilità di escludere una faccia dalla ricerca
|
|
-- 2022/09/01 Aggiunte le funzioni GetTunnelDimension, CalcCollisionSafety, SetOpenSide, precedentemente in ProcessLapJoint.
|
|
-- 2023/01/10 In GetFaceWithMostAdj aggiunta verifica che la feature abbia almeno una faccia aperta.
|
|
-- 2023/01/20 Modificata PutStartNearestToEdge per gestire lato preferito come Y+, Y-, z*, Z-. Aggiunta funzione GetDistanceToNextPart.
|
|
-- 2023/01/31 Aggiunta funzione ConvertToClosedCurve, precedentemente parte di ProcessMortise.Make
|
|
-- 2023/02/22 Modifiche a SetOpenSide, aggiunte ChangeOrOpenStart e CurveWithOnlyStraightLines.
|
|
-- 2023/06/12 In ChangeOrOpenStart corretta ricerca segmento più lungo.
|
|
-- 2023/09/13 Aggiunte funzioni Is3EdgesApprox e GetProcessAffectedFaces.
|
|
-- 2023/09/25 In GetFaceWithMostAdj aggiunta verifica sottosquadro anche per facce non adiacenti.
|
|
-- 2023/09/26 In GetFaceWithMostAdj gestito primo parametro anche come Proc; gestito caso strip con facce tutte in sottosquadro.
|
|
-- 2023/09/26 Spostata qui funzione IsFeatureCuttingEntireSection da BeamExec.
|
|
-- 2023/11/30 Calcolo elevazione velocizzato e centralizzato tramite la funzione GetFaceElevation. Se l'elevazione è già calcolata la recupera da Proc, altrimenti la calcola al momento.
|
|
-- 2023/12/15 Correzione a GetFaceWithMostAdj per calcoli con facce che fanno ombra.
|
|
-- 2024/01/08 Correzione a Is3EdgesApprox per casi in cui nAddGroup non esista ancora.
|
|
-- 2024/01/18 Aggiunta funzione GetBlockedAxis che gestisce gli assi bloccati per tutti i tipi di utensile.
|
|
|
|
-- 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- nNearSide : 2=Y+, -2=Y-, 3=Z+, -3=Z-
|
|
function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, dMaxDist, nNearSide)
|
|
-- 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 dCoeffY = 0
|
|
if abs( vtN:getY()) < 0.999 then dCoeffY= 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) end
|
|
local dCoeffZ = 0
|
|
if abs( vtN:getZ()) < 0.999 then dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) end
|
|
-- 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 dSopt = GEO.INFINITO
|
|
local dUi, dUf = EgtCurveDomain( nCrvId)
|
|
for dU = dUi, dUf, 0.5 do
|
|
local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT)
|
|
local vtDp = EgtUV( nCrvId, dU, -1, GDB_ID.ROOT)
|
|
local vtDs = EgtUV( nCrvId, dU, 1, GDB_ID.ROOT)
|
|
local bTg = ( vtDp and vtDs and vtDp * vtDs > 0.96)
|
|
if ptP and bTg then
|
|
local vtMin = ptP - b3Raw:getMin()
|
|
local vtMax = ptP - b3Raw:getMax()
|
|
local dD = abs( vtMin:getY()) * dCoeffY
|
|
dD = min( abs( vtMax:getY()) * dCoeffY, dD)
|
|
dD = min( abs( vtMin:getZ()) * dCoeffZ, dD)
|
|
dD = min( abs( vtMax:getZ()) * dCoeffZ, dD)
|
|
local dS
|
|
if nNearSide == -2 then
|
|
dS = abs( vtMin:getY() * dCoeffY)
|
|
elseif nNearSide == 2 then
|
|
dS = abs( vtMax:getY() * dCoeffY)
|
|
elseif nNearSide == -3 then
|
|
dS = abs( vtMin:getZ() * dCoeffZ)
|
|
else --nNearSide == 3
|
|
dS = abs( vtMax:getZ() * dCoeffZ)
|
|
end
|
|
if dD < dMaxDist and dS < dSopt + GEO.EPS_SMALL then
|
|
dUopt = dU
|
|
dDopt = dD
|
|
dSopt = dS
|
|
end
|
|
end
|
|
end
|
|
if abs( dUopt - dUi) > GEO.EPS_ZERO and abs( dUopt - dUf) > 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.95 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.95 * abs( vtMyRef:getZ()) then
|
|
if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getY()) 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.91 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.91 * abs( vtMyRef:getZ()) then
|
|
-- se prevale la componente destra/sinistra
|
|
if abs( vtMyRef:getX()) > 0.95 * 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 or nOrthoOpposite == MCH_MILL_FU.ORTUP_LEFT or nOrthoOpposite == MCH_MILL_FU.PARAL_LEFT then
|
|
return X_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT or nOrthoOpposite == MCH_MILL_FU.ORTUP_RIGHT or nOrthoOpposite == MCH_MILL_FU.PARAL_RIGHT then
|
|
return -X_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT or nOrthoOpposite == MCH_MILL_FU.ORTUP_FRONT or nOrthoOpposite == MCH_MILL_FU.PARAL_FRONT then
|
|
return Y_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK or nOrthoOpposite == MCH_MILL_FU.ORTUP_BACK or nOrthoOpposite == MCH_MILL_FU.PARAL_BACK then
|
|
return -Y_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN or nOrthoOpposite == MCH_MILL_FU.ORTUP_DOWN or nOrthoOpposite == MCH_MILL_FU.PARAL_DOWN then
|
|
return Z_AX()
|
|
elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP or nOrthoOpposite == MCH_MILL_FU.ORTUP_TOP or nOrthoOpposite == MCH_MILL_FU.PARAL_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 then
|
|
return vtNy
|
|
else
|
|
return vtNz
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetFaceElevation( procOrProcId, nFacet, b3Solid)
|
|
local Proc, nProcId
|
|
if type( procOrProcId) == "table" then
|
|
Proc = procOrProcId
|
|
nProcId = Proc.Id
|
|
else
|
|
nProcId = procOrProcId
|
|
end
|
|
local dElevation
|
|
if not Proc or not Proc.Face or not Proc.Face[nFacet + 1].Elevation then
|
|
dElevation = EgtSurfTmFacetElevationInBBox( nProcId, nFacet, b3Solid, true, GDB_ID.ROOT)
|
|
else
|
|
dElevation = Proc.Face[nFacet + 1].Elevation
|
|
end
|
|
|
|
return dElevation
|
|
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( Proc, nPartId, bCompare3Fc, dCosSideAng)
|
|
local nSurfId = Proc.Id
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- verifica che la superficie non sia chiusa e quindi non lavorabile
|
|
if EgtSurfIsClosed( nSurfId) then
|
|
return
|
|
end
|
|
-- recupero il numero di facce
|
|
local nFacCnt = EgtSurfTmFacetCount( nSurfId)
|
|
if not dCosSideAng then
|
|
dCosSideAng = -0.09
|
|
end
|
|
-- recupero le normali delle facce
|
|
local vvtN = {}
|
|
local vPtC = {}
|
|
for i = 1, nFacCnt do
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT)
|
|
vvtN[i] = vtN ;
|
|
vPtC[i] = ptC
|
|
end
|
|
-- adiacenze e sottosquadra delle facce
|
|
local vAdj = {}
|
|
local vUcut = {}
|
|
local vOrtho = {}
|
|
local nFacesWithUnderCut = 0
|
|
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 sottosquadro ( dal valore passato o - 3deg) e ortogonalità, per facce adiacenti
|
|
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
|
|
-- determino evenutale sottosquadro per facce non adiacenti
|
|
for j = 1, nFacCnt do
|
|
local bIsFaceAdjacent = false
|
|
for k = 1, #vFacAdj do
|
|
if j - 1 == vFacAdj[k] then
|
|
bIsFaceAdjacent = true
|
|
break
|
|
end
|
|
end
|
|
if not ( bIsFaceAdjacent or ( j == i)) then
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BeamLib.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
EgtOutLog( 'Error : missing AddGroup')
|
|
return 0, 0, 0
|
|
end
|
|
-- verifico eventuale intersezione tra la faccia i-1 esima e la proiezione dell'altra sulla stessa
|
|
local nShadowFacetId = EgtCopySurfTmFacet( nSurfId, j - 1, nAddGrpId)
|
|
local nMasterContourId = EgtExtractSurfTmFacetLoops( nSurfId, i - 1, nAddGrpId)
|
|
local nShadowContourId = EgtExtractSurfTmLoops( nShadowFacetId, nAddGrpId)
|
|
EgtCutSurfTmPlane( nShadowFacetId, vPtC[i], -vvtN[i], false, GDB_RT.GLOB)
|
|
if nMasterContourId and nShadowContourId then
|
|
local nMasterSurfFlatId = EgtSurfFlatRegion( nAddGrpId, nMasterContourId)
|
|
local frOCSMaster = Frame3d( vPtC[i], vvtN[i])
|
|
EgtScale( nShadowContourId, frOCSMaster, 1, 1, 0, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nShadowContourId, vvtN[i], GDB_RT.GLOB)
|
|
local nShadowSurfFlatId
|
|
-- se non troppo ortogonale (almeno 0.5deg di delta)
|
|
local dResV = vvtN[i] * vvtN[j]
|
|
if abs( dResV) > 0.087 then
|
|
EgtOffsetCurve( nShadowContourId, EgtIf( dResV > GEO.EPS_SMALL, - 50, 50) * GEO.EPS_SMALL)
|
|
local nShadowSurfFlatId = EgtSurfFlatRegion( nAddGrpId, nShadowContourId)
|
|
local bShadowSurfIsExternal = EgtSurfFrTestExternal( nMasterSurfFlatId, nShadowSurfFlatId)
|
|
if not bShadowSurfIsExternal then
|
|
bUcut = true
|
|
end
|
|
EgtErase( nShadowSurfFlatId)
|
|
end
|
|
EgtErase( nMasterSurfFlatId)
|
|
end
|
|
EgtErase( { nMasterContourId, nShadowContourId, nShadowFacetId})
|
|
end
|
|
end
|
|
if bUcut then
|
|
nFacesWithUnderCut = nFacesWithUnderCut + 1
|
|
end
|
|
vUcut[i] = bUcut
|
|
vOrtho[i] = bOrtho
|
|
end
|
|
local bEveryFaceHasUndercut = ( nFacesWithUnderCut == nFacCnt)
|
|
-- tunnel o assimilabile
|
|
if Proc.Topology == 'Tunnel' or ( bCompare3Fc and Proc.Topology == 'Groove' and Proc.IsThrough) or ( Proc.Topology == 'Strip' and bEveryFaceHasUndercut) then
|
|
if Proc.IsParallel or Proc.AllRightAngles then
|
|
return -1, GEO.INFINITO, true
|
|
else
|
|
-- non gestito nella LapJoint
|
|
return -1, GEO.INFINITO
|
|
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( Proc, nFacInd[i], b3Solid)
|
|
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) and dMinElev < 0.85 * dtElev[i] 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
|
|
|
|
---------------------------------------------------------------------
|
|
--- ritorna il riferimento di tipo OCS della faccia *nFacet* della trimesh *nSurfId* e le dimensioni orizzontale e verticale, eventualmente limitate dal grezzo *b3Raw*
|
|
---@param nSurfId integer Id della trimesh
|
|
---@param nFacet integer Indice 0-based della faccia della trimesh di cui restituire le informazioni
|
|
---@param b3Raw? BBox3d Eventuale box del grezzo per limitare le dimensioni
|
|
---@return Frame3d frHv riferimento faccia OCS
|
|
---@return number dDimH dimensione orizzontale OCS
|
|
---@return number dDmiV dimensione verticale OCS
|
|
function BeamLib.GetFaceHvRefDim( nSurfId, nFacet, b3Raw)
|
|
-- 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)
|
|
local dDimH = b3HV:getDimX()
|
|
local dDimV = b3HV:getDimY()
|
|
-- se definito grezzo (o solido), applico eventuali limiti
|
|
if b3Raw then
|
|
local dCoeffY = abs( frHV:getVersX():getY())
|
|
if dCoeffY > GEO.EPS_SMALL then
|
|
dDimH = min( dDimH, b3Raw:getDimY() / dCoeffY)
|
|
end
|
|
local dCoeffZ = abs( frHV:getVersY():getZ())
|
|
if dCoeffZ > GEO.EPS_SMALL then
|
|
dDimV = min( dDimV, b3Raw:getDimZ() / dCoeffZ)
|
|
end
|
|
end
|
|
-- restituisco i valori calcolati
|
|
return frHV, dDimH, dDimV
|
|
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, vtN, vtOrtho)
|
|
if BD.GetNzLimDownUp then
|
|
return BD.GetNzLimDownUp( b3Raw, vtN, vtOrtho)
|
|
elseif BD.C_SIMM then
|
|
return -0.484
|
|
elseif BD.TURN then
|
|
return -2
|
|
else
|
|
if vtOrtho and vtOrtho:getZ() > 0.35 then
|
|
-- N_HorAng < 15° or N_HorAng > 55°
|
|
if vtN and ( abs( vtN:getY()) < 0.259 or abs( vtN:getY()) > 0.819) then
|
|
return -0.708
|
|
-- N_HorAng > 50°
|
|
elseif vtN and abs( vtN:getY()) > 0.766 then
|
|
return -0.383
|
|
else
|
|
return EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM, -0.609, -0.383)
|
|
end
|
|
else
|
|
-- N_HorAng > 60°
|
|
if vtN and ( abs( vtN:getY()) > 0.866) then
|
|
return -0.708
|
|
else
|
|
if b3Raw:getDimZ() < 120 then
|
|
return -0.708
|
|
elseif b3Raw:getDimZ() < 200 then
|
|
-- N_HorAng < 15° or N_HorAng > 55°
|
|
if vtN and ( abs( vtN:getY()) < 0.259 or abs( vtN:getY()) > 0.819) then
|
|
return -0.5
|
|
else
|
|
return -0.383
|
|
end
|
|
elseif b3Raw:getDimZ() < 300 then
|
|
-- N_HorAng < 10°
|
|
if vtN and ( abs( vtN:getY()) < 0.174) then
|
|
return -0.5
|
|
else
|
|
return -0.259
|
|
end
|
|
elseif b3Raw:getDimZ() < BD.MIN_DIM_HBEAM then
|
|
-- N_HorAng < 10°
|
|
if vtN and ( abs( vtN:getY()) < 0.174) then
|
|
return -0.342
|
|
else
|
|
return -0.259
|
|
end
|
|
else
|
|
-- N_HorAng < 10°
|
|
if vtN and ( abs( vtN:getY()) < 0.174) then
|
|
return -0.383
|
|
else
|
|
return -0.174
|
|
end
|
|
end
|
|
end
|
|
end
|
|
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
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetDistanceToNextPart( nRawId, nPhase)
|
|
-- Recupero la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or BD.OVM_MID
|
|
-- se segue una parte rimanente riutilizzabile, modifico opportunamente questa distanza
|
|
if not BeamLib.IsSplittedPartPhase( nPhase) then
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and
|
|
EgtGetPartInRawPartCount( nNextRawId) <= 0 and
|
|
EgtGetRawPartBBox( nNextRawId):getDimX() >= BD.MinRaw then
|
|
|
|
dDistToNextPiece = BD.OVM_MID
|
|
end
|
|
end
|
|
return dDistToNextPiece
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetChainSawInitAngs( vtN, vtO, nInd)
|
|
if BD.GetChainSawInitAngs then
|
|
return BD.GetChainSawInitAngs( vtN, vtO, nInd)
|
|
else
|
|
if BD.C_SIMM then
|
|
return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180')
|
|
else
|
|
if nInd == 1 then
|
|
return ''
|
|
else
|
|
return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
---
|
|
---@param sMachining string nome della lavorazione di cui bloccare l'asse
|
|
---@param sBlockedAxis string rappresenta lo stato desiderato dell'asse bloccato, parallelo o perpendicolare all'asse rotante da cui dipende (*parallel* o *perpendicular*)
|
|
---@param b3Raw? BBox3d
|
|
---@param vtTool? Vector3d
|
|
---@param vtOut? Vector3d
|
|
---@return string # testo contenente il valore dell'asse rotante bloccato da scrivere nel parametro *MCH_MP.BLOCKEDAXIS* della lavorazione (es: 'A2=90')
|
|
function BeamLib.GetBlockedAxis( sMachining, sBlockedAxis, b3Raw, vtTool, vtOut)
|
|
-- informazioni sull'utensile della lavorazione
|
|
local nToolType, sHead
|
|
if EgtMdbSetCurrMachining( sMachining) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
|
|
sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
end
|
|
end
|
|
-- se presente funzione specifica nella macchina, la richiamo
|
|
if BD.GetBlockedAxis then
|
|
return BD.GetBlockedAxis( sHead, nToolType, sBlockedAxis, b3Raw, vtTool, vtOut) or ''
|
|
-- sezione mantenuta per retrocompatibilità con GetChainSawBlockedAxis
|
|
elseif nToolType == MCH_TY.MORTISE_STD then
|
|
local nInd = EgtIf( sBlockedAxis == 'parallel', 0, 1)
|
|
if BD.GetChainSawBlockedAxis then
|
|
return BD.GetChainSawBlockedAxis( nInd)
|
|
else
|
|
if nInd == 1 then
|
|
return EgtIf( BD.C_SIMM, 'A=90', 'A=90')
|
|
else
|
|
return EgtIf( BD.C_SIMM, 'A=0', 'A=0')
|
|
end
|
|
end
|
|
end
|
|
|
|
return ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Trova l'Ind (0 based) della faccia meglio orientata come l'asse vtAx. Restituisce anche vtN e ptC della faccia stessa. La faccia di indice (0 based) fctExclude non viene considerata nella ricerca.
|
|
function BeamLib.FindFaceBestOrientedAsAxis( Proc, vtAx, fctExclude)
|
|
local nFaceIndMax = 0
|
|
local dMaxComp = 0
|
|
fctExclude = fctExclude or -1
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
local dComp = abs( vtN * vtAx)
|
|
if dComp > dMaxComp and i ~= fctExclude + 1 then
|
|
nFaceIndMax = i -1
|
|
dMaxComp = dComp
|
|
end
|
|
end
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFaceIndMax, GDB_ID.ROOT)
|
|
return nFaceIndMax, ptC, vtN
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetEdgeToMachineFromVector( nSurfId, nFacet, vtOrtho)
|
|
local _, EdgesEgt = EgtSurfTmGetFacetOutlineInfo( nSurfId, nFacet, GDB_ID.ROOT)
|
|
|
|
local nEdgeIndMax = 0
|
|
local dMaxComp = - GEO.INFINITO
|
|
for i = 1, #EdgesEgt do
|
|
local vtN = EdgesEgt[i].Norm
|
|
if EdgesEgt[i].Open then
|
|
vtN = -vtN
|
|
end
|
|
local dComp = vtN * vtOrtho
|
|
if dComp > dMaxComp then
|
|
nEdgeIndMax = i -1
|
|
dMaxComp = dComp
|
|
end
|
|
end
|
|
|
|
return nEdgeIndMax
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetTunnelDimension( Proc, nPartId)
|
|
-- sono necessarie almeno due facce
|
|
if Proc.Fct < 2 then return 0, 0, 0 end
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- recupero centro e normale delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
for i = 1, Proc.Fct do
|
|
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
end
|
|
-- calcolo l'orientamento del tunnel
|
|
local vtOrtho
|
|
local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1)
|
|
if bAdj then
|
|
vtOrtho = vtN[1] ^ vtN[2]
|
|
else
|
|
if Proc.Fct >= 3 then
|
|
vtOrtho = vtN[1] ^ vtN[3]
|
|
else
|
|
return 0, 0, 0
|
|
end
|
|
end
|
|
-- ottengo il boundingBox e prendo le dimensioni lungo la direzione (Z locale) che rappresenta la profondità della fessura
|
|
local frFc = Frame3d( ptC[1], vtOrtho) ;
|
|
local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
|
|
local dDepth = b3BoxLoc:getDimZ()
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BeamLib.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
EgtOutLog( 'Error : missing AddGroup')
|
|
return 0, 0, 0
|
|
end
|
|
-- centro del bounding box locale
|
|
local ptCen = b3BoxLoc:getCenter()
|
|
ptCen:toGlob( frFc)
|
|
-- creo superficie intermedia
|
|
local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptCen, vtOrtho, b3Solid, GDB_ID.ROOT)
|
|
if not nSurfInt then return 0, 0, 0 end
|
|
-- ritaglio la superficie con le facce della fessura
|
|
for i = 1, Proc.Fct do
|
|
EgtCutSurfTmPlane( nSurfInt, ptC[i], -vtN[i], false, GDB_ID.ROOT)
|
|
end
|
|
local frSurfInt, dDimMax, dDimMin = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT)
|
|
-- cerco la faccia con larghezza pari a dimensione massima della fessura
|
|
local nLongIdFace = 0
|
|
for i = 1, Proc.Fct do
|
|
if abs( vtN[i] * frSurfInt:getVersX()) < 0.5 then
|
|
nLongIdFace = i - 1
|
|
break
|
|
end
|
|
end
|
|
return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.CalcCollisionSafety( vtDir)
|
|
local dCollSic = 10 * BD.COLL_SIC
|
|
if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then
|
|
dCollSic = 0
|
|
elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then
|
|
dCollSic = 1 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then
|
|
dCollSic = 2.5 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.86 or abs( vtDir:getY()) > 0.86 or abs( vtDir:getZ()) > 0.86 then
|
|
dCollSic = 4 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then
|
|
dCollSic = 5.5 * BD.COLL_SIC
|
|
end
|
|
return dCollSic
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.SetOpenSide( nPathInt, b3Solid)
|
|
-- fondo tra loro le curve compatibili
|
|
EgtMergeCurvesInCurveCompo( nPathInt)
|
|
-- vettore indici lati aperti
|
|
local vOpen = {}
|
|
-- ciclo sulle curve elementari della composita
|
|
local _, nNumEnt = EgtCurveDomain( nPathInt)
|
|
for i = 0, nNumEnt - 1 do
|
|
-- se segmento di retta
|
|
if EgtCurveCompoRadius( nPathInt, i) == -1 then
|
|
-- verifico se giace in uno dei piani limite del pezzo quindi se è un lato aperto
|
|
local ptIni = EgtUP( nPathInt, i, GDB_RT.GLOB)
|
|
local ptFin = EgtUP( nPathInt, i + 1, GDB_RT.GLOB)
|
|
if ( abs( ptIni:getX() - b3Solid:getMax():getX()) < 100 * GEO.EPS_SMALL and abs( ptFin:getX() - b3Solid:getMax():getX()) < 100 * GEO.EPS_SMALL) or
|
|
( abs( ptIni:getX() - b3Solid:getMin():getX()) < 100 * GEO.EPS_SMALL and abs( ptFin:getX() - b3Solid:getMin():getX()) < 100 * GEO.EPS_SMALL) or
|
|
( abs( ptIni:getY() - b3Solid:getMax():getY()) < 100 * GEO.EPS_SMALL and abs( ptFin:getY() - b3Solid:getMax():getY()) < 100 * GEO.EPS_SMALL) or
|
|
( abs( ptIni:getY() - b3Solid:getMin():getY()) < 100 * GEO.EPS_SMALL and abs( ptFin:getY() - b3Solid:getMin():getY()) < 100 * GEO.EPS_SMALL) or
|
|
( abs( ptIni:getZ() - b3Solid:getMax():getZ()) < 100 * GEO.EPS_SMALL and abs( ptFin:getZ() - b3Solid:getMax():getZ()) < 100 * GEO.EPS_SMALL) or
|
|
( abs( ptIni:getZ() - b3Solid:getMin():getZ()) < 100 * GEO.EPS_SMALL and abs( ptFin:getZ() - b3Solid:getMin():getZ()) < 100 * GEO.EPS_SMALL) then
|
|
-- aggiorno il vettore dei lati aperti
|
|
table.insert( vOpen, i)
|
|
end
|
|
end
|
|
end
|
|
-- assegno gli indici dei lati aperti
|
|
EgtSetInfo( nPathInt, 'OPEN', vOpen)
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.ChangeOrOpenStart( nPathInt, nStartPoint)
|
|
-- verifico richiesta
|
|
if nStartPoint ~= 1 and nStartPoint ~= 2 then
|
|
return false
|
|
end
|
|
-- verifico che la curva sia chiusa
|
|
if not EgtCurveIsClosed( nPathInt) then
|
|
return true
|
|
end
|
|
-- recupero l'indice del segmento aperto più lungo
|
|
local nMaxOpen, dMaxLen
|
|
local vOpen = EgtGetInfo( nPathInt or GDB_ID.NULL, 'OPEN', 'vi')
|
|
for i = 1, #( vOpen or {}) do
|
|
-- se primo o più lungo, lo salvo
|
|
local dLen = EgtCurveCompoLength( nPathInt, vOpen[i])
|
|
if not dMaxLen or dLen > dMaxLen then
|
|
dMaxLen = dLen
|
|
nMaxOpen = vOpen[i]
|
|
end
|
|
end
|
|
-- se esiste tratto aperto
|
|
if nMaxOpen then
|
|
-- sposto il punto di inizio a metà del tratto aperto più lungo (la curva deve essere chiusa)
|
|
EgtChangeClosedCurveStart( nPathInt, nMaxOpen + 0.5)
|
|
-- aggiorno il vettore dei lati aperti
|
|
for i = 1, #vOpen do
|
|
vOpen[i] = vOpen[i] - nMaxOpen
|
|
end
|
|
table.insert( vOpen, #vOpen)
|
|
-- se devo eliminare gli estremi aperti
|
|
if nStartPoint == 2 then
|
|
-- elimino gli estremi
|
|
EgtRemoveCurveCompoCurve( nPathInt, true)
|
|
EgtRemoveCurveCompoCurve( nPathInt, false)
|
|
-- aggiorno il vettore dei lati aperti
|
|
table.remove( vOpen, 1)
|
|
table.remove( vOpen)
|
|
for i = 1, #vOpen do
|
|
vOpen[i] = vOpen[i] - 1
|
|
end
|
|
end
|
|
end
|
|
-- assegno gli indici modificati dei lati aperti
|
|
EgtSetInfo( nPathInt, 'OPEN', vOpen)
|
|
-- restituisco flag percorso aperto
|
|
return ( not EgtCurveIsClosed( nPathInt))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.ConvertToClosedCurve( Proc, AuxId)
|
|
local bCurveModified = false
|
|
if not EgtCurveIsClosed( AuxId) then
|
|
local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id))
|
|
if NewId then
|
|
-- elimino eventuali loop interni (non dovrebbero comunque esserci)
|
|
for i = 1, nCount - 1 do
|
|
EgtErase( NewId + i)
|
|
end
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
|
|
-- sostituisco il loop esterno alla curva originale
|
|
EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT)
|
|
EgtRelocate( NewId, AuxId, GDB_IN.AFTER)
|
|
EgtErase( AuxId)
|
|
EgtChangeId( NewId, AuxId)
|
|
bCurveModified = true
|
|
-- sistemo i lati aperti
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1]
|
|
if vFacAdj then
|
|
local vOpen = {}
|
|
for i = 1, #vFacAdj do
|
|
if vFacAdj[i] < 0 then
|
|
table.insert( vOpen, i - 1)
|
|
end
|
|
end
|
|
EgtSetInfo( AuxId, 'OPEN', vOpen)
|
|
end
|
|
end
|
|
end
|
|
|
|
return true, bCurveModified
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.CurveWithOnlyStraightLines( nPathInt)
|
|
-- verifico sia una retta oppure una curva composita
|
|
local nType = EgtGetType( nPathInt)
|
|
if nType == GDB_TY.CRV_LINE then
|
|
return true
|
|
elseif nType~= GDB_TY.CRV_COMPO then
|
|
return false
|
|
end
|
|
-- ciclo sulle curve elementari della composita
|
|
local _, nNumEnt = EgtCurveDomain( nPathInt)
|
|
for i = 0, nNumEnt - 1 do
|
|
-- se segmento di retta
|
|
if EgtCurveCompoRadius( nPathInt, i) ~= -1 then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
|
function BeamLib.Is3EdgesApprox( Proc, nFacet, nAddGrpId)
|
|
nAddGrpId = nAddGrpId or BeamLib.GetAddGroup( Proc.PartId)
|
|
if not nAddGrpId then
|
|
local nEdges = #(EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1])
|
|
return ( nEdges == 3)
|
|
end
|
|
local bResult = false
|
|
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
|
|
if not nContourId then return false end
|
|
EgtMergeCurvesInCurveCompo( nContourId)
|
|
-- recupero il numero effettivo di lati
|
|
local _, nEntityCount = EgtCurveDomain( nContourId)
|
|
local nEdges = nEntityCount
|
|
if nEntityCount and nEntityCount == 3 then
|
|
bResult = true
|
|
-- rimuovo i lati molto corti dal conteggio totale
|
|
elseif nEntityCount then
|
|
for i = 1, nEntityCount do
|
|
local dLength = EgtCurveCompoLength( nContourId, i - 1)
|
|
if dLength < 15 then nEdges = nEdges - 1 end
|
|
end
|
|
end
|
|
if nEdges == 3 then bResult = true end
|
|
-- cancello tutti i contorni appena creati
|
|
EgtErase( EgtTableFill( nContourId, nContourCnt))
|
|
return bResult
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce le facce della parte interessate dalla feature Proc
|
|
function BeamLib.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 vero se la feature con box b3Proc taglia l'intera sezione della barra, rappresentata dalle sue dimensioni W e H
|
|
function BeamLib.IsFeatureCuttingEntireSection( b3Proc, dRawW, dRawH)
|
|
return ((abs(b3Proc:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or b3Proc:getDimY() > dRawW) and (abs(b3Proc:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or b3Proc:getDimZ() > dRawH))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetAdjacentFaces( Proc, nFacet)
|
|
local AdjacentFaces = {}
|
|
local vFaceAdjacencies = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1]
|
|
for i = 1, #vFaceAdjacencies do
|
|
if vFaceAdjacencies[i] > -1 then
|
|
local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacet, vFaceAdjacencies[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( AdjacentFaces, { Id = vFaceAdjacencies[i], LengthOnMainFace = dLen})
|
|
end
|
|
end
|
|
|
|
return AdjacentFaces
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetFacetsInfo( Proc, b3Raw)
|
|
|
|
if Proc.Fct > 20 then
|
|
return nil
|
|
end
|
|
|
|
local Face = {}
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( Proc.PartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
local vAdj
|
|
if Proc.AdjacencyMatrix then
|
|
vAdj = Proc.AdjacencyMatrix
|
|
else
|
|
vAdj = BeamLib.GetAdjacencyMatrix( Proc)
|
|
end
|
|
|
|
for i = 1, Proc.Fct do
|
|
Face[i] = {}
|
|
Face[i].Id = i - 1
|
|
Face[i].PtCenter, Face[i].VtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
if Proc.Fct < 10 then
|
|
local frHV, dFaceWidthTrimmed, dFaceHeightTrimmed = BeamLib.GetFaceHvRefDim( Proc.Id, i - 1, b3Raw)
|
|
-- frame OCS faccia
|
|
Face[i].FrameHV = frHV
|
|
-- larghezza OCS faccia trimmata con grezzo
|
|
Face[i].WidthTrimmed = dFaceWidthTrimmed
|
|
-- altezza OCS faccia trimmata con grezzo
|
|
Face[i].HeightTrimmed = dFaceHeightTrimmed
|
|
local _, dFaceWidth, dFaceHeight = BeamLib.GetFaceHvRefDim( Proc.Id, i - 1)
|
|
-- larghezza OCS faccia
|
|
Face[i].Width = dFaceWidth
|
|
-- altezza OCS faccia
|
|
Face[i].Height = dFaceHeight
|
|
-- elevazione calcolata rispetto al box della parte
|
|
Face[i].Elevation = EgtSurfTmFacetElevationInBBox( Proc.Id, i - 1, b3Solid, true, GDB_ID.ROOT)
|
|
-- area della faccia
|
|
-- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo
|
|
local _, dLongEdgeDimension, dShortEdgeDimension = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
Face[i].Area = dShortEdgeDimension * dLongEdgeDimension
|
|
-- adiacenze della faccia
|
|
-- TODO chiamarle in modo che si capisca che sono solo gli id e non l'intero oggetto faccia
|
|
Face[i].Adjacencies = {}
|
|
for j = 1, Proc.Fct do
|
|
if vAdj[i][j] and vAdj[i][j] ~= 0 and ( i ~= j) then
|
|
table.insert( Face[i].Adjacencies, j - 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return Face
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetEdgesInfo( Proc, Face)
|
|
local Edges = {}
|
|
local nFaceType, vEdges = EgtSurfTmGetFacetOutlineInfo( Proc.Id, Face.Id, GDB_ID.ROOT)
|
|
|
|
if nFaceType < 1 then
|
|
for j = 1, #vEdges do
|
|
local nPreviousEdgeIndex = j - 1
|
|
if j == 1 then
|
|
nPreviousEdgeIndex = #vEdges
|
|
end
|
|
local nNextEdgeIndex = j + 1
|
|
if j == #vEdges then
|
|
nNextEdgeIndex = 1
|
|
end
|
|
|
|
local CurrentEdge = {}
|
|
CurrentEdge.AdjacentFaceId = vEdges[j].Adj
|
|
CurrentEdge.ToolDirection = Vector3d( vEdges[j].Norm)
|
|
CurrentEdge.Length = vEdges[j].Len
|
|
CurrentEdge.Elevation = vEdges[j].Elev
|
|
CurrentEdge.IsOpen = vEdges[j].Open
|
|
CurrentEdge.IsStartOpen = ( vEdges[nPreviousEdgeIndex].Open)
|
|
CurrentEdge.IsEndOpen = ( vEdges[nNextEdgeIndex].Open)
|
|
|
|
table.insert( Edges, CurrentEdge)
|
|
end
|
|
else
|
|
error( 'Face with closed hole')
|
|
end
|
|
|
|
return Edges
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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 BeamLib.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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetMachiningSteps( dMachiningDepth, dStep)
|
|
|
|
local MachiningSteps = {}
|
|
MachiningSteps.StepLength = 0
|
|
MachiningSteps.Count = ceil( ( dMachiningDepth - 10 * GEO.EPS_SMALL) / dStep)
|
|
if MachiningSteps.Count > 1 then
|
|
MachiningSteps.StepLength = ( dMachiningDepth - dStep) / ( MachiningSteps.Count - 1)
|
|
end
|
|
|
|
return MachiningSteps
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.IsCutNeeded( Proc, b3Raw, dOvmHead, dOvmTail)
|
|
if not dOvmTail then
|
|
dOvmTail = BD.OVM_MID
|
|
end
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
|
|
if Proc.Head then
|
|
-- se coincide con il taglio di separazione precedente, non va fatto
|
|
if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
|
|
return false
|
|
end
|
|
-- altrimenti taglio di coda
|
|
else
|
|
-- se coincide con taglio di separazione, non va fatto
|
|
if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < dOvmTail + 10 * GEO.EPS_SMALL then
|
|
return false
|
|
end
|
|
end
|
|
-- se coincide con un taglio frontale non va fatto
|
|
if Proc.CutFront then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamLib.GetToolFromMachining( sMachiningName)
|
|
local Tool = {}
|
|
if EgtMdbSetCurrMachining( sMachiningName) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
Tool.Name = EgtTdbGetCurrToolParam( MCH_TP.NAME)
|
|
Tool.IsCCW = ( EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) < 0)
|
|
Tool.Type = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
|
|
Tool.Diameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0
|
|
Tool.HeadType = {}
|
|
Tool.PreferredSide = {}
|
|
if BD.GetSetupInfo then
|
|
Tool.HeadType = BD.GetSetupInfo( EgtTdbGetCurrToolParam( MCH_TP.HEAD)).HeadType
|
|
Tool.PreferredSide = BD.GetSetupInfo( EgtTdbGetCurrToolParam( MCH_TP.HEAD)).PreferredSide
|
|
end
|
|
-- lama
|
|
if Tool.Type == MCH_TY.SAW_STD or Tool.Type == MCH_TY.SAW_FLAT then
|
|
Tool.Thickness = EgtTdbGetCurrToolParam(MCH_TP.THICK) or 0
|
|
Tool.MaxDepth = EgtTdbGetCurrToolMaxDepth() or 0
|
|
Tool.SideStep = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDESTEP', 'd')
|
|
-- sega a catena
|
|
elseif Tool.Type == MCH_TY.MORTISE_STD then
|
|
Tool.Length = EgtTdbGetCurrToolParam( MCH_TP.LEN) or 0
|
|
Tool.MaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or 0
|
|
Tool.Width = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0
|
|
Tool.Thickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0
|
|
Tool.CornerRadius = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or 0
|
|
-- fresa (TODO al momento aggiunte solo le informazioni che servono)
|
|
elseif Tool.Type == MCH_TY.MILL_STD or MCH_TY.MILL_NOTIP then
|
|
if BD.GetSetupInfo then
|
|
Tool.IsOnAggregate = BD.GetSetupInfo( EgtTdbGetCurrToolParam( MCH_TP.HEAD)).bToolOnAggregate
|
|
else
|
|
Tool.IsOnAggregate = false
|
|
end
|
|
-- altri utensili al momento non previsti
|
|
else
|
|
error( 'Wrong tool type')
|
|
end
|
|
end
|
|
end
|
|
|
|
return Tool
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return BeamLib |