![]() |
UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
|
#include <DynamicMeshEditor.h>
Classes | |
| struct | FLoopPairSet |
Public Types | |
| enum class | EDuplicateTriBehavior : uint8 { EnsureContinue , EnsureAbort , UseExisting , Replace } |
Public Attributes | |
| FDynamicMesh3 * | Mesh |
FDynamicMeshEditor implements low-level mesh editing operations. These operations can be used to construct higher-level operations. For example an Extrude operation could be implemented via DuplicateTriangles() and StitchLoopMinimal().
|
strong |
In ReinsertSubmesh, a problem can arise where the mesh we are inserting has duplicate triangles of the base mesh.
This can lead to problematic behavior later. We can do various things, like delete and replace that existing triangle, or just use it instead of adding a new one. Or fail, or ignore it.
This enum/argument controls the behavior. However, fundamentally this kind of problem should be handled upstream!! For example by not trying to remesh areas that contain nonmanifold geometry...
| Enumerator | |
|---|---|
| EnsureContinue | |
| EnsureAbort | |
| UseExisting | |
| Replace | |
|
inline |
| bool FDynamicMeshEditor::AddTriangleFan_OrderedVertexLoop | ( | int | CenterVertex, |
| const TArray< int > & | VertexLoop, | ||
| int | GroupID, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Fill hole with a triangle fan given an existing (unconnected) center vertex and an ordered loop of boundary vertices on the hole border.
| CenterVertex | Index of floating vertex in the center of the hole |
| VertexLoop | Indices of vertices on the boundary of the hole, in order |
| ResultOut | lists of newly created triangles |
| void FDynamicMeshEditor::AppendColors | ( | const FDynamicMesh3 * | AppendMesh, |
| const FDynamicMeshColorOverlay * | FromOverlay, | ||
| FDynamicMeshColorOverlay * | ToOverlay, | ||
| const FIndexMapi & | VertexMap, | ||
| const FIndexMapi & | TriangleMap, | ||
| FIndexMapi & | ColorMapOut | ||
| ) |
Append Colors from one attribute overlay to another. Assumes that AppendMesh has already been appended to Mesh. Note that this function has no dependency on .Mesh, it could be static
| AppendMesh | mesh that owns FromOverlay attribute overlay |
| FromOverlay | Color overlay we want to append from (owned by AppendMesh) |
| ToOverlay | Color overlay we want to append to (owned by Mesh) |
| VertexMap | map from AppendMesh vertex IDs to vertex IDs applicable to ToOverlay (ie of .Mesh) |
| TriangleMap | map from AppendMesh triangle IDs to triangle IDs applicable to ToOverlay (ie of .Mesh) |
| ColorMapOut | Mapping from element IDs of FromUVs to new element IDs in ToOverlay |
| void UE::Geometry::FDynamicMeshEditor::AppendElementSubset | ( | const FDynamicMesh3 * | FromMesh, |
| const TSet< int > & | TriangleROI, | ||
| const TSet< int > & | VertexROI, | ||
| const TDynamicMeshOverlay< RealType, ElementSize > * | FromOverlay, | ||
| TDynamicMeshOverlay< RealType, ElementSize > * | ToOverlay | ||
| ) |
| GEOMETRYCORE_API void UE::Geometry::FDynamicMeshEditor::AppendElementSubset | ( | const FDynamicMesh3 * | FromMesh, |
| const TSet< int > & | TriangleROI, | ||
| const TSet< int > & | VertexROI, | ||
| const TDynamicMeshOverlay< RealType, ElementSize > * | FromOverlay, | ||
| TDynamicMeshOverlay< RealType, ElementSize > * | ToOverlay | ||
| ) |
Append overlay elements in both ROIs from one overlay to another
| FromMesh | Mesh that owns FromOverlay attribute overlay |
| TriangleROI | Triangles containing the copied overlay elements |
| VertexROI | Parent vertices of the copied overlay elements |
| FromOverlay | Overlay we want to append from (owned by FromMesh) |
| ToOverlay | Overlay we want to append into (owned by .Mesh) |
| void FDynamicMeshEditor::AppendMesh | ( | const FDynamicMesh3 * | AppendMesh, |
| FMeshIndexMappings & | IndexMapsOut, | ||
| TFunction< FVector3d(int, const FVector3d &)> | PositionTransform = nullptr, |
||
| TFunction< FVector3d(int, const FVector3d &)> | NormalTransform = nullptr, |
||
| bool | bReverseOrientation = false |
||
| ) |
Append input mesh to our internal mesh
| AppendMesh | mesh to append |
| IndexMapsOut | mesh element index mappings generated in this append operation |
| PositionTransform | optional transformation function applied to mesh vertex positions |
| NormalTransform | optional transformation function applied to mesh normals |
| void FDynamicMeshEditor::AppendMesh | ( | const TTriangleMeshAdapter< double > * | AppendMesh, |
| FMeshIndexMappings & | IndexMapsOut, | ||
| TFunction< FVector3d(int, const FVector3d &)> | PositionTransform = nullptr |
||
| ) |
Append input mesh to our internal Mesh. If the internal Mesh has attributes enabled, per-triangle normals will be computed and set. No other attributes are initialized.
| AppendMesh | mesh to append |
| IndexMapsOut | mesh element index mappings generated in this append operation |
| PositionTransform | optional transformation function applied to mesh vertex positions |
| void FDynamicMeshEditor::AppendNormals | ( | const FDynamicMesh3 * | AppendMesh, |
| const FDynamicMeshNormalOverlay * | FromNormals, | ||
| FDynamicMeshNormalOverlay * | ToNormals, | ||
| const FIndexMapi & | VertexMap, | ||
| const FIndexMapi & | TriangleMap, | ||
| TFunction< FVector3d(int, const FVector3d &)> | NormalTransform, | ||
| FIndexMapi & | NormalMapOut | ||
| ) |
Append normals from one attribute overlay to another. Assumes that AppendMesh has already been appended to Mesh. Note that this function has no dependency on .Mesh, it could be static
| AppendMesh | mesh that owns FromNormals attribute overlay |
| FromNormals | Normals overlay we want to append from (owned by AppendMesh) |
| ToNormals | Normals overlay we want to append to (owned by Mesh) |
| VertexMap | map from AppendMesh vertex IDs to vertex IDs applicable to ToNormals (ie of .Mesh) |
| TriangleMap | map from AppendMesh triangle IDs to triangle IDs applicable to ToNormals (ie of .Mesh) |
| NormalTransform | optional transformation function applied to mesh normals |
| NormalMapOut | Mapping from element IDs of FromNormals to new element IDs in ToNormals |
| void FDynamicMeshEditor::AppendTriangles | ( | const FDynamicMesh3 * | SourceMesh, |
| const TArrayView< const int > & | SourceTriangles, | ||
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult & | ResultOut, | ||
| bool | bComputeTriangleMap = true |
||
| ) |
Append triangles of an existing mesh. This duplicates the current groups and also any attributes existing on the triangles.
| SourceMesh | the mesh to copy from |
| SourceTriangles | the triangles to copy |
| IndexMaps | returned mappings from old to new triangles/vertices/etc (you may initialize to optimize memory usage, etc) |
| ResultOut | lists of newly created triangles/vertices/etc |
| bComputeTriangleMap | if true, computes the triangle map section of IndexMaps (which is not needed for the append to work, so is optional) |
| void FDynamicMeshEditor::AppendUVs | ( | const FDynamicMesh3 * | AppendMesh, |
| const FDynamicMeshUVOverlay * | FromUVs, | ||
| FDynamicMeshUVOverlay * | ToUVs, | ||
| const FIndexMapi & | VertexMap, | ||
| const FIndexMapi & | TriangleMap, | ||
| FIndexMapi & | UVMapOut | ||
| ) |
Append UVs from one attribute overlay to another. Assumes that AppendMesh has already been appended to Mesh. Note that this function has no dependency on .Mesh, it could be static
| AppendMesh | mesh that owns FromUVs attribute overlay |
| FromUVs | UV overlay we want to append from (owned by AppendMesh) |
| ToUVs | UV overlay we want to append to (owned by Mesh) |
| VertexMap | map from AppendMesh vertex IDs to vertex IDs applicable to ToUVs (ie of .Mesh) |
| TriangleMap | map from AppendMesh triangle IDs to triangle IDs applicable to ToUVs (ie of .Mesh) |
| UVMapOut | Mapping from element IDs of FromUVs to new element IDs in ToUVs |
| FVector3f FDynamicMeshEditor::ComputeAndSetQuadNormal | ( | const FIndex2i & | QuadTris, |
| bool | bIsPlanar = false |
||
| ) |
Calculate and set the per-triangle normals of the two input quads. Average of the two face normals is used unless the quad is planar
| QuadTris | pair of triangle IDs. If second ID is invalid, it is ignored |
| bIsPlanar | if the quad is known to be planar, operation is more efficient |
|
static |
Converts a loop to a sequence of edge identifiers that are both Vid and Eid independent. The identifiers are of the form (TriangleID, ([0,2] vert sub index, [0,2] vert sub index)), and they are used in some cases (extrude, inset) where we want to perform vertex splits along a region boundary (to remove bowties) but need to maintain a record of the original loop path. We don't use (TriangleID, Eid sub index) because that makes it harder to keep track of individual edge directionality.
| VidLoop | Vertex IDs of loop to convert. |
| EdgeLoop | Edge IDs of loop to convert, must match VidLoop. |
| TriVertPairsOut | Output |
| void FDynamicMeshEditor::CopyAttributes | ( | int | FromTriangleID, |
| int | ToTriangleID, | ||
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Copy all attribute-layer values from one triangle to another, using the IndexMaps to track and re-use shared attribute values.
| FromTriangleID | source triangle |
| ToTriangleID | destination triangle |
| IndexMaps | mappings passed to FindOrCreateDuplicateX functions to track already-created attributes |
| ResultOut | information about new attributes is stored here ( |
|
static |
Cut existing 2D attribute overlay topology with a set of edges. This allows for creating partial seams/darts, interior cuts, etc.
Avoids creating bowties in the overlay. In cases where an edge is not next to any present or future seams/borders, some adjacent edge will be picked to be made into a seam as well, since it's impossible to make the original into a seam otherwise.
| EidsToMakeIntoSeams | list of edges to turn into seams |
| AddedElementIDs | if non-null, list of new elements created along the path will be stored here (not ordered) |
|
static |
Cut existing 3D attribute overlay topology with a set of edges. This allows for creating partial seams/darts, interior cuts, etc.
Avoids creating bowties in the overlay. In cases where an edge is not next to any present or future seams/borders, some adjacent edge will be picked to be made into a seam as well, since it's impossible to make the original into a seam otherwise.
| EidsToMakeIntoSeams | list of edges to turn into seams |
| AddedElementIDs | if non-null, list of new elements created along the path will be stored here (not ordered) |
| void FDynamicMeshEditor::DisconnectTriangles | ( | const TArray< int > & | Triangles, |
| bool | bPreventBowties = true |
||
| ) |
Disconnects triangles (without constructing boundary loops) such that the input Triangles are not connected to any other triangles in the mesh
| Triangles | set of triangles |
| bPreventBowties | do some additional processing and vertex splitting as needed to prevent the creation of any new bowties |
| bool FDynamicMeshEditor::DisconnectTriangles | ( | const TArray< int > & | Triangles, |
| TArray< FLoopPairSet > & | LoopSetOut, | ||
| bool | bHandleBoundaryVertices | ||
| ) |
Finds boundary loops of connected components of a set of triangles, and duplicates the vertices along the boundary, such that the triangles become disconnected. If the triangle set includes boundary vertices, they cannot be disconnected as they will become unreferenced. The function returns false if boundary vertices are found, unless bHandleBoundaryVertices = true. In that case, the boundary vertex is duplicated, and the original vertex is kept with the "Inner" loop. The new unreferenced vertex is left on the "Outer" loop, and the attached edges do not exist so are set as InvalidID. The FLoopPairSet.bOuterIncludesIsolatedVertices flag is set to true if boundary vertices are encountered. Note: This function can create a mesh with bowties if you pass in a subset of triangles that would have bowtie connectivity. (it is impossible to create the paired LoopSetOut with 1:1 vertex pairs without leaving in the bowties?)
| Triangles | set of triangles |
| LoopSetOut | set of boundary loops. LoopA is original loop which remains with "outer" triangles, and LoopB is new boundary loop of triangle set |
| bHandleBoundaryVertices | if true, boundary vertices are handled as described above, otherwise function aborts and returns false if a boundary vertex is encountered |
| bool FDynamicMeshEditor::DisconnectTriangles | ( | const TSet< int > & | TriangleSet, |
| const TArray< FEdgeLoop > & | BoundaryLoops, | ||
| TArray< FLoopPairSet > & | LoopSetOut, | ||
| bool | bAllowBoundaryVertices | ||
| ) |
Variant of DisconnectTriangles that takes a precomputed set of BoundaryLoops of the triangles, and a TSet of Triangles. These are both computed internally by the version that only takes a TArray of Triangles.
| Triangles | set of triangles |
| BoundaryLoops | precomputed set of boundary EdgeLoops of TriangleSet |
| LoopSetOut | returned set of boundary loops. LoopA is original loop which remains with "outer" triangles previously connected to TriangleSet, and LoopB is new boundary loop of TriangleSet |
| bAllowBoundaryVertices | if true, mesh boundary vertices are duplicated and left on the 'outer' loop, otherwise function aborts and returns false if a boundary vertex is encountered |
| bool FDynamicMeshEditor::DisconnectTrianglesAlongEdges | ( | const TSet< int32 > & | Edges, |
| TArray< int32 > * | AddedVertexIDs = nullptr |
||
| ) |
Disconnect triangles along the given Edges, so that all input edges become boundary edges.
| Edges | IDs of edges to disconnect |
| AddedVertexIDs | Optional array of vertices added by this operation |
| TIDsUntilNextBoundary | TIDs in a fan away from EID around VID until the next boundary. Will be the entire one-ring if the given EID is the only boundary attached to VID. |
| void FDynamicMeshEditor::DuplicateTriangles | ( | const TArray< int > & | Triangles, |
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Duplicate triangles of a mesh. This duplicates the current groups and also any attributes existing on the triangles.
| Triangles | the triangles to duplicate |
| IndexMaps | returned mappings from old to new triangles/vertices/etc (you may initialize to optimize memory usage, etc) |
| ResultOut | lists of newly created triangles/vertices/etc |
Make a copy of provided triangles, with new vertices. You provide IndexMaps because you know if you are doing a small subset or a full-mesh-copy.
| int FDynamicMeshEditor::FindOrCreateDuplicateColor | ( | int | ElementID, |
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult * | ResultOut | ||
| ) |
Find "new" color for input color element under Index mapping, or create new if missing
| ElementID | the source color we want a duplicate of |
| IndexMaps | source/destination mapping of already-duplicated colors |
| ResultOut | any newly created element indices are stored in NewColorOverlayElements here. |
| int FDynamicMeshEditor::FindOrCreateDuplicateGroup | ( | int | TriangleID, |
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Find "new" group for input group under Index mapping, or create new if missing
| TriangleID | the source triangle whose group we want a copy of |
| IndexMaps | source/destination mapping of already-duplicated groups |
| ResultOut | newly-created groups are stored here |
| int FDynamicMeshEditor::FindOrCreateDuplicateNormal | ( | int | ElementID, |
| int | NormalLayerIndex, | ||
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult * | ResultOut = nullptr |
||
| ) |
Find "new" normal for input normal element under Index mapping, or create new if missing
| ElementID | the source normal we want a duplicate of |
| NormalLayerIndex | which normal layer to consider |
| IndexMaps | source/destination mapping of already-duplicated normals |
| ResultOut | any newly created element indices are stored in NewNormalOverlayElements here. Note that NewNormalOverlayElements must have size > NormalLayerIndex. |
| int FDynamicMeshEditor::FindOrCreateDuplicateUV | ( | int | ElementID, |
| int | UVLayerIndex, | ||
| FMeshIndexMappings & | IndexMaps | ||
| ) |
Find "new" UV for input UV element under Index mapping, or create new if missing
| ElementID | the source UV we want a duplicate of |
| UVLayerIndex | which UV layer to consider |
| IndexMaps | source/destination mapping of already-duplicated UVs |
| int FDynamicMeshEditor::FindOrCreateDuplicateVertex | ( | int | VertexID, |
| FMeshIndexMappings & | IndexMaps, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Find "new" vertex for input vertex under Index mapping, or create new if missing
| VertexID | the source vertex we want a copy of |
| IndexMaps | source/destination mapping of already-duplicated vertices |
| ResultOut | newly-created vertices are stored here |
Flip the normals of the given triangles. This includes their vertex normals, if they exist, as well as any per-triangle attribute normals.
| Triangles | the triangles to modify |
| bool FDynamicMeshEditor::ReinsertSubmesh | ( | const FDynamicSubmesh3 & | Submesh, |
| FOptionallySparseIndexMap & | SubToNewV, | ||
| TArray< int > * | NewTris = nullptr, |
||
| EDuplicateTriBehavior | DuplicateBehavior = EDuplicateTriBehavior::EnsureAbort |
||
| ) |
Update a Base Mesh from a Submesh; See FMeshRegionOperator::BackPropropagate for a usage example.
Assumes that Submesh has been modified, but boundary loop has been preserved, and that old submesh has already been removed from this mesh. Just appends new vertices and rewrites triangles.
| Submesh | The mesh to insert back into its BaseMesh. The original submesh triangles should have already been removed when this function is called |
| SubToNewV | Mapping from submesh to vertices in the updated base mesh |
| NewTris | If not null, will be filled with IDs of triangles added to the base mesh |
| DuplicateBehavior | Choice of what to do if inserting a triangle from the submesh would duplicate a triangle in the base mesh |
| bool FDynamicMeshEditor::RemoveIsolatedVertices | ( | ) |
Remove any vertices that are not used by any triangles
|
static |
Merge any seams in the given 2D attribute Overlay along the given mesh edge IDs
| EidsToRemoveAsSeams | list of edges to remove seams from |
|
static |
Merge any seams in the given (3D attribute) Overlay along the given mesh edge IDs
| EidsToRemoveAsSeams | list of edges to remove seams from |
| int FDynamicMeshEditor::RemoveSmallComponents | ( | double | MinVolume, |
| double | MinArea = 0.0, |
||
| int | MinTriangleCount = 0 |
||
| ) |
Remove any connected components with volume or area below the given thresholds
| MinVolume | Remove components with less volume than this |
| MinArea | Remove components with less area than this |
| bool FDynamicMeshEditor::RemoveTriangles | ( | const TArray< int > & | Triangles, |
| bool | bRemoveIsolatedVerts | ||
| ) |
Remove a list of triangles from the mesh, and optionally any vertices that are now orphaned
| Triangles | the triangles to remove |
| bRemoveIsolatedVerts | if true, remove vertices that end up with no triangles |
| bool FDynamicMeshEditor::RemoveTriangles | ( | const TArray< int > & | Triangles, |
| bool | bRemoveIsolatedVerts, | ||
| TFunctionRef< void(int)> | OnRemoveTriFunc | ||
| ) |
Remove a list of triangles from the mesh, and optionally any vertices that are now orphaned
| Triangles | the triangles to remove |
| bRemoveIsolatedVerts | if true, remove vertices that end up with no triangles |
| OnRemoveTriFunc | called for each triangle to be removed |
| void FDynamicMeshEditor::RescaleAttributeUVs | ( | float | UVScale = 1.0f, |
| bool | bWorldSpace = false, |
||
| int | UVLayerIndex = 0, |
||
| TOptional< FTransformSRT3d > | ToWorld = TOptional<FTransformSRT3d>() |
||
| ) |
Rescale UVs for the whole mesh, for the given UV attribute layer
| UVScale | Scale factor to multiply into UVs. If in world space, this is in centimeters relative to the average UV scale |
| bWorldSpace | If true, UVs are rescaled relative to an absolute world scale. |
| UVLayerIndex | which UV layer to operate on (must exist) |
| ToWorld | Optionally transform vertices for world space scaling |
| void FDynamicMeshEditor::ReverseTriangleOrientations | ( | const TArray< int > & | Triangles, |
| bool | bInvertNormals | ||
| ) |
Reverse the orientation of the given triangles, and optionally flip relevant normals
| Triangles | the triangles to modify |
| bInvertNormals | if ture we call InvertTriangleNormals() |
| void FDynamicMeshEditor::SetGeneralTubeUVs | ( | const TArray< int > & | Triangles, |
| const TArray< int > & | VertexIDs1, | ||
| const TArray< int > & | MatchedIndices1, | ||
| const TArray< int > & | VertexIDs2, | ||
| const TArray< int > & | MatchedIndices2, | ||
| const TArray< float > & | UValues, | ||
| const FVector3f & | VDir, | ||
| float | UVScaleFactor = 1.0f, |
||
| const FVector2f & | UVTranslation = FVector2f::Zero(), |
||
| int | UVLayerIndex = 0 |
||
| ) |
For triangles connecting loops of corresponded vertices, set UVs in a cylindrical pattern so that the U coordinate starts at 0 for the first corresponded pair of vertices, and cycles around to 1 Assumes Triangles array stores indices of triangles in progressively filling the tube, starting with VertexIDs*[0]. (This is used to set the UVs correctly at the seam joining the start & end of the loop)
Create and set new shared per-triangle normals for a pair of triangles that share one edge (ie a quad)
| QuadTris | pair of triangle IDs. If second ID is invalid, it is ignored |
| Normal | normal vector to set |
| void FDynamicMeshEditor::SetQuadUVsFromProjection | ( | const FIndex2i & | QuadTris, |
| const FFrame3d & | ProjectionFrame, | ||
| float | UVScaleFactor = 1.0f, |
||
| const FVector2f & | UVTranslation = FVector2f::Zero(), |
||
| int | UVLayerIndex = 0 |
||
| ) |
Project the two triangles of the quad onto a plane defined by the ProjectionFrame and use that to create/set new shared per-triangle UVs. UVs are translated so that their bbox min-corner is at origin, and scaled by given scale factor
| QuadTris | pair of triangle IDs. If second ID is invalid, it is ignored |
| ProjectFrame | vertices are projected into XY axes of this frame |
| UVScaleFactor | UVs are scaled by this uniform scale factor |
| UVTranslation | UVs are translated after scaling |
| UVLayerIndex | which UV layer to operate on (must exist) |
Create and set new shared per-triangle normals for a list of triangles. Normal at each vertex is calculated based only on average of triangles in set
| Triangles | list of triangle IDs |
| void FDynamicMeshEditor::SetTriangleNormals | ( | const TArray< int > & | Triangles, |
| const FVector3f & | Normal | ||
| ) |
Create and set new shared per-triangle normals for a list of triangles
| Triangles | list of triangle IDs |
| Normal | normal vector to set |
| void FDynamicMeshEditor::SetTriangleUVsFromProjection | ( | const TArray< int > & | Triangles, |
| const FFrame3d & | ProjectionFrame, | ||
| const FVector2f & | UVScale = FVector2f::One(), |
||
| const FVector2f & | UVTranslation = FVector2f::Zero(), |
||
| int | UVLayerIndex = 0, |
||
| bool | bShiftToOrigin = true, |
||
| bool | bNormalizeBeforeScaling = false |
||
| ) |
Project triangles onto a plane defined by the ProjectionFrame and use that to create/set new shared per-triangle UVs.
| Triangles | TArray of triangle IDs |
| ProjectFrame | Vertices are projected into XY axes of this frame |
| UVScaleFactor | UVs are scaled by these factors |
| UVTranslation | UVs are translated after scaling by these amounts |
| UVLayerIndex | Which UV layer to operate on (must exist) |
| bShiftToOrigin | Whether to translate the UV coordinates to make their bounding box min corner be (0,0) before applying UVTranslation |
| bNormalizeBeforeScaling | Whether to place the UV coordinates into the range [0,1] before applying UVScaleFactor and UVTranslation |
| GEOMETRYCORE_API void UE::Geometry::FDynamicMeshEditor::SetTriangleUVsFromProjection | ( | const TArray< int32 > & | Triangles, |
| const FFrame3d & | ProjectionFrame, | ||
| float | UVScaleFactor = 1.0f, |
||
| const FVector2f & | UVTranslation = FVector2f::Zero(), |
||
| bool | bShiftToOrigin = true, |
||
| int32 | UVLayerIndex = 0 |
||
| ) |
Project triangles onto a plane defined by the ProjectionFrame and use that to create/set new shared per-triangle UVs. UVs can be translated so that their bbox min-corner is at origin, and scaled by given scale factor This is an older function signature that forwards to the more specific one.
| Triangles | TArray of triangle IDs |
| ProjectFrame | vertices are projected into XY axes of this frame |
| UVScaleFactor | UVs are scaled by this uniform scale factor |
| UVTranslation | UVs are translated after scaling |
| bShiftToOrigin | Whether to translate the UV coordinates to make their bounding box min corner be (0,0) before applying UVTranslation |
| UVLayerIndex | which UV layer to operate on (must exist) |
| void FDynamicMeshEditor::SetTubeNormals | ( | const TArray< int > & | Triangles, |
| const TArray< int > & | VertexIDs1, | ||
| const TArray< int > & | MatchedIndices1, | ||
| const TArray< int > & | VertexIDs2, | ||
| const TArray< int > & | MatchedIndices2, | ||
| bool | bReverseNormals = false |
||
| ) |
For a 'tube' of triangles connecting loops of corresponded vertices, set smooth normals such that corresponding vertices have corresponding normals
| void FDynamicMeshEditor::SplitBowties | ( | FDynamicMeshEditResult & | ResultOut | ) |
Splits all bowties across the whole mesh
|
inline |
Splits any bowties specifically on the given vertex, and updates (does not reset!) ResultOut with any added vertices
|
inline |
Splits any bowties specifically on the given vertex, and (if not null) updates (does not reset!) NewVertices with any added vertices
| void FDynamicMeshEditor::SplitBowtiesAtTriangles | ( | const TArray< int32 > & | TriangleIDs, |
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Splits bowties attached to any of the given triangles, and updates (does not reset!) ResultOut with any added vertices
|
static |
Create multiple meshes out of the source mesh by splitting triangles out. Static because it creates multiple output meshes, so doesn't quite fit in the FDynamicMeshEditor model of operating on a single mesh
| SourceMesh | The mesh to split |
| SplitMeshes | An array with one mesh per unique Mesh ID found in SourceMesh (optionally excluding the DeleteMeshID) |
| TriIDToMeshID | A function mapping Triangle IDs to Mesh IDs |
| DeleteMeshID | If non-negative, triangles with this Mesh ID will be removed rather than being placed in a split mesh |
| MeshIDPerSplitMesh | If non-null, will be filled with the Mesh ID for each of the SplitMeshes generated |
| bSortByMeshID | If true, SplitMeshes will be sorted in order of increasing Mesh ID |
| bool FDynamicMeshEditor::StitchSparselyCorrespondedVertexLoops | ( | const TArray< int > & | VertexIDs1, |
| const TArray< int > & | MatchedIndices1, | ||
| const TArray< int > & | VertexIDs2, | ||
| const TArray< int > & | MatchedIndices2, | ||
| FDynamicMeshEditResult & | ResultOut, | ||
| bool | bReverseOrientation = false |
||
| ) |
Stitch together two loops of vertices where vertices are only sparsely corresponded
| VertexIDs1 | first array of sequential vertices |
| MatchedIndices1 | indices into the VertexIDs1 array of vertices that have a corresponding match in the VertexIDs2 array; Must be ordered |
| VertexIDs2 | second array of sequential vertices |
| MatchedIndices2 | indices into the VertexIDs2 array of vertices that have a corresponding match in the VertexIDs1 array; Must be ordered |
| ResultOut | lists of newly created triangles/vertices/etc |
| bool FDynamicMeshEditor::StitchVertexLoopsMinimal | ( | const TArray< int > & | VertexLoop1, |
| const TArray< int > & | VertexLoop2, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Stitch together two loops of vertices with a quad-strip of triangles. Loops must be oriented (ordered) correctly for your use case. If loop edges are [a,b] and [c,d], then tris added are [b,a,d] and [a,c,d]
| Loop1 | first loop of sequential vertices |
| Loop2 | second loop of sequential vertices |
| ResultOut | lists of newly created triangles/vertices/etc |
| bool FDynamicMeshEditor::StitchVertexLoopToTriVidPairSequence | ( | const TArray< TPair< int32, TPair< int8, int8 > > > & | TriVidPairs1, |
| const TArray< int > & | VertexLoop2, | ||
| FDynamicMeshEditResult & | ResultOut | ||
| ) |
Given a sequence of edges in the form given by ConvertLoopToTriVidPairSequence and a loop of vertices, stitch the two together. Edges are identified as (TriangleID, (0-2 subindex of vert1, 0-2 subindex of vert2)), and should match the number of vertex ids in the corresponding vertex loop (each i corresponds to the edge between vert i and i+1 in the vertex loop). This works much like StitchVertexLoopsMinimal, but it can be used after one of the loops undergoes vertex splits (to remove bowties) as long as the "loop" (which may now be broken) can still be identified by the composing triangles. In particular, this is used in extrude and inset where the base loop needs to remain as a sequence of Vids (since some of these may be free vertices, unattached to a triangle) but the offset/inset loop is guaranteed to be attached to triangles yet may have its Vids change due to bowtie splits.
If an entry of TriVidPairs1 resolves to verts [a,b] and the corresponding pair of verts in VertexLoop2 are [c,d], then tris added are [b,a,d] and [a,c,d].
| TriVidPairs1 | First loop, given as output of ConvertLoopToTriVidPairSequence() |
| VertexLoop2 | Second loop, given as vertex IDs |
| ResultOut | lists of newly created triangles/vertices/etc |
| bool FDynamicMeshEditor::WeldVertexLoops | ( | const TArray< int32 > & | VertexLoop1, |
| const TArray< int32 > & | VertexLoop2 | ||
| ) |
Weld together two loops of vertices. Loops must be oriented (ordered) correctly for your use case.
| Loop1 | first loop of sequential vertices |
| Loop2 | second loop of sequential vertices. These vertices and their edges will not exist after the operation. |
| FDynamicMesh3* UE::Geometry::FDynamicMeshEditor::Mesh |
The mesh we will be editing