d7096a8a68
- aggiunto parametro sCanDamageNextPiece
478 lines
18 KiB
Lua
478 lines
18 KiB
Lua
-- BeamLib.lua by Egalware s.r.l. 2024/04/02
|
|
-- Libreria globale per Travi
|
|
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
|
|
|
|
|
|
-- Tabella per definizione modulo
|
|
local BeamLib = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BeamData = require( 'BeamData')
|
|
|
|
EgtOutLog( ' BeamLib started', 1)
|
|
|
|
--TODO refactoring di queste funzioni
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
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( nRawId, OriXR, PosXR, dDeltaSucc)
|
|
EgtAddPhase()
|
|
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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
--- funzione che ruota il pezzo, da lanciare per creare la disposizione corretta
|
|
function BeamLib.RotatePart( Part, nPosition)
|
|
-- primo posizionamento
|
|
if nPosition == 1 then
|
|
; -- il pezzo è già in posizione
|
|
-- rotazione 90°
|
|
elseif nPosition == 2 then
|
|
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
|
|
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
|
|
local bPreMove = dDeltaYZ < 0
|
|
-- ruoto le travi della fase corrente
|
|
local nRId = Part.idRaw
|
|
while nRId do
|
|
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90))
|
|
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
nRId = EgtGetNextRawPart( nRId)
|
|
end
|
|
-- rotazione 180°
|
|
elseif nPosition == 3 then
|
|
-- ribalto le travi della fase corrente
|
|
local nRId = Part.idRaw
|
|
while nRId do
|
|
EgtRotateRawPart( nRId, X_AX(), 180)
|
|
nRId = EgtGetNextRawPart( nRId)
|
|
end
|
|
-- rotazione 270°
|
|
elseif nPosition == 4 then
|
|
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
|
|
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
|
|
local bPreMove = dDeltaYZ < 0
|
|
-- ruoto le travi della fase corrente
|
|
local nRId = Part.idRaw
|
|
while nRId do
|
|
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, 90, -90))
|
|
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
nRId = EgtGetNextRawPart( nRId)
|
|
end
|
|
end
|
|
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.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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce le facce della parte interessate dalla feature Proc
|
|
function BeamLib.GetAffectedFaces( Proc, Part)
|
|
local vtFacesAffected = { bTop = false, bBottom = false, bFront = false, bBack = false, bLeft = false, bRight = false}
|
|
if Proc.b3Box and not Proc.b3Box:isEmpty() then
|
|
if Proc.b3Box:getMax():getZ() > Part.b3Solid:getMax():getZ() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bTop = true
|
|
end
|
|
if Proc.b3Box:getMin():getZ() < Part.b3Solid:getMin():getZ() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bBottom = true
|
|
end
|
|
if Proc.b3Box:getMin():getY() < Part.b3Solid:getMin():getY() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bFront = true
|
|
end
|
|
if Proc.b3Box:getMax():getY() > Part.b3Solid:getMax():getY() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bBack = true
|
|
end
|
|
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bLeft = true
|
|
end
|
|
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - 500 * GEO.EPS_SMALL then
|
|
vtFacesAffected.bRight = true
|
|
end
|
|
end
|
|
|
|
return vtFacesAffected
|
|
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.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
|
|
|
|
---------------------------------------------------------------------
|
|
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
|
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
|
|
nAddGrpId = nAddGrpId or BeamLib.GetAddGroup( Proc.idPart)
|
|
if not nAddGrpId then
|
|
local nEdges = #(EgtSurfTmFacetAdjacencies( Proc.id, idFace)[1])
|
|
return ( nEdges == 3)
|
|
end
|
|
local bResult = false
|
|
|
|
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- sovrascrivo i parametri personalizzati salvati su Proc a quelli di default dalla strategia
|
|
-- N.B. : I parametri personalizzati non più presenti tra i default della strategia, verranno ignorati. Quelli extra avranno valore di default
|
|
-- Il controllo deve essere fatto SEMPRE all'inizio di ogni strategia, per controllare conformità parametri custom
|
|
function BeamLib.GetUpdateCustomParameters( CustomStrategyParamList, DefaultStrategyParamList)
|
|
if CustomStrategyParamList and #CustomStrategyParamList > 0 then
|
|
for i = 1, #DefaultStrategyParamList do
|
|
for j = 1, #CustomStrategyParamList do
|
|
if DefaultStrategyParamList[i].sName == CustomStrategyParamList[j].sName then
|
|
DefaultStrategyParamList[i].sValue = CustomStrategyParamList[j].sValue
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return DefaultStrategyParamList
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- si traduce la tabella dei parametri con tutte le informazioni in una lista contenente i parametri utilizzabili con accesso diretto
|
|
function BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
|
local Parameters = {}
|
|
if CustomParameters and #CustomParameters > 0 then
|
|
for i=1, #CustomParameters do
|
|
if CustomParameters[i].sType == 'b' then
|
|
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue == 'true'
|
|
elseif CustomParameters[i].sType == 'd' then
|
|
Parameters[CustomParameters[i].sName] = tonumber( CustomParameters[i].sValue)
|
|
else --CustomParameters[i].sType == 's' or CustomParameters[i].sType == 'combo'
|
|
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue
|
|
end
|
|
end
|
|
end
|
|
return Parameters
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetChainSawInitAngs( vtN, vtO, nInd)
|
|
if BeamData.GetChainSawInitAngs then
|
|
return BeamData.GetChainSawInitAngs( vtN, vtO, nInd)
|
|
else
|
|
if BeamData.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
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
|
|
-- se presente funzione specifica nella macchina, la richiamo
|
|
if BeamData.GetBlockedAxis then
|
|
return BeamData.GetBlockedAxis( TOOLS[nToolIndex].sHead, TOOLS[nToolIndex].nTypeId, sBlockedAxis, b3Raw, vtTool, vtOut) or ''
|
|
-- sezione mantenuta per retrocompatibilità con GetChainSawBlockedAxis
|
|
elseif TOOLS[nToolIndex].nTypeId == MCH_TY.MORTISE_STD then
|
|
local nInd = EgtIf( sBlockedAxis == 'parallel', 0, 1)
|
|
if BeamData.GetChainSawBlockedAxis then
|
|
return BeamData.GetChainSawBlockedAxis( nInd)
|
|
else
|
|
if nInd == 1 then
|
|
return EgtIf( BeamData.C_SIMM, 'A=90', 'A=90')
|
|
else
|
|
return EgtIf( BeamData.C_SIMM, 'A=0', 'A=0')
|
|
end
|
|
end
|
|
end
|
|
|
|
return ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.BinaryToDecimal( dNumber)
|
|
local sNumberToConvert = tostring( dNumber)
|
|
local dResult = 0
|
|
local k = 0
|
|
|
|
for i = #sNumberToConvert, 1, -1 do
|
|
k = k + 1
|
|
local n = string.sub(sNumberToConvert, k, k)
|
|
dResult = dResult + n*(2^(i-1))
|
|
end
|
|
|
|
return dResult
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.DecimalToBinary( dNumber)
|
|
local sNumberToConvert = tostring( dNumber)
|
|
local n = sNumberToConvert
|
|
local tmp = {}
|
|
local sResult = ""
|
|
|
|
for i = sNumberToConvert, 0, -1 do
|
|
local q = math.modf(n)
|
|
n = n/2
|
|
local b = q%2
|
|
table.insert(tmp, b)
|
|
|
|
if (q == 1) then
|
|
break
|
|
end
|
|
end
|
|
|
|
for i = #tmp, 1, -1 do
|
|
sResult = sResult..tmp[i]
|
|
end
|
|
|
|
return tonumber( sResult)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
|
|
local NumberString = tostring( dNumber)
|
|
while #NumberString < CharNumber do
|
|
NumberString = '0' .. NumberString
|
|
end
|
|
|
|
return NumberString
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
|
|
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
|
|
function BeamLib.TableCopyDeep( OriginalTable)
|
|
local CopiedTable = {}
|
|
for key, value in pairs( OriginalTable) do
|
|
if type( value) == "table" then
|
|
if isBBox3d( value) then
|
|
CopiedTable[ key] = BBox3d( value)
|
|
elseif isColor3d( value) then
|
|
CopiedTable[ key] = Color3d( value)
|
|
elseif isFrame3d( value) then
|
|
CopiedTable[ key] = Frame3d( value)
|
|
elseif isPoint3d( value) then
|
|
CopiedTable[ key] = Point3d( value)
|
|
elseif isQuaternion( value) then
|
|
CopiedTable[ key] = Quaternion( value)
|
|
elseif isVector3d( value) then
|
|
CopiedTable[ key] = Vector3d( value)
|
|
else
|
|
CopiedTable[ key] = BeamLib.TableCopyDeep( value)
|
|
end
|
|
else
|
|
CopiedTable[ key] = value
|
|
end
|
|
end
|
|
|
|
return CopiedTable
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return BeamLib
|