UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MeshUtilities.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CADKernelEngine.h"
6#if PLATFORM_DESKTOP
8
9#include "IntVectorTypes.h"
11#include "Util/DynamicVector.h"
12
13namespace UE::CADKernel
14{
15 class FModelMesh;
16 struct FMeshExtractionContext;
17}
18
19namespace UE::Geometry
20{
21 class FDynamicMesh3;
22}
23
24class FMeshDecription;
25
27
28namespace UE::CADKernel::MeshUtilities
29{
31 {
32 public:
33
35
36 virtual void Register(bool bKeepExistingAttribute = false) override;
37
38 bool IsValid() const
39 {
40 return GetVertexInstanceNormals().IsValid() &&
41 GetVertexInstanceTangents().IsValid() &&
42 GetVertexInstanceBinormalSigns().IsValid() &&
43 GetVertexInstanceColors().IsValid() &&
44 GetVertexInstanceUVs().IsValid() &&
45 GetPolygonGroupMaterialSlotNames().IsValid() &&
46 GetPolygonGroups().IsValid();
47 }
48
56 };
57
59 {
60 public:
61 struct FFaceTriangle
62 {
63 int32 GroupID;
64 uint32 MaterialID;
65
66 // Indices referencing the array of positions set calling SetVertices or the latest call to AddNewVertices
67 const FArray3i VertexIndices;
68
69 // Indices referencing the array of normals, Normals, set calling StartFaceTriangles.
70 const FArray3i Normals;
71
72 // Indices referencing the array of texture coordinates, TexCoords, set calling StartFaceTriangles.
73 const FArray3i TexCoords;
74
76 : GroupID(InGroupID)
77 , MaterialID(InMaterialID)
78 , VertexIndices(InVertexIndices)
80 , TexCoords(InTexCoords)
81 {
82 }
83 };
84
85 FMeshWrapperAbstract(const FMeshExtractionContext& InContext) : Context(InContext)
86 {
87 bHasFaceGroupsToSkip = !InContext.FaceGroupsToExtract.IsEmpty();
88 }
89
90 /*
91 ** Call this method when the building of the mesh is completed.
92 ** Must be called before the pointer to the child class is deleted.
93 */
94 void Complete()
95 {
96 if (bIsComplete)
97 {
98 return;
99 }
100
101 if (Context.MeshParams.bIsSymmetric)
102 {
103 AddSymmetry();
104 }
105
106 FinalizeMesh();
107
108 // Workaround for SDHE-19725 (Declined): Compute any null normals.
110
111 OrientMesh();
112
113 if (Context.bResolveTJunctions)
114 {
116 }
117
118 bIsComplete = true;
119 }
120
121 virtual ~FMeshWrapperAbstract() {}
122
123 virtual void ClearMesh() = 0;
124
125 virtual bool SetVertices(TArray<FVector>&& Vertices) = 0;
126
127 virtual bool AddNewVertices(TArray<FVector>&& Vertices) = 0;
128
129 virtual bool ReserveNewTriangles(int32 AdditionalTriangleCount) = 0;
130
131 /*
132 ** Expected Normals.Num() == TexCoords.Num() == 3 * TriangleCount
133 */
134 virtual bool StartFaceTriangles(int32 TriangleCount, const TArray<FVector3f>& Normals, const TArray<FVector2f>& TexCoords) = 0;
135 virtual bool StartFaceTriangles(const TArrayView<FVector>& Normals, const TArrayView<FVector2d>& TexCoords) = 0;
136
138
139 virtual bool AddFaceTriangle(const FFaceTriangle& FaceTriangle) = 0;
140
141 virtual void EndFaceTriangles() = 0;
142
143
144 /*
145 * Normals and TexCoords array are expected to be arrays of 3 elements
146 * Each value in those arrays is associated to the vertex in VertexIndices at the same index value, 0, 1 and 2.
147 */
148 virtual bool AddTriangle(int32 GroupID, uint32 MaterialID, const FArray3i& VertexIndices, const TArrayView<FVector3f>& Normals, const TArrayView<FVector2f>& TexCoords) = 0;
149
150 bool IsFaceGroupValid(int32 GroupID)
151 {
152 return bHasFaceGroupsToSkip ? Context.FaceGroupsToExtract.Contains(GroupID) : true;
153 }
154
155 static TSharedPtr<FMeshWrapperAbstract> MakeWrapper(const FMeshExtractionContext& InContext, FMeshDescription& Mesh);
157
158 protected:
159 static constexpr FArray3i Clockwise{ 0, 1, 2 };
160 static constexpr FArray3i CounterClockwise{ 0, 2, 1 };
161
162 const FMeshExtractionContext& Context;
163 bool bAreVerticesSet = false;
164
165 // #cad_import: The UV scaling should be done in CADKernel
166 static constexpr double ScaleUV = 0.001; // mm to m
167
168 protected:
169 virtual void AddSymmetry() = 0;
170 virtual void FinalizeMesh() = 0;
171 virtual void RecomputeNullNormal() = 0;
172 virtual void OrientMesh() = 0;
173 virtual void ResolveTJunctions() = 0;
174
175 private:
176 bool bHasFaceGroupsToSkip = false;
177 bool bIsComplete = false;
178 };
179
182
183 template<typename VecType>
184 void ConvertVectorArray(uint8 ModelCoordSys, UE::Geometry::TDynamicVector<VecType>& Array)
185 {
186 switch (ECADKernelModelCoordSystem(ModelCoordSys))
187 {
189 for (VecType& Vector : Array)
190 {
191 Vector.Set(Vector[2], Vector[0], Vector[1]);
192 }
193 break;
194
196 for (VecType& Vector : Array)
197 {
198 Vector.Set(-Vector[2], Vector[0], Vector[1]);
199 }
200 break;
201
203 for (VecType& Vector : Array)
204 {
205 Vector.Set(-Vector[0], Vector[1], Vector[2]);
206 }
207 break;
208
210 for (VecType& Vector : Array)
211 {
212 Vector.Set(Vector[0], -Vector[1], Vector[2]);
213 }
214 break;
215
217 default:
218 break;
219 }
220 }
221
222 template<typename Type>
223 UE::Math::TMatrix<Type> GetSymmetricMatrix(const UE::Math::TVector<Type>& Origin, const UE::Math::TVector<Type>& Normal)
224 {
225 using namespace UE::Math;
226 //Calculate symmetry matrix
227 //(Px, Py, Pz) = normal
228 // -Px*Px + Pz*Pz + Py*Py | - 2 * Px * Py | - 2 * Px * Pz
229 // - 2 * Py * Px | - Py*Py + Px*Px + Pz*Pz | - 2 * Py * Pz
230 // - 2 * Pz * Px | - 2 * Pz * Py | - Pz*Pz + Py*Py + Px*Px
231
232 TVector<Type> LocOrigin = Origin;
233
237
240 TVector<Type> Axis0(-NormalXSqr + NormalZSqr + NormalYSqr, -2 * Normal.X * Normal.Y, -2 * Normal.X * Normal.Z);
241 TVector<Type> Axis1(-2 * Normal.Y * Normal.X, -NormalYSqr + NormalXSqr + NormalZSqr, -2 * Normal.Y * Normal.Z);
243 OSymmetricMatrix.SetAxes(&Axis0, &Axis1, &Axis2);
244
247
248 //Translate to 0, 0, 0
249 LocOrigin *= -1.;
250 SymmetricMatrix.SetOrigin(LocOrigin);
251
254
255 //Translate to original position
256 LocOrigin *= -1.;
259 OrigTranslation.SetOrigin(LocOrigin);
261
262 return SymmetricMatrix;
263 }
264
265 class FMeshOperations
266 {
267 static bool OrientMesh(FMeshDescription& MeshDescription);
268 static void ResolveTJunctions(FMeshDescription& MeshDescription, double Tolerance);
270 };
271}
272#endif
@ Normal
Definition AndroidInputInterface.h:116
ECADKernelModelCoordSystem
Definition CADKernelEngineDefinitions.h:11
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
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition StaticMeshAttributes.h:54
Definition ArrayView.h:139
Definition Array.h:670
Definition MeshAttributeArray.h:836
Definition SharedPointer.h:692
Definition DynamicMesh3.h:108
Definition DynamicVector.h:27
Type
Definition PawnAction_Move.h:11
Definition CADEntity.cpp:23
Definition ParametricSurfaceData.h:18
Definition Sphere.cpp:10
Definition MeshDescription.h:94
Definition IntVectorTypes.h:252
Definition Matrix.h:43
void SetIdentity()
Definition Matrix.inl:48
Definition Vector.h:51