UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ToDynamicMesh.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
11#include "VectorTypes.h"
12#include "Async/Async.h"
13
14namespace UE
15{
16namespace Geometry
17{
18
19
47template<typename SrcMeshType>
49{
50public:
51
52 using SrcVertIDType = typename SrcMeshType::VertIDType;
53 using SrcTriIDType = typename SrcMeshType::TriIDType;
54
55
57 {
58 }
59
60
61 // Mapping data captured by conversion
64
67
68 // Produces a DynamicMesh3 w/o attributes from the MeshIn.
70 {
71 MeshOut.Clear();
72 MeshOut.DiscardAttributes();
73
74 MeshOut.EnableTriangleGroups(0);
75
78
79 const int32 NumSrcVerts = MeshIn.NumVerts();
80 const int32 NumSrcTris = MeshIn.NumTris();
81
82 if (NumSrcVerts == 0 || NumSrcTris == 0)
83 {
84 return;
85 }
86 // allocate for map data
87
90 // copy vertex positions. Later we may have to append duplicate vertices to resolve non-manifold structures.
92 for (const SrcVertIDType& SrcVertID : MeshIn.GetVertIDs())
93 {
94 const FVector3d Position = MeshIn.GetPosition(SrcVertID);
95 const int32 DstVertID = MeshOut.AppendVertex(Position);
97
99 }
100 // map the other direction
103 for (int32 i = 0; i < ToSrcVertIDMap.Num(); ++i)
104 {
107 }
108
110
111 // copy the index buffer. Note, this may add vertices if a non-manifold state has to be resolved.
112 for (const SrcTriIDType& SrcTriID : MeshIn.GetTriIDs())
113 {
114
116
119
123
124 // attemp to add tri. this may fail if DynamicMesh is more topologically restrictive than the src mesh.
126
127 //-- already seen this triangle for some reason.. or the src mesh had a degenerate tri
129 {
130 continue;
131 }
132
133 //-- non manifold
134 // if append failed due to non-manifold, duplicate verts
136 {
137 // determine which verts need to be duplicated
138 bool bDuplicate[3] = { false, false, false };
139 for (int i = 0; i < 3; ++i)
140 {
141 int ii = (i + 1) % 3;
142 int EID = MeshOut.FindEdge(DstTriVerts[i], DstTriVerts[ii]);
143 if (EID != FDynamicMesh3::InvalidID && MeshOut.IsBoundaryEdge(EID) == false)
144 {
145 bDuplicate[i] = true;
146 bDuplicate[ii] = true;
147 }
148 }
149 for (int i = 0; i < 3; ++i)
150 {
151 if (bDuplicate[i])
152 {
153 const FVector3d Position = MeshOut.GetVertex(DstTriVerts[i]);
154 const int32 NewDstVertID = MeshOut.AppendVertex(Position);
156 // grow the map to make room
158
160 }
161 }
162
163 // add the fixed tri
164 DstTriangleID = MeshOut.AppendTriangle(DstTriVerts, DstGroupID);
166 }
167
168 // record in map
170 }
171
172 const int32 MaxDstTriID = MeshOut.MaxTriangleID(); // really MaxTriID+1
173 // if the source mesh had duplicates then TriIDMap will be too long, this will trim excess
176 }
177};
178
179
180// Used for exact attribute value welding.
181template <typename AttrType>
183{
184 int VID;
185 AttrType AttrValue;
186 bool operator==(const TVertexAttr& o) const
187 {
188 return VID == o.VID && AttrValue == o.AttrValue;
189 }
190};
191
192template <typename AttrType>
194{
195 // ugh copied from FVector clearly should not be using CRC for hash!!
196 return FCrc::MemCrc32(&Vector, sizeof(Vector));
197}
198
199template <typename AttrType> struct TOverlayTraits {};
203
204// Welder used for exact attribute value welding when constructing overlay
205template <typename AttrType>
207{
208public:
211
214
215 TAttrWelder() : Overlay(nullptr){}
216
222
223 int FindOrAddUnique(const AttrType& AttrValue, int VertexID)
224 {
225 FVertexAttr VertAttr = { VertexID, AttrValue };
226
227 const int32* FoundIndex = UniqueVertexAttrs.Find(VertAttr);
228 if (FoundIndex != nullptr)
229 {
230 return *FoundIndex;
231 }
232
233 int32 NewIndex = Overlay->AppendElement(AttrValue);
234 UniqueVertexAttrs.Add(VertAttr, NewIndex);
235 return NewIndex;
236 }
237};
238
328template <typename SrcMeshType>
329class TToDynamicMesh : public TToDynamicMeshBase<SrcMeshType>
330{
331public:
335 using SrcUVIDType = typename SrcMeshType::UVIDType;
336 using SrcNormalIDType = typename SrcMeshType::NormalIDType;
337 using SrcColorIDType = typename SrcMeshType::ColorIDType;
338 using SrcWedgeIDType = typename SrcMeshType::WedgeIDType;
339
341
342
343
344 // Convert To FDynamicMesh w/o attributes
351
352
353 // Convert To FDynamicMesh. Will Copy GroupID to the mesh, and will create overlays with UVs, Normal, MaterialID (additionally Tangents and BiTangents if requested)
355 const SrcMeshType& MeshIn,
358 bool bCopyTangents)
359 {
360
361 MyBase::Convert(MeshOut, MeshIn, GroupIDFunction); // convert the mesh. Must call before populate overlays
362 PopulateOverlays(MeshOut, MeshIn, MaterialIDFunction, bCopyTangents); // convert the attributes
363 }
364
365protected:
366
367
368 // Populates overlays for UVs, Normal, Color, Material ID. Also Tangent and BiTangent if bCopyTangents == true.
369 // NB: This does not copy any polygroup information.
371 {
372 // Attributes we want to transfer
373 FDynamicMeshNormalOverlay* NormalOverlay = nullptr;
376 FDynamicMeshColorOverlay* ColorOverlay = nullptr;
377 FDynamicMeshMaterialAttribute* MaterialIDAttrib = nullptr;
378
379 // only copy tangents if they exist
380 bCopyTangents = bCopyTangents && MeshIn.HasTangents() && MeshIn.HasBiTangents();
381
382 // -- Create Overlays
383 const int32 NumUVLayers = MeshIn.NumUVLayers();
384
385 MeshOut.EnableAttributes(); // by default 1-UV layer and 1-normal layer
386
387 // create any addition Normal overlays and reserve space.
389 if (MeshOut.Attributes()->NumNormalLayers() < NumRequiredNormalLayers)
390 {
391 MeshOut.Attributes()->SetNumNormalLayers(NumRequiredNormalLayers);
392 }
393 for (int32 i = 0; i < NumRequiredNormalLayers; ++i)
394 {
395 MeshOut.Attributes()->GetNormalLayer(i)->InitializeTriangles(MeshOut.MaxTriangleID());
396 }
397
398 NormalOverlay = MeshOut.Attributes()->PrimaryNormals();
399 if (bCopyTangents)
400 {
401 TangentOverlay = MeshOut.Attributes()->PrimaryTangents();
402 BiTangentOverlay = MeshOut.Attributes()->PrimaryBiTangents();
403 }
404
405 // create UV overlays
406 MeshOut.Attributes()->SetNumUVLayers(FMath::Max(1, NumUVLayers));
407 // reserve space in any new UV layers.
408 for (int32 i = 1; i < NumUVLayers; ++i) //-V654 //-V621 (The static analyzer complains if it knows NumUVLayers is 0 for a given SrcMeshType)
409 {
410 MeshOut.Attributes()->GetUVLayer(i)->InitializeTriangles(MeshOut.MaxTriangleID());
411 }
412
413 // create color overlay
414 if (MeshIn.HasColors())
415 {
416 MeshOut.Attributes()->EnablePrimaryColors();
417 ColorOverlay = MeshOut.Attributes()->PrimaryColors();
418 ColorOverlay->InitializeTriangles(MeshOut.MaxTriangleID());
419 }
420
421 // always enable Material ID if there are any attributes
422 MeshOut.Attributes()->EnableMaterialID();
423 MaterialIDAttrib = MeshOut.Attributes()->GetMaterialID();
424
425 // do the conversions.
426 // we will populate all the attributes simultaneously, hold on to futures in this array and then Wait for them at the end
428
429
430
431 // populate UV overlays
432 for (int UVLayerIndex = 0; UVLayerIndex < NumUVLayers; UVLayerIndex++) //-V654 //-V621 (The static analyzer complains if it knows NumUVLayers is 0 for a given SrcMeshType)
433 {
434 auto UVFuture = Async(EAsyncExecution::ThreadPool, [&, UVLayerIndex]()
435 {
436 FDynamicMeshUVOverlay* Overlay = MeshOut.Attributes()->GetUVLayer(UVLayerIndex);
437
439 Overlay,
440 MeshIn.GetUVIDs(UVLayerIndex),
441 [&MeshIn, UVLayerIndex](const SrcUVIDType& UVID)->FVector2f { return MeshIn.GetUV(UVLayerIndex, UVID); },
442 [&MeshIn, UVLayerIndex](const SrcTriIDType& TriID, SrcUVIDType& UV0, SrcUVIDType& UV1, SrcUVIDType& UV2)->bool {return MeshIn.GetUVTri(UVLayerIndex, TriID, UV0, UV1, UV2); },
443 [&MeshIn, UVLayerIndex](const SrcWedgeIDType& WID)->FVector2f {return MeshIn.GetWedgeUV(UVLayerIndex, WID); },
444 [&MeshIn](const SrcTriIDType& TriID, SrcWedgeIDType& WID0, SrcWedgeIDType& WID1, SrcWedgeIDType& WID2)->void { MeshIn.GetWedgeIDs(TriID, WID0, WID1, WID2); }
445 );
446 });
448 }
449 // populate Normal overlay
450 if (NormalOverlay != nullptr)
451 {
453 {
455 NormalOverlay,
456 MeshIn.GetNormalIDs(),
457 [&MeshIn](const SrcNormalIDType& NID)->FVector3f { return MeshIn.GetNormal(NID); },
458 [&MeshIn](const SrcTriIDType& TriID, SrcNormalIDType& N0, SrcNormalIDType& N1, SrcNormalIDType& N2)->bool {return MeshIn.GetNormalTri(TriID, N0, N1, N2); },
459 [&MeshIn](const SrcWedgeIDType& WID)->FVector3f {return MeshIn.GetWedgeNormal(WID); },
460 [&MeshIn](const SrcTriIDType& TriID, SrcWedgeIDType& WID0, SrcWedgeIDType& WID1, SrcWedgeIDType& WID2)->void { MeshIn.GetWedgeIDs(TriID, WID0, WID1, WID2); }
461 );
462 });
464 }
465 // populate Tangent overlay
466 if (TangentOverlay != nullptr)
467 {
469 {
472 MeshIn.GetTangentIDs(),
473 [&MeshIn](const SrcNormalIDType& NID)->FVector3f { return MeshIn.GetTangent(NID); },
474 [&MeshIn](const SrcTriIDType& TriID, SrcNormalIDType& N0, SrcNormalIDType& N1, SrcNormalIDType& N2)->bool {return MeshIn.GetTangentTri(TriID, N0, N1, N2); },
475 [&MeshIn](const SrcWedgeIDType& WID)->FVector3f {return MeshIn.GetWedgeTangent(WID); },
476 [&MeshIn](const SrcTriIDType& TriID, SrcWedgeIDType& WID0, SrcWedgeIDType& WID1, SrcWedgeIDType& WID2)->void { MeshIn.GetWedgeIDs(TriID, WID0, WID1, WID2); }
477 );
478 });
480 }
481 //populate BiTangent overlay
482 if (BiTangentOverlay != nullptr)
483 {
485 {
488 MeshIn.GetBiTangentIDs(),
489 [&MeshIn](const SrcNormalIDType& NID)->FVector3f { return MeshIn.GetBiTangent(NID); },
490 [&MeshIn](const SrcTriIDType& TriID, SrcNormalIDType& N0, SrcNormalIDType& N1, SrcNormalIDType& N2)->bool {return MeshIn.GetBiTangentTri(TriID, N0, N1, N2); },
491 [&MeshIn](const SrcWedgeIDType& WID)->FVector3f {return MeshIn.GetWedgeBiTangent(WID); },
492 [&MeshIn](const SrcTriIDType& TriID, SrcWedgeIDType& WID0, SrcWedgeIDType& WID1, SrcWedgeIDType& WID2)->void { MeshIn.GetWedgeIDs(TriID, WID0, WID1, WID2); }
493 );
494
495 });
497 }
498 if (ColorOverlay != nullptr)
499 {
501 {
503 ColorOverlay,
504 MeshIn.GetColorIDs(),
505 [&MeshIn](const SrcColorIDType& CID)->FVector4f { return MeshIn.GetColor(CID); },
506 [&MeshIn](const SrcTriIDType& TriID, SrcColorIDType& C0, SrcColorIDType& C1, SrcColorIDType& C2)->bool {return MeshIn.GetColorTri(TriID, C0, C1, C2); },
507 [&MeshIn](const SrcWedgeIDType& WID)->FVector4f {return MeshIn.GetWedgeColor(WID); },
508 [&MeshIn](const SrcTriIDType& TriID, SrcWedgeIDType& WID0, SrcWedgeIDType& WID1, SrcWedgeIDType& WID2)->void { MeshIn.GetWedgeIDs(TriID, WID0, WID1, WID2); }
509 );
510
511 });
513 }
514
515 //populate MaterialID overlay
516 if (MaterialIDAttrib != nullptr)
517 {
519 {
520 for (int32 TriangleID : MeshOut.TriangleIndicesItr())
521 {
523 MaterialIDAttrib->SetValue(TriangleID, MaterialIDFunction(SrcTriID));
524 }
525 });
527 }
528
529 //populate WeightMap attribute
530 const int32 NumWeightMaps = MeshIn.NumWeightMapLayers();
531 MeshOut.Attributes()->SetNumWeightLayers(NumWeightMaps);
532 for (int WeightMapIndex = 0; WeightMapIndex < NumWeightMaps; WeightMapIndex++) //-V654 //-V621 (The static analyzer complains if it knows NumWeightMaps is 0 for a given SrcMeshType)
533 {
535 {
536 FDynamicMeshWeightAttribute* WeightMapAttrib = MeshOut.Attributes()->GetWeightLayer(WeightMapIndex);
537
538 for (int32 VertexID : MeshOut.VertexIndicesItr())
539 {
541 float Weight = MeshIn.GetVertexWeight(WeightMapIndex, SrcVertID);
542 WeightMapAttrib->SetValue(VertexID, &Weight);
543 }
544
545 WeightMapAttrib->SetName( MeshIn.GetWeightMapName(WeightMapIndex) );
546 });
548 }
549
550
551 // populate skinning weight attribute
552 const int32 NumSkinWeightAttributes = MeshIn.NumSkinWeightAttributes();
553
554 // first, attach all the skinning weight attributes (this also allocates memory to store skinning weights for each attribute)
555 for (int AttributeIndex = 0; AttributeIndex < NumSkinWeightAttributes; ++AttributeIndex) //-V621 //-V654
556 {
558 const FName AttribName = MeshIn.GetSkinWeightAttributeName(AttributeIndex);
559 Attribute->SetName(AttribName);
560 MeshOut.Attributes()->AttachSkinWeightsAttribute(AttribName, Attribute);
561 }
562
563 // now set all of the skin weight data
564 for (int AttributeIndex = 0; AttributeIndex < NumSkinWeightAttributes; ++AttributeIndex) //-V621
565 {
566 auto SkinAttributeFeature = Async(EAsyncExecution::ThreadPool, [this, &MeshIn, &MeshOut, AttributeIndex]()
567 {
568 const FName AttribName = MeshIn.GetSkinWeightAttributeName(AttributeIndex);
569
571 checkSlow(OutAttribute != nullptr);
572
573 if (OutAttribute)
574 {
575 for (int32 VertexID : MeshOut.VertexIndicesItr())
576 {
578 UE::AnimationCore::FBoneWeights SkinWeight = MeshIn.GetVertexSkinWeight(AttributeIndex, SrcVertID);
579 OutAttribute->SetValue(VertexID, SkinWeight);
580 }
581 }
582 });
584 }
585
586 // populate bones attribute
587 const int NumBones = MeshIn.GetNumBones();
588 if (MeshIn.GetNumBones())
589 {
590 MeshOut.Attributes()->EnableBones(NumBones);
591 FDynamicMeshBoneNameAttribute* BoneNameAttrib = MeshOut.Attributes()->GetBoneNames();
592 FDynamicMeshBoneParentIndexAttribute* BoneParentIndices = MeshOut.Attributes()->GetBoneParentIndices();
593 FDynamicMeshBonePoseAttribute* BonePoses = MeshOut.Attributes()->GetBonePoses();
594 FDynamicMeshBoneColorAttribute* BoneColors = MeshOut.Attributes()->GetBoneColors();
595
597 {
598 for (int32 BoneIdx = 0; BoneIdx < NumBones; ++BoneIdx)
599 {
600 BoneNameAttrib->SetValue(BoneIdx, MeshIn.GetBoneName(BoneIdx));
601 BoneParentIndices->SetValue(BoneIdx, MeshIn.GetBoneParentIndex(BoneIdx));
602 BonePoses->SetValue(BoneIdx, MeshIn.GetBonePose(BoneIdx));
603 BoneColors->SetValue(BoneIdx, MeshIn.GetBoneColor(BoneIdx));
604 }
605 });
607 }
608
609 // TODO: PolyGroup layers
610
611 // wait for all work to be done
612 for (TFuture<void>& Future : Pending)
613 {
614 Future.Wait();
615 }
616 }
617
618
619 // Access the attributes in the Source Mesh on a per-wedge granularity (each corner of each triangle is a wedge), and weld them based on strict equality when creating the overlay.
620 template<typename AttrType>
624 bool bWeldIdenticalAttrs = true)
625 {
626
627 FDynamicMesh3& MeshOut = *Overlay->GetParentMesh();
629
630 for (int32 TriangleID : MeshOut.TriangleIndicesItr())
631 {
632 // skip overlay triangles that a prior method has populated.
633 // NB: this function may have been called after PopulateOverlayFromSharedAttr
634 if (Overlay->IsSetTriangle(TriangleID))
635 {
636 continue;
637 }
638
639 const SrcTriIDType& SrcTriID = MyBase::ToSrcTriIDMap[TriangleID];
640
642 TriToWedges(SrcTriID, WID[0], WID[1], WID[2]);
643
644 FIndex3i Tri = MeshOut.GetTriangle(TriangleID);
646 for (int j = 0; j < 3; ++j)
647 {
648 const AttrType& AttrValue = WedgeAttrs(WID[j]);
650 {
651 AttrTri[j] = AttrWelder.FindOrAddUnique(AttrValue, Tri[j]);
652 }
653 else
654 {
655 AttrTri[j] = Overlay->AppendElement(AttrValue);
656 }
657 }
658 Overlay->SetTriangle(TriangleID, AttrTri);
659 }
660 }
661
662
663 template <typename AttrType, typename SrcAttrIDType>
668 {
669 FDynamicMesh3& MeshOut = *Overlay->GetParentMesh();
670
671 // return if no shared attributes.
672 if (SrcAttrIDs.Num() == 0)
673 {
674 return;
675 }
676
677
678 int32 MaxSrcAttrID = -1;
679 for (const SrcAttrIDType& SrcAttrID : SrcAttrIDs)
680 {
682 }
685 // copy attr values into the overlay - these are vertices in the attr mesh.
686 for (const SrcAttrIDType& SrcAttrID : SrcAttrIDs)
687 {
688 const AttrType AttrValue = SharedAttrValues(SrcAttrID);
689 const int32 NewIndex = Overlay->AppendElement(AttrValue);
691 FromSrcAttrIDMap[SrcAttrID32] = NewIndex;
692 }
693
694 // use the attr index buffer to make triangles in the overlay
695 for (int32 TriID : MeshOut.TriangleIndicesItr())
696 {
700
701 if (!bHasValidAttrTri)
702 {
703 // don't set this tri in the overlay
704 continue;
705 }
706
707 // translate to Overlay indicies
711
713 {
714 // MeshIn may attach multiple mesh vertices to the same attribute element. DynamicMesh does not.
715 // if we have already used this element for a different mesh vertex, split it.
716 const FIndex3i ParentTriangle = MeshOut.GetTriangle(TriID);
717 for (int i = 0; i < 3; ++i)
718 {
719 int32 ParentVID = Overlay->GetParentVertex(AttrTri[i]);
721 {
722 const AttrType AttrValue = SharedAttrValues(SrcAttrTri[i]);
723 AttrTri[i] = Overlay->AppendElement(AttrValue);
724 }
725 }
726
727 // MeshIn may have degenerate attr tris. Dynamic Mesh does not.
728 // if the attr tri is degenerate we split the degenerate attr edge by adding two new attrs
729 // in its place, or if it is totally degenerate we add 3 new attrs
730
731 if (AttrTri[0] == AttrTri[1] && AttrTri[0] == AttrTri[2])
732 {
733 const AttrType AttrValue = SharedAttrValues(SrcAttrTri[0]);
734 AttrTri[0] = Overlay->AppendElement(AttrValue);
735 AttrTri[1] = Overlay->AppendElement(AttrValue);
736 AttrTri[2] = Overlay->AppendElement(AttrValue);
737
738 }
739 else
740 {
741 if (AttrTri[0] == AttrTri[1])
742 {
743 const AttrType AttrValue = SharedAttrValues(SrcAttrTri[0]);
744 AttrTri[0] = Overlay->AppendElement(AttrValue);
745 AttrTri[1] = Overlay->AppendElement(AttrValue);
746 }
747 if (AttrTri[0] == AttrTri[2])
748 {
749 const AttrType AttrValue = SharedAttrValues(SrcAttrTri[0]);
750 AttrTri[0] = Overlay->AppendElement(AttrValue);
751 AttrTri[2] = Overlay->AppendElement(AttrValue);
752 }
753 if (AttrTri[1] == AttrTri[2])
754 {
755 const AttrType AttrValue = SharedAttrValues(SrcAttrTri[1]);
756 AttrTri[1] = Overlay->AppendElement(AttrValue);
757 AttrTri[2] = Overlay->AppendElement(AttrValue);
758 }
759 }
760 }
761
762 // set the triangle in the overlay
763 Overlay->SetTriangle(TriID, AttrTri);
764
765 }
766 }
767
768 template <typename AttrType, typename SrcAttrIDType>
780};
781
782} } // end namespace UE::Geometry
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
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
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition NameTypes.h:617
Definition Array.h:670
UE_FORCEINLINE_HINT SizeType AddUninitialized()
Definition Array.h:1664
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Reset(SizeType NewSize=0)
Definition Array.h:2246
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
void Init(const ElementType &Element, SizeType Number)
Definition Array.h:3043
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
Definition AssetRegistryState.h:50
Definition Future.h:393
Definition UnrealString.h.inl:34
A simple container for per-vertex influence of bones and their weights.
Definition BoneWeights.h:526
Definition DynamicMesh3.h:108
static constexpr int NonManifoldID
Definition DynamicMesh3.h:160
static constexpr int DuplicateTriangleID
Definition DynamicMesh3.h:162
static constexpr int InvalidID
Definition DynamicMesh3.h:158
Definition ToDynamicMesh.h:207
typename TOverlayTraits< AttrType >::OverlayType OverlayType
Definition ToDynamicMesh.h:209
OverlayType * Overlay
Definition ToDynamicMesh.h:213
TAttrWelder()
Definition ToDynamicMesh.h:215
TMap< FVertexAttr, int > UniqueVertexAttrs
Definition ToDynamicMesh.h:212
int FindOrAddUnique(const AttrType &AttrValue, int VertexID)
Definition ToDynamicMesh.h:223
TAttrWelder(OverlayType *OverlayIn)
Definition ToDynamicMesh.h:217
Definition DynamicBoneAttribute.h:25
void SetValue(const int32 InBoneID, const AttribValueType &InValue)
Definition DynamicBoneAttribute.h:79
void InitializeTriangles(int MaxTriangleID)
Definition DynamicMeshOverlay.cpp:506
Definition DynamicMeshTriangleAttribute.h:604
void SetValue(int TriangleID, RealType Value)
Definition DynamicMeshTriangleAttribute.h:629
Definition DynamicMeshOverlay.h:714
Definition DynamicVertexAttribute.h:49
Definition DynamicVertexSkinWeightsAttribute.h:48
Definition ToDynamicMesh.h:49
void Convert(FDynamicMesh3 &MeshOut, const SrcMeshType &MeshIn, TFunctionRef< int32(const SrcTriIDType &SrcTrID)> GroupIDFunction)
Definition ToDynamicMesh.h:69
FDateTime Time_AfterVertices
Definition ToDynamicMesh.h:65
TToDynamicMeshBase()
Definition ToDynamicMesh.h:56
TArray< SrcVertIDType > ToSrcVertIDMap
Definition ToDynamicMesh.h:62
FDateTime Time_AfterTriangles
Definition ToDynamicMesh.h:66
typename SrcMeshType::VertIDType SrcVertIDType
Definition ToDynamicMesh.h:52
TArray< SrcTriIDType > ToSrcTriIDMap
Definition ToDynamicMesh.h:63
typename SrcMeshType::TriIDType SrcTriIDType
Definition ToDynamicMesh.h:53
Definition ToDynamicMesh.h:330
typename MyBase::SrcTriIDType SrcTriIDType
Definition ToDynamicMesh.h:333
void ConvertWOAttributes(FDynamicMesh3 &MeshOut, const SrcMeshType &MeshIn, TFunctionRef< int32(const SrcTriIDType &SrcTrID)> GroupIDFunction)
Definition ToDynamicMesh.h:345
void PopulateOverlay(typename TOverlayTraits< AttrType >::OverlayType *Overlay, const TArray< SrcAttrIDType > &SrcAttrIDs, TFunctionRef< AttrType(const SrcAttrIDType &AttrID)> SharedAttrValues, TFunctionRef< bool(const SrcTriIDType &SrcTriID, SrcAttrIDType &AttrID0, SrcAttrIDType &AttrID1, SrcAttrIDType &AttrID2)> AttrTriIndices, TFunctionRef< AttrType(const SrcWedgeIDType &WegdeID)> WedgeAttrs, TFunctionRef< void(const SrcTriIDType &SrcTriID, SrcWedgeIDType &WID0, SrcWedgeIDType &WID1, SrcWedgeIDType &WID2)> TriToWedges)
Definition ToDynamicMesh.h:769
void PopulateOverlays(FDynamicMesh3 &MeshOut, const SrcMeshType &MeshIn, TFunctionRef< int32(const SrcTriIDType &SrcTrID)> MaterialIDFunction, bool bCopyTangents)
Definition ToDynamicMesh.h:370
void PopulateOverlayFromWedgeAttr(typename TOverlayTraits< AttrType >::OverlayType *Overlay, TFunctionRef< AttrType(const SrcWedgeIDType &WedgeID)> WedgeAttrs, TFunctionRef< void(const SrcTriIDType &SrcTriID, SrcWedgeIDType &WID0, SrcWedgeIDType &WID1, SrcWedgeIDType &WID2)> TriToWedges, bool bWeldIdenticalAttrs=true)
Definition ToDynamicMesh.h:621
TToDynamicMesh()
Definition ToDynamicMesh.h:340
typename SrcMeshType::NormalIDType SrcNormalIDType
Definition ToDynamicMesh.h:336
typename MyBase::SrcVertIDType SrcVertIDType
Definition ToDynamicMesh.h:334
typename SrcMeshType::UVIDType SrcUVIDType
Definition ToDynamicMesh.h:335
typename SrcMeshType::ColorIDType SrcColorIDType
Definition ToDynamicMesh.h:337
typename SrcMeshType::WedgeIDType SrcWedgeIDType
Definition ToDynamicMesh.h:338
void Convert(FDynamicMesh3 &MeshOut, const SrcMeshType &MeshIn, TFunctionRef< int32(const SrcTriIDType &SrcTrID)> GroupIDFunction, TFunctionRef< int32(const SrcTriIDType &SrcTrID)> MaterialIDFunction, bool bCopyTangents)
Definition ToDynamicMesh.h:354
TToDynamicMeshBase< SrcMeshType > MyBase
Definition ToDynamicMesh.h:332
void PopulateOverlayFromSharedAttr(typename TOverlayTraits< AttrType >::OverlayType *Overlay, const TArray< SrcAttrIDType > &SrcAttrIDs, TFunctionRef< AttrType(const SrcAttrIDType &AttrID)> SharedAttrValues, TFunctionRef< bool(const SrcTriIDType &SrcTriID, SrcAttrIDType &AttrID0, SrcAttrIDType &AttrID1, SrcAttrIDType &AttrID2)> AttrTriIndices)
Definition ToDynamicMesh.h:664
TDynamicVertexSkinWeightsAttribute< FDynamicMesh3 > FDynamicMeshVertexSkinWeightsAttribute
Definition DynamicMeshAttributeSet.h:62
uint32 GetTypeHash(const TBox< T > &Box)
Definition Box.h:1008
Definition AdvancedWidgetsModule.cpp:13
static UE_FORCEINLINE_HINT uint32 MemCrc32(const void *Data, int32 Length, uint32 CRC=0)
Definition Crc.h:31
Definition DateTime.h:76
static CORE_API FDateTime Now()
Definition DateTime.cpp:377
Definition IndexTypes.h:158
FDynamicMeshUVOverlay OverlayType
Definition ToDynamicMesh.h:201
FDynamicMeshNormalOverlay OverlayType
Definition ToDynamicMesh.h:200
FDynamicMeshColorOverlay OverlayType
Definition ToDynamicMesh.h:202
Definition ToDynamicMesh.h:199
Definition ToDynamicMesh.h:183
AttrType AttrValue
Definition ToDynamicMesh.h:185
bool operator==(const TVertexAttr &o) const
Definition ToDynamicMesh.h:186
int VID
Definition ToDynamicMesh.h:184