UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
DynamicMeshTriangleAttribute.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
7
8namespace UE
9{
10namespace Geometry
11{
12
13template<typename AttribValueType, int AttribDimension>
14class TDynamicMeshTriangleAttribute;
15
16
17template<typename AttribValueType, int AttribDimension>
19{
20private:
21 struct FChangeTriangleAttribute
22 {
24 int TriangleID;
25 };
26
27 TArray<FChangeTriangleAttribute> OldTriangleAttributes, NewTriangleAttributes;
28
29public:
32
35
36 inline virtual void SaveInitialTriangle(const FDynamicMeshAttributeBase* Attribute, int TriangleID) override;
37
38 inline virtual void StoreAllFinalTriangles(const FDynamicMeshAttributeBase* Attribute, const TArray<int>& TriangleIDs) override;
39
40 inline virtual bool Apply(FDynamicMeshAttributeBase* Attribute, bool bRevert) const override;
41};
42
43
44
52template<typename AttribValueType, int AttribDimension>
54{
55
56protected:
59
62
64
65 friend class FDynamicMesh3;
67
68public:
71 {
72 ParentMesh = nullptr;
73 }
74
84
85private:
87 void Reparent(FDynamicMesh3* ParentMeshIn)
88 {
90 }
91
92public:
94 const FDynamicMesh3* GetParentMesh() const { return ParentMesh; }
97
104
111
118
126
128 {
129 for (int TID = 0, NumTID = CompactMaps.NumTriangleMappings(); TID < NumTID; TID++)
130 {
131 const int ToTID = CompactMaps.GetTriangleMapping(TID);
133 {
134 continue;
135 }
136 if (ensure(ToTID <= TID))
137 {
139 }
140 }
142 }
143
145 {
147 check(CompactMaps.NumTriangleMappings() <= int(ToCopy.AttribValues.Num() / AttribDimension));
149 for (int TID = 0, NumTID = CompactMaps.NumTriangleMappings(); TID < NumTID; TID++)
150 {
151 const int ToTID = CompactMaps.GetTriangleMapping(TID);
153 {
154 continue;
155 }
156 ToCopy.GetValue(TID, Data);
157 SetValue(ToTID, Data);
158 }
159 }
160
161
164 {
165 check(ParentMesh != nullptr);
167 AttribValues.Fill(InitialValue);
168 }
169
171 {
173 for (int i = 0; i < AttribDimension; ++i)
174 {
175 AttribValues.InsertAt(Data[i], k + i);
176 }
177 }
178
179
180
181 //
182 // Accessors/Queries
183 //
184
185 virtual bool CopyThroughMapping(const TDynamicAttributeBase<FDynamicMesh3>* Source, const FMeshIndexMappings& Mapping) override
186 {
188 int BufferSize = sizeof(BufferData);
189 for (const TPair<int32, int32>& MapTID : Mapping.GetTriangleMap().GetForwardMap())
190 {
191 if (!ensure(Source->CopyOut(MapTID.Key, BufferData, BufferSize)))
192 {
193 return false;
194 }
195 SetValue(MapTID.Value, BufferData);
196 }
197 return true;
198 }
199
201 {
202 int32 NewMaxID = Info.NumTriangle + Info.TriangleOffset;
204 {
206 }
207
209 int BufferSize = sizeof(BufferData);
210 for (int32 Idx = 0; Idx < Info.NumTriangle; ++Idx)
211 {
212 if (!ensure(Source.CopyOut(Idx, BufferData, BufferSize)))
213 {
214 return false;
215 }
216 SetValue(Idx + Info.TriangleOffset, BufferData);
217 }
218 return true;
219 }
220
226
227 virtual bool CopyOut(int RawID, void* Buffer, int BufferSize) const override
228 {
229 if (sizeof(AttribValueType) * AttribDimension != BufferSize)
230 {
231 return false;
232 }
234 int k = RawID * AttribDimension;
235 for (int i = 0; i < AttribDimension; ++i)
236 {
237 BufferData[i] = AttribValues[k + i];
238 }
239 return true;
240 }
241 virtual bool CopyIn(int RawID, void* Buffer, int BufferSize) override
242 {
243 if (sizeof(AttribValueType) * AttribDimension != BufferSize)
244 {
245 return false;
246 }
248 int k = RawID * AttribDimension;
249 for (int i = 0; i < AttribDimension; ++i)
250 {
251 AttribValues[k + i] = BufferData[i];
252 }
253 return true;
254 }
255
257 inline void GetValue(int TriangleID, AttribValueType* Data) const
258 {
259 int k = TriangleID * AttribDimension;
260 for (int i = 0; i < AttribDimension; ++i)
261 {
262 Data[i] = AttribValues[k + i];
263 }
264 }
265
267 template<typename AsType>
268 void GetValue(int TriangleID, AsType& Data) const
269 {
270 int k = TriangleID * AttribDimension;
271 for (int i = 0; i < AttribDimension; ++i)
272 {
273 Data[i] = AttribValues[k + i];
274 }
275 }
276
277
279 inline void SetValue(int TriangleID, const AttribValueType* Data)
280 {
281 int k = TriangleID * AttribDimension;
282 for (int i = 0; i < AttribDimension; ++i)
283 {
284 AttribValues[k + i] = Data[i];
285 }
286 }
287
289 template<typename AsType>
290 void SetValue(int TriangleID, const AsType& Data)
291 {
292 int k = TriangleID * AttribDimension;
293 for (int i = 0; i < AttribDimension; ++i)
294 {
295 AttribValues[k + i] = Data[i];
296 }
297 }
298
300 inline void SetScalarValue(int TriangleID, const AttribValueType& SingleValue)
301 {
302 int k = TriangleID * AttribDimension;
303 for (int i = 0; i < AttribDimension; ++i)
304 {
305 AttribValues[k + i] = SingleValue;
306 }
307 }
308
313 {
316 for (int i = 0; i < AttribDimension; ++i)
317 {
319 }
320 }
321
322
324 bool IsBorderEdge(int EdgeID, bool bMeshBoundaryIsBorder = true) const
325 {
328 {
330 }
332 int kB = EdgeTris.B * AttribDimension;
333 for (int i = 0; i < AttribDimension; ++i)
334 {
335 if (AttribValues[kA+i] != AttribValues[kB+i])
336 {
337 return true;
338 }
339 }
340 return false;
341 }
342
343
348
349
350public:
351
354 {
355 CopyValue(SplitInfo.OriginalTriangles.A, SplitInfo.NewTriangles.A);
356 if (SplitInfo.OriginalTriangles.B != FDynamicMesh3::InvalidID)
357 {
358 CopyValue(SplitInfo.OriginalTriangles.B, SplitInfo.NewTriangles.B);
359 }
360 }
361
364 {
365 // yikes! triangles did not actually change so we will leave attrib unmodified
366 }
367
370 {
371 // nothing to do here, triangles were only deleted
372 }
373
376 {
377 CopyValue(PokeInfo.OriginalTriangle, PokeInfo.NewTriangles.A);
378 CopyValue(PokeInfo.OriginalTriangle, PokeInfo.NewTriangles.B);
379 }
380
383 {
384 // nothing to do here because triangles did not change
385 }
386
388 {
389 // This resolves as either an edge collapse, edge weld, or merge of disconnected vertices.
390 // The triangles either get removed or unchanged- nothing more to do here.
391 }
392
395 {
396 // nothing to do here because triangles did not change
397 }
398
400 {
401 return (AttribValueType)0;
402 }
403
404 inline void ResizeAttribStoreIfNeeded(int TriangleID)
405 {
406 if (!ensure(TriangleID >= 0))
407 {
408 return;
409 }
410 size_t NeededSize = (((size_t)TriangleID+1) * AttribDimension);
412 {
414 }
415 }
416
417 virtual void OnNewTriangle(int TriangleID, bool bInserted) override
418 {
419 ResizeAttribStoreIfNeeded(TriangleID);
421 }
422
423public:
428 {
429 if (!bIgnoreDataLayout)
430 {
431 if (AttribValues.Num() != Other.AttribValues.Num())
432 {
433 return false;
434 }
435
436 for (int Idx = 0, NumValues = AttribValues.Num(); Idx < NumValues; Idx++)
437 {
438 if (AttribValues[Idx] != Other.AttribValues[Idx])
439 {
440 return false;
441 }
442 }
443 }
444 else
445 {
448 FRefCountVector::IndexIterator ItTidOther = Other.ParentMesh->GetTrianglesRefCounts().BeginIndices();
449 const FRefCountVector::IndexIterator ItTidEndOther = Other.ParentMesh->GetTrianglesRefCounts().EndIndices();
450
451 while (ItTid != ItTidEnd && ItTidOther != ItTidEndOther)
452 {
453 for (int32 i = 0; i < AttribDimension; ++i)
454 {
458 {
459 // Triangle attribute value is not the same.
460 return false;
461 }
462 }
463 ++ItTid;
464 ++ItTidOther;
465 }
466
468 {
469 // Number of triangle attribute values is not the same.
470 return false;
471 }
472 }
473
474 return true;
475 }
476
485 {
486 Attr.Serialize(Ar, nullptr, false);
487 return Ar;
488 }
489
497 void Serialize(FArchive& Ar, const FCompactMaps* CompactMaps, bool bUseCompression)
498 {
500
502 if (Ar.IsLoading() && Ar.CustomVer(FUE5MainStreamObjectVersion::GUID) < FUE5MainStreamObjectVersion::DynamicMeshCompactedSerialization)
503 {
504 Ar << AttribValues;
505 }
506 else
507 {
508 auto SerializeVector = [](FArchive& Ar, auto& Vector, bool bUseCompression)
509 {
510 if (bUseCompression)
511 {
512 Vector.template Serialize<true, true>(Ar);
513 }
514 else
515 {
516 Vector.template Serialize<true, false>(Ar);
517 }
518 };
519
520 Ar << bUseCompression;
521
522 if (CompactMaps == nullptr || !CompactMaps->TriangleMapIsSet())
523 {
524 SerializeVector(Ar, AttribValues, bUseCompression);
525 }
526 else
527 {
530
531 int32 TidCompact = 0;
532 for (int32 Tid = 0, Num = AttribValues.Num() / AttribDimension; Tid < Num; ++Tid)
533 {
534 const int32 TidMapping = CompactMaps->GetTriangleMapping(Tid);
536 {
537 for (int32 i = 0; i < AttribDimension; ++i)
538 {
540 }
541 }
542 }
543
544 SerializeVector(Ar, AttribValuesCompact, bUseCompression);
545 }
546 }
547 }
548
549 virtual SIZE_T GetByteCount() const
550 {
551 return AttribValues.GetByteCount();
552 }
553};
554
555
556
557template<typename AttribValueType, int AttribDimension>
559{
560 FChangeTriangleAttribute& Change = OldTriangleAttributes.Emplace_GetRef();
561 Change.TriangleID = TriangleID;
563 AttribCast->GetValue(TriangleID, Change.Data);
564}
565
566template<typename AttribValueType, int AttribDimension>
568{
570 NewTriangleAttributes.Reserve(NewTriangleAttributes.Num() + TriangleIDs.Num());
571 for (int TriangleID : TriangleIDs)
572 {
573 FChangeTriangleAttribute& Change = NewTriangleAttributes.Emplace_GetRef();
574 Change.TriangleID = TriangleID;
575 AttribCast->GetValue(TriangleID, Change.Data);
576 }
577}
578
579template<typename AttribValueType, int AttribDimension>
581{
583 const TArray<FChangeTriangleAttribute> *Changes = bRevert ? &OldTriangleAttributes : &NewTriangleAttributes;
584 for (const FChangeTriangleAttribute& Change : *Changes)
585 {
586 bool bIsTriangle = AttribCast->GetParentMesh()->IsTriangle(Change.TriangleID);
588 if (bIsTriangle)
589 {
590 AttribCast->SetValue(Change.TriangleID, Change.Data);
591 }
592 }
593 return true;
594}
595
596
597
602template<typename RealType>
604{
605public:
608 using BaseType::GetValue;
609 using BaseType::SetValue;
610
614
618
619 inline void SetNewValue(int NewTriangleID, RealType Value)
620 {
621 this->AttribValues.InsertAt(Value, NewTriangleID);
622 }
623
624 inline RealType GetValue(int TriangleID) const
625 {
626 return this->AttribValues[TriangleID];
627 }
628
629 inline void SetValue(int TriangleID, RealType Value)
630 {
631 this->AttribValues[TriangleID] = Value;
632 }
633};
634
635
636} // end namespace UE::Geometry
637} // end namespace UE
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
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
@ Num
Definition MetalRHIPrivate.h:234
Definition Archive.h:1208
virtual CORE_API void UsingCustomVersion(const struct FGuid &Guid)
Definition Archive.cpp:590
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
CORE_API int32 CustomVer(const struct FGuid &Key) const
Definition Archive.cpp:602
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
Definition UniquePtr.h:107
Definition CompactMaps.h:20
static constexpr int32 InvalidID
Definition CompactMaps.h:25
Definition DynamicMesh3.h:108
int MaxTriangleID() const
Definition DynamicMesh3.h:399
const FRefCountVector & GetTrianglesRefCounts() const
Definition DynamicMesh3.h:1292
int TriangleCount() const
Definition DynamicMesh3.h:383
FIndex2i GetEdgeT(int EdgeID) const
Definition DynamicMesh3.h:882
static constexpr int InvalidID
Definition DynamicMesh3.h:158
Definition DynamicMeshAttributeSet.h:84
Definition DynamicMeshTriangleAttribute.h:19
virtual void StoreAllFinalTriangles(const FDynamicMeshAttributeBase *Attribute, const TArray< int > &TriangleIDs) override
Definition DynamicMeshTriangleAttribute.h:567
virtual ~FDynamicMeshTriangleAttributeChange()
Definition DynamicMeshTriangleAttribute.h:33
virtual bool Apply(FDynamicMeshAttributeBase *Attribute, bool bRevert) const override
Definition DynamicMeshTriangleAttribute.h:580
FDynamicMeshTriangleAttributeChange()
Definition DynamicMeshTriangleAttribute.h:30
virtual void SaveInitialTriangle(const FDynamicMeshAttributeBase *Attribute, int TriangleID) override
Definition DynamicMeshTriangleAttribute.h:558
Definition RefCountVector.h:403
IndexIterator BeginIndices() const
Definition RefCountVector.h:430
IndexIterator EndIndices() const
Definition RefCountVector.h:435
Definition DynamicAttribute.h:67
virtual void CopyParentClassData(const TDynamicAttributeBase< ParentType > &Other)
Definition DynamicAttribute.h:249
void Serialize(FArchive &Ar)
Definition DynamicAttribute.h:231
Definition DynamicAttribute.h:24
Definition DynamicMeshTriangleAttribute.h:604
TDynamicMeshScalarTriangleAttribute()
Definition DynamicMeshTriangleAttribute.h:611
RealType GetValue(int TriangleID) const
Definition DynamicMeshTriangleAttribute.h:624
TDynamicMeshScalarTriangleAttribute(FDynamicMesh3 *ParentMeshIn)
Definition DynamicMeshTriangleAttribute.h:615
void SetNewValue(int NewTriangleID, RealType Value)
Definition DynamicMeshTriangleAttribute.h:619
void SetValue(int TriangleID, RealType Value)
Definition DynamicMeshTriangleAttribute.h:629
Definition DynamicMeshTriangleAttribute.h:54
void CompactInPlace(const FCompactMaps &CompactMaps)
Definition DynamicMeshTriangleAttribute.h:127
virtual bool CopyThroughMapping(const TDynamicAttributeBase< FDynamicMesh3 > *Source, const FMeshIndexMappings &Mapping) override
Definition DynamicMeshTriangleAttribute.h:185
void GetValue(int TriangleID, AsType &Data) const
Definition DynamicMeshTriangleAttribute.h:268
TDynamicMeshTriangleAttribute()
Definition DynamicMeshTriangleAttribute.h:70
void OnCollapseEdge(const DynamicMeshInfo::FEdgeCollapseInfo &CollapseInfo) override
Definition DynamicMeshTriangleAttribute.h:369
FDynamicMesh3 * GetParentMesh()
Definition DynamicMeshTriangleAttribute.h:96
void OnSplitVertex(const DynamicMeshInfo::FVertexSplitInfo &SplitInfo, const TArrayView< const int > &TrianglesToUpdate) override
Definition DynamicMeshTriangleAttribute.h:394
void CompactCopy(const FCompactMaps &CompactMaps, const TDynamicMeshTriangleAttribute< AttribValueType, AttribDimension > &ToCopy)
Definition DynamicMeshTriangleAttribute.h:144
void SetValue(int TriangleID, const AsType &Data)
Definition DynamicMeshTriangleAttribute.h:290
void OnPokeTriangle(const DynamicMeshInfo::FPokeTriangleInfo &PokeInfo) override
Definition DynamicMeshTriangleAttribute.h:375
bool IsBorderEdge(int EdgeID, bool bMeshBoundaryIsBorder=true) const
Definition DynamicMeshTriangleAttribute.h:324
void OnSplitEdge(const DynamicMeshInfo::FEdgeSplitInfo &SplitInfo) override
Definition DynamicMeshTriangleAttribute.h:353
void OnMergeEdges(const DynamicMeshInfo::FMergeEdgesInfo &MergeInfo) override
Definition DynamicMeshTriangleAttribute.h:382
void GetValue(int TriangleID, AttribValueType *Data) const
Definition DynamicMeshTriangleAttribute.h:257
void CopyValue(int FromTriangleID, int ToTriangleID)
Definition DynamicMeshTriangleAttribute.h:312
void OnFlipEdge(const DynamicMeshInfo::FEdgeFlipInfo &FlipInfo) override
Definition DynamicMeshTriangleAttribute.h:363
FDynamicMesh3 * ParentMesh
Definition DynamicMeshTriangleAttribute.h:58
TDynamicVector< AttribValueType > AttribValues
Definition DynamicMeshTriangleAttribute.h:61
virtual SIZE_T GetByteCount() const
Definition DynamicMeshTriangleAttribute.h:549
void SetNewValue(int NewTriangleID, const AttribValueType *Data)
Definition DynamicMeshTriangleAttribute.h:170
TDynamicMeshTriangleAttribute(FDynamicMesh3 *ParentMeshIn, bool bAutoInit=true)
Definition DynamicMeshTriangleAttribute.h:76
void Copy(const TDynamicMeshTriangleAttribute< AttribValueType, AttribDimension > &Copy)
Definition DynamicMeshTriangleAttribute.h:113
const FDynamicMesh3 * GetParentMesh() const
Definition DynamicMeshTriangleAttribute.h:94
virtual void AppendDefaulted(const UE::Geometry::FDynamicMesh3::FAppendInfo &Info) override
Definition DynamicMeshTriangleAttribute.h:221
void SetValue(int TriangleID, const AttribValueType *Data)
Definition DynamicMeshTriangleAttribute.h:279
friend FArchive & operator<<(FArchive &Ar, TDynamicMeshTriangleAttribute< AttribValueType, AttribDimension > &Attr)
Definition DynamicMeshTriangleAttribute.h:484
virtual FDynamicMeshAttributeBase * MakeNew(FDynamicMesh3 *ParentMeshIn) const override
Definition DynamicMeshTriangleAttribute.h:98
virtual bool Append(const TDynamicAttributeBase &Source, const UE::Geometry::FDynamicMesh3::FAppendInfo &Info) override
Definition DynamicMeshTriangleAttribute.h:200
void Serialize(FArchive &Ar, const FCompactMaps *CompactMaps, bool bUseCompression)
Definition DynamicMeshTriangleAttribute.h:497
virtual bool CopyIn(int RawID, void *Buffer, int BufferSize) override
Definition DynamicMeshTriangleAttribute.h:241
void SetScalarValue(int TriangleID, const AttribValueType &SingleValue)
Definition DynamicMeshTriangleAttribute.h:300
virtual bool CopyOut(int RawID, void *Buffer, int BufferSize) const override
Definition DynamicMeshTriangleAttribute.h:227
virtual FDynamicMeshAttributeBase * MakeCompactCopy(const FCompactMaps &CompactMaps, FDynamicMesh3 *ParentMeshIn) const override
Definition DynamicMeshTriangleAttribute.h:119
virtual void OnNewTriangle(int TriangleID, bool bInserted) override
Definition DynamicMeshTriangleAttribute.h:417
void ResizeAttribStoreIfNeeded(int TriangleID)
Definition DynamicMeshTriangleAttribute.h:404
virtual AttribValueType GetDefaultAttributeValue()
Definition DynamicMeshTriangleAttribute.h:399
void OnMergeVertices(const DynamicMeshInfo::FMergeVerticesInfo &MergeInfo) override
Definition DynamicMeshTriangleAttribute.h:387
virtual TUniquePtr< FDynamicMeshAttributeChangeBase > NewBlankChange() const override
Definition DynamicMeshTriangleAttribute.h:344
void Initialize(AttribValueType InitialValue=(AttribValueType) 0)
Definition DynamicMeshTriangleAttribute.h:163
virtual FDynamicMeshAttributeBase * MakeCopy(FDynamicMesh3 *ParentMeshIn) const override
Definition DynamicMeshTriangleAttribute.h:105
bool IsSameAs(const TDynamicMeshTriangleAttribute< AttribValueType, AttribDimension > &Other, bool bIgnoreDataLayout) const
Definition DynamicMeshTriangleAttribute.h:427
Definition DynamicVector.h:27
size_t GetByteCount() const
Definition DynamicVector.h:149
void InsertAt(const Type &Data, unsigned int Index)
Definition DynamicVector.h:747
bool SetMinimumSize(unsigned int Count, const Type &InitValue)
Resize if Num() is less than Count; returns true if resize occurred.
Definition DynamicVector.h:646
size_t Num() const
Definition DynamicVector.h:147
void Resize(unsigned int Count)
Definition DynamicVector.h:603
void Fill(const Type &Value)
Definition DynamicVector.h:590
void SetNum(unsigned int Count)
Definition DynamicVector.h:143
TDynamicAttributeBase< FDynamicMesh3 > FDynamicMeshAttributeBase
Definition DynamicAttribute.h:256
Definition AdvancedWidgetsModule.cpp:13
Definition InfoTypes.h:181
Definition InfoTypes.h:171
Definition InfoTypes.h:155
Definition InfoTypes.h:197
Definition InfoTypes.h:216
Definition InfoTypes.h:229
Definition InfoTypes.h:242
CORE_API static const FGuid GUID
Definition UE5MainStreamObjectVersion.h:22
Definition Tuple.h:652
Definition DynamicMesh3.h:309
Definition IndexTypes.h:27
int A
Definition IndexTypes.h:32
Definition MeshIndexMappings.h:22
FIndexMapi & GetTriangleMap()
Definition MeshIndexMappings.h:66
TMap< IntType, IntType > & GetForwardMap()
Definition GeometryTypes.h:119