-- 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') 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( Part, OriXR, PosXR, dDeltaSucc) EgtAddPhase() local nRawId = Part.IdRaw 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.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) 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 --------------------------------------------------------------------- -- 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.PartId) 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 --------------------------------------------------------------------- --- ritorna il riferimento di tipo OCS della faccia *idFace* della trimesh *nSurfId* e le dimensioni orizzontale e verticale, eventualmente limitate dal grezzo *Part.RawBox* function BeamLib.GetFaceHvRefDim( nSurfId, idFace, Part) -- recupero centro e normale della faccia local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, idFace, 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, idFace, GDB_BB.STANDARD, frHV) local dDimH = b3HV:getDimX() local dDimV = b3HV:getDimY() -- se definito grezzo (o solido), applico eventuali limiti if Part.RawBox then local dCoeffY = abs( frHV:getVersX():getY()) if dCoeffY > GEO.EPS_SMALL then dDimH = min( dDimH, Part.RawBox:getDimY() / dCoeffY) end local dCoeffZ = abs( frHV:getVersY():getZ()) if dCoeffZ > GEO.EPS_SMALL then dDimV = min( dDimV, Part.RawBox:getDimZ() / dCoeffZ) end end -- restituisco i valori calcolati return frHV, dDimH, dDimV 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].Name == CustomStrategyParamList[j].Name then DefaultStrategyParamList[i].Value = CustomStrategyParamList[j].Value 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].Type == 'b' then Parameters[CustomParameters[i].Name] = CustomParameters[i].Value == 'true' elseif CustomParameters[i].Type == 'd' then Parameters[CustomParameters[i].Name] = tonumber( CustomParameters[i].Value) else -- CustomParameters.Type == 's' Parameters[CustomParameters[i].Name] = CustomParameters[i].Value end end end return Parameters end ------------------------------------------------------------------------------------------------------------- return BeamLib