UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MeshElementIndexer.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
8#include "Containers/Set.h"
9#include "CoreMinimal.h"
10#include "HAL/UnrealMemory.h"
11#include "Math/UnrealMathSSE.h"
12#include "MeshAttributeArray.h"
14#include "Templates/EnableIf.h"
16#include "UObject/NameTypes.h"
17
19struct FElementID;
20
21
48{
49public:
52
53 // Copying not allowed as they reference elements of a MeshDescription of which they are normally a part
56
57 // Moving OK
60
64 MESHDESCRIPTION_API void Set(const FMeshElementChannels* Key, const FMeshElementChannels* Referencer, FName AttributeName, int32 ReferencerChannelIndex = 0);
65
70
76 {
77 ChunkBits = FMath::CeilLogTwo(InChunkSize);
78 ChunkMask = (1U << ChunkBits) - 1;
79 }
80
86 {
87 SetChunkSize(1);
88 check(ChunkBits == 0);
89 check(ChunkMask == 0);
90 }
91
96
102 {
103 check(!bSuspended);
104 ConditionalBuild(KeyIndex, KeyChannelIndex);
105 int32 Chunk = GetChunkForKey(KeyIndex);
106 int32 ChunkElement = GetChunkElementForKey(KeyIndex);
107
108 check(KeyChannelIndex < PerChannelIndices.Num());
109 if (PerChannelIndices[KeyChannelIndex].Chunks.Num() == 0)
110 {
112 }
113 return PerChannelIndices[KeyChannelIndex].Chunks[Chunk].Get(ChunkElement);
114 }
115
116
117 template <typename ElementIDType>
119 {
120 check(!bSuspended);
121 check(KeyIndex != INDEX_NONE);
122 ConditionalBuild(KeyIndex, KeyChannelIndex);
123 int32 Chunk = GetChunkForKey(KeyIndex);
124 int32 ChunkElement = GetChunkElementForKey(KeyIndex);
125
126 // If the key hasn't yet had a chunk created for it, assume that nothing has yet referenced it, and return an empty array.
127 if (Chunk >= PerChannelIndices[KeyChannelIndex].Chunks.Num())
128 {
130 }
131 return PerChannelIndices[KeyChannelIndex].Chunks[Chunk].Get<ElementIDType>(ChunkElement);
132 }
133
134
139
145
152
156 void Suspend() { bSuspended = true; }
157
161 void Resume()
162 {
163 bSuspended = false;
164 bEverythingStale = true;
165 }
166
171
176
177private:
178 // Ensure that the right number of per channel indices are allocated
179 MESHDESCRIPTION_API void UpdatePerChannelIndices();
180
181 // Incrementally builds the index based on the lists of stale keys and referencers
182 MESHDESCRIPTION_API void BuildIndex(int32 Index);
183
184 // Does a full rebuild of the index from scratch, directly from referencing attributes
185 MESHDESCRIPTION_API void RebuildIndex(int32 Index);
186
187 // Performs an incremental build if the specified key is stale
188 MESHDESCRIPTION_API void ConditionalBuild(int32 KeyIndex, int32 KeyChannelIndex);
189
190 // Add a reference to a key in unchunked mode
191 MESHDESCRIPTION_API void AddUnchunked(int32 KeyIndex, int32 ReferenceIndex, int32 KeyChannelIndex = 0);
192
193 // Return the chunk index relating to this key index
194 int32 GetChunkForKey(int32 ElementIndex) const
195 {
196 checkSlow(ElementIndex != INDEX_NONE);
197 return ElementIndex >> ChunkBits;
198 }
199
200 // Return the chunk element index relating to this key index
201 int32 GetChunkElementForKey(int32 ElementIndex) const
202 {
203 checkSlow(ElementIndex != INDEX_NONE);
204 return ElementIndex & ChunkMask;
205 }
206
207 // Return the currently configured chunk size
208 int32 GetChunkSize() const { return (1 << ChunkBits); }
209
210 // Return the number of chunks required to accommodate the specified number of keys
211 int32 GetNumChunksForKeys(int32 NumElements) const { return (NumElements + ChunkMask) >> ChunkBits; }
212
213
221 struct FChunk
222 {
223 FChunk(int32 InitialSize, int32 ChunkSize)
224 {
225 // Allocate the block which will contain the actual referencing elements
226 Data.SetNumUninitialized(ChunkSize * InitialSize, EAllowShrinking::No);
227
228 // Initialize indexing structures
229 StartIndex.SetNumUninitialized(ChunkSize);
230 Count.SetNumUninitialized(ChunkSize);
231 MaxCount.SetNumUninitialized(ChunkSize);
232
233 int32 N = 0;
234 for (int I = 0; I < ChunkSize; I++)
235 {
236 StartIndex[I] = N;
237 N += InitialSize;
238 }
239
240 for (int I = 0; I < ChunkSize; I++)
241 {
242 MaxCount[I] = InitialSize;
243 }
244
245 FMemory::Memzero(Count.GetData(), sizeof(int32) * ChunkSize);
246 }
247
249 bool Add(int32 Index, int32 Value);
250
252 bool AddUnsorted(int32 Index, int32 Value);
253
256
258 bool Contains(int32 Index, int32 Value) const;
259
261 void Sort(int32 Index);
262
265 {
266 // Build array view for the portion of the data array corresponding to this element
267 const int32* Ptr = Data.GetData() + StartIndex[Index];
268 return TArrayView<const int32>(Ptr, Count[Index]);
269 }
270
273 {
274 // Build array view for the portion of the data array corresponding to this element
275 static_assert(sizeof(ElementIDType) == sizeof(int32), "ElementIDType must be 32 bits long");
276 const ElementIDType* Ptr = reinterpret_cast<const ElementIDType*>(Data.GetData()) + StartIndex[Index];
277 return TArrayView<const ElementIDType>(Ptr, Count[Index]);
278 }
279
282
290 };
291
292 struct FIndexPerChannel
293 {
295 TArray<FChunk> Chunks;
296
298 TSet<int32> StaleKeyIndices;
299
301 TSet<int32> StaleReferencerIndices;
302 };
303
304 TArray<FIndexPerChannel> PerChannelIndices;
305
307 const FMeshElementChannels* ReferencedElementType;
308
311
313 int32 InitialSize = 1;
314
316 uint32 ChunkBits = 8;
317 uint32 ChunkMask = (1U << ChunkBits) - 1;
318
320 bool bSuspended = false;
321
323 bool bEverythingStale = true;
324};
325
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MeshElementContainer.h:367
Definition MeshElementIndexer.h:48
void SetUnchunked()
Definition MeshElementIndexer.h:85
MESHDESCRIPTION_API void Build()
Definition MeshElementIndexer.cpp:195
TArrayView< const ElementIDType > Find(int32 KeyIndex, int32 KeyChannelIndex=0)
Definition MeshElementIndexer.h:118
MESHDESCRIPTION_API void AddReferenceToKey(int32 KeyIndex, int32 ReferenceIndex, int32 KeyChannelIndex=0)
Definition MeshElementIndexer.cpp:119
TArrayView< const int32 > Find(int32 KeyIndex, int32 KeyChannelIndex=0)
Definition MeshElementIndexer.h:101
FMeshElementIndexer & operator=(FMeshElementIndexer &&)=default
FMeshElementIndexer()=default
MESHDESCRIPTION_API void Reset()
Definition MeshElementIndexer.cpp:34
MESHDESCRIPTION_API void ForceRebuild()
Definition MeshElementIndexer.cpp:50
MESHDESCRIPTION_API void RemoveKey(int32 KeyIndex, int32 KeyChannelIndex=0)
Definition MeshElementIndexer.cpp:58
void Resume()
Definition MeshElementIndexer.h:161
void SetInitialNumReferences(int InInitialSize)
Definition MeshElementIndexer.h:69
MESHDESCRIPTION_API void RemoveReferenceFromKey(int32 KeyIndex, int32 ReferenceIndex, int32 KeyChannelIndex=0)
Definition MeshElementIndexer.cpp:85
FMeshElementIndexer(FMeshElementIndexer &&)=default
void SetChunkSize(int InChunkSize)
Definition MeshElementIndexer.h:75
void Suspend()
Definition MeshElementIndexer.h:156
FMeshElementIndexer(const FMeshElementIndexer &)=delete
FMeshElementIndexer & operator=(const FMeshElementIndexer &)=delete
Definition NameTypes.h:617
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
Definition MeshAttributeArray.h:836
UE_REWRITE void Sort(RangeType &&Range)
Definition Sort.h:16
@ Count
Definition AudioMixerDevice.h:90
GeometryCollection::Facades::FMuscleActivationData Data
Definition MuscleActivationConstraints.h:15
@ Contains
Definition AutomationTest.h:160
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
U16 Index
Definition radfft.cpp:71
Definition MeshTypes.h:22
static UE_FORCEINLINE_HINT void * Memzero(void *Dest, SIZE_T Count)
Definition UnrealMemory.h:131