MeshDataTool
Working copy of a triangle surface with vertex/edge/face adjacency.
MeshDataTool is an owned RefCounted rather than a Mesh or Entity. CreateFromSurface reads one ArrayMesh Triangles surface and builds local adjacency by indices. Equal positions with different vertex indices are not welded, so UV/normal seams can remain topological boundaries. Dispose an owned tool after use.
using var source = new ArrayMesh();
using var arrays = new Reckfell.Collections.Array();
arrays.Resize((int)Mesh.ArrayType.Max);
arrays[(int)Mesh.ArrayType.Vertex] = new Vector3[] {
Vector3.Zero, new Vector3(1, 0, 0), new Vector3(0, 1, 0)
};
source.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
using var edit = new MeshDataTool();
if (edit.CreateFromSurface(source, 0) != Error.Ok)
throw new System.InvalidOperationException("Cannot read surface");
edit.SetVertex(0, new Vector3(0, 0, 1));
using var output = new ArrayMesh();
if (edit.CommitToSurface(output) != Error.Ok)
throw new System.InvalidOperationException("Cannot commit surface");Editing the tool does not mutate the source Mesh. CommitToSurface appends a new surface to the supplied ArrayMesh rather than replacing the source; use a new ArrayMesh for a separate result. Assign it to the relevant MeshInstance3D to display it. The example does not automatically generate new normals/UVs: prepare required attributes separately after changing geometry.
Vertex/edge/face IDs are local to the current import. A face has three corners and three edges; an edge has two vertex endpoints. GetEdgeFaces can return one, two or more faces, so adjacency does not establish a manifold mesh. These methods do not add/remove vertices or faces. Clear or a new import resets IDs/metadata.
SetVertex changes position without recomputing stored vertex normals/tangents, UVs or skin weights. GetFaceNormal uses current corner positions and can change immediately. Attribute setters enable a channel for the whole surface: populate every vertex when adding a channel. Bone/weight pairs are fixed at four values here; eight-influence roundtrips are unsupported.
Vertex/Edge/Face metadata is tool-local and not saved in the committed surface. Material is a shared reference. Commit does not preserve source custom channels, blend shapes or LODs; this is not a universal lossless imported-mesh editor. Review required channels first.
The combined 34 Windows headless MeshDataTool/TriangleMesh checks used ArrayMesh CPU storage rather than a GPU image. They covered topology, attributes, append commit/reimport, metadata lifetime and BVH. Visible rendering, skeleton deformation, arbitrary topology, custom/blend/LOD fidelity and performance remain unestablished.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
MeshDataToolConstructor
public MeshDataTool();Creates an owned RefCounted with zero counts/format and no material. Import a Triangles surface before indexed access.
Methods41
Clearvoid
public void Clear();Clears working vertices, edges, faces and their metadata; resets material/format. Does not change the source Mesh.
CommitToSurface2 overloads
public Error CommitToSurface(ArrayMesh mesh);Appends a Triangles surface to mesh and assigns current material. Neither replaces an old surface nor clears the tool. Does not serialize metadata/custom channels/blend shapes/LODs; bone/weight channels use 4 values. Error.Ok establishes neither visual correctness nor unsupported-channel fidelity.
| Name | Type | Default |
|---|---|---|
mesh | ArrayMesh | — |
meshNonnull destination ArrayMesh; a surface is appended rather than replaced.
ErrorWrapper Error result; inspect the new surface/log separately rather than treating Ok as visual acceptance.
public Error CommitToSurface(ArrayMesh mesh, ulong compressionFlags = 0);Appends a Triangles surface to mesh and assigns current material. Neither replaces an old surface nor clears the tool. Does not serialize metadata/custom channels/blend shapes/LODs; bone/weight channels use 4 values. Error.Ok establishes neither visual correctness nor unsupported-channel fidelity.
| Name | Type | Default |
|---|---|---|
mesh | ArrayMesh | — |
compressionFlags | ulong | 0 |
meshNonnull destination ArrayMesh; a surface is appended rather than replaced.
compressionFlagsulong surface/compression flags forwarded to AddSurfaceFromArrays, default 0. Do not automatically convert unsupported channels.
ErrorWrapper Error result; inspect the new surface/log separately rather than treating Ok as visual acceptance.
CreateFromSurfaceError
public Error CreateFromSurface(ArrayMesh mesh, int surface);Reads one ArrayMesh Triangles surface, checking nonempty vertices, triangle-divisible indices and index bounds. Without INDEX it uses sequential indices rather than position welding. Successful import replaces state/material; old IDs must not be reused. Does not validate arbitrary manifold topology or every channel length.
| Name | Type | Default |
|---|---|---|
mesh | ArrayMesh | — |
surface | int | — |
meshNonnull ArrayMesh with an existing Triangles surface to import.
surfaceExisting source ArrayMesh surface index.
ErrorError.Ok for accepted import; error handling does not establish arbitrary-channel validation.
GetEdgeCountint
public int GetEdgeCount();Count of unique undirected vertex-index pairs. Equal positions with distinct indices do not weld edges.
intNonnegative current-import element count.
GetEdgeFacesint[]
public int[] GetEdgeFaces(int idx);Returns face IDs using the edge. One is normally a boundary, two a shared edge; more than two is possible and not rejected as nonmanifold.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
int[]New managed array of data/local IDs; editing it does not change the tool.
GetEdgeMetaVariant
public Variant GetEdgeMeta(int idx);Reads current-element metadata Variant. Nil is valid rather than an error-only sentinel. Tool-local metadata rather than a serialized surface field.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
VariantCaller-owned Variant; Nil is valid. Dispose the Variant after use.
GetEdgeVertexint
public int GetEdgeVertex(int idx, int vertex);Returns one of an edge's two vertex IDs. Endpoints are stored in ascending-index order rather than face-winding direction.
| Name | Type | Default |
|---|---|---|
idx | int | — |
vertex | int | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
vertexEdge endpoint selector 0 or 1 rather than a vertex ID.
intLocal vertex/edge ID, or -1 on a diagnosed invalid index.
GetFaceCountint
public int GetFaceCount();Triangle face count rather than index count.
intNonnegative current-import element count.
GetFaceEdgeint
public int GetFaceEdge(int idx, int edge);Returns the edge ID between local corners edge and (edge+1)%3. Stored edge endpoints have canonical order, not necessarily face direction.
| Name | Type | Default |
|---|---|---|
idx | int | — |
edge | int | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
edgeLocal face edge selector 0…2 rather than a global edge ID.
intLocal vertex/edge ID, or -1 on a diagnosed invalid index.
GetFaceMetaVariant
public Variant GetFaceMeta(int idx);Reads current-element metadata Variant. Nil is valid rather than an error-only sentinel. Tool-local metadata rather than a serialized surface field.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal face ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
VariantCaller-owned Variant; Nil is valid. Dispose the Variant after use.
GetFaceNormalVector3
public Vector3 GetFaceNormal(int idx);Computes a Plane unit normal from current corner positions. Neither reads nor updates stored vertex normals. Degenerate faces have no reliable direction.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal face ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
Vector3Geometric normal of current positions rather than a stored vertex normal.
GetFaceVertexint
public int GetFaceVertex(int idx, int vertex);Returns the vertex ID of local corner 0…2 in original triangle-index order.
| Name | Type | Default |
|---|---|---|
idx | int | — |
vertex | int | — |
idxLocal face ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
vertexLocal face corner 0…2 rather than a vertex ID.
intLocal vertex/edge ID, or -1 on a diagnosed invalid index.
GetFormatulong
public ulong GetFormat();Returns ulong mask of imported/enabled channels. Does not establish that Commit preserves every source-format bit; custom and 8-weight data lack complete roundtrip support.
ulongulong channel bit mask; 0 for a new/cleared tool.
GetMaterialMaterial
public Material GetMaterial();Returns the shared current-surface Material or null. Not an independent copy; do not dispose an alias still used by an owner.
MaterialShared Material or null, not a copy.
GetVertexVector3
public Vector3 GetVertex(int idx);Reads vertex-record position. Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
Vector3Current local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexBonesint[]
public int[] GetVertexBones(int idx);Reads vertex-record four bone indices. Returns an independent managed array; editing it does not mutate the tool.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
int[]New managed array of data/local IDs; editing it does not change the tool.
GetVertexColorColor
public Color GetVertexColor(int idx);Reads vertex-record color. Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
ColorCurrent local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexCountint
public int GetVertexCount();Current imported vertex-record count rather than unique-position count.
intNonnegative current-import element count.
GetVertexEdgesint[]
public int[] GetVertexEdges(int idx);Returns copied local edge IDs incident to a vertex record, not traversal of the entire connected component.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
int[]New managed array of data/local IDs; editing it does not change the tool.
GetVertexFacesint[]
public int[] GetVertexFaces(int idx);Returns copied face IDs containing the vertex record without position welding.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal face ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
int[]New managed array of data/local IDs; editing it does not change the tool.
GetVertexMetaVariant
public Variant GetVertexMeta(int idx);Reads current-element metadata Variant. Nil is valid rather than an error-only sentinel. Tool-local metadata rather than a serialized surface field.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
VariantCaller-owned Variant; Nil is valid. Dispose the Variant after use.
GetVertexNormalVector3
public Vector3 GetVertexNormal(int idx);Reads vertex-record stored normal. Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
Vector3Current local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexTangentPlane
public Plane GetVertexTangent(int idx);Reads vertex-record tangent in Plane (Normal=xyz, D=handedness). Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
PlaneCurrent local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexUVVector2
public Vector2 GetVertexUV(int idx);Reads vertex-record first UV. Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
Vector2Current local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexUV2Vector2
public Vector2 GetVertexUV2(int idx);Reads vertex-record second UV. Working data rather than world-transformed values.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
Vector2Current local vertex-attribute value; a diagnosed fallback does not establish a valid index.
GetVertexWeightsfloat[]
public float[] GetVertexWeights(int idx);Reads vertex-record four weights. Returns an independent managed array; editing it does not mutate the tool.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
float[]New managed array of data/local IDs; editing it does not change the tool.
SetEdgeMetavoid
public void SetEdgeMeta(int idx, Variant meta);Stores element metadata only in the tool. Variant containers are not deep-cloned; Commit omits metadata and Clear/new import removes it.
| Name | Type | Default |
|---|---|---|
idx | int | — |
meta | Variant | — |
idxLocal edge ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
metaMetadata Variant; explicitly copy shared containers when needed.
SetFaceMetavoid
public void SetFaceMeta(int idx, Variant meta);Stores element metadata only in the tool. Variant containers are not deep-cloned; Commit omits metadata and Clear/new import removes it.
| Name | Type | Default |
|---|---|---|
idx | int | — |
meta | Variant | — |
idxLocal face ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
metaMetadata Variant; explicitly copy shared containers when needed.
SetMaterialvoid
public void SetMaterial(Material material);Stores a shared reference for the next CommitToSurface without immediately changing the source Mesh. null clears the selected material.
| Name | Type | Default |
|---|---|---|
material | Material | — |
materialShared Material or null for the next Commit rather than an immediate source-mesh edit.
SetVertexvoid
public void SetVertex(int idx, Vector3 vertex);Writes vertex-record position. Does not recompute normals/tangents, UVs, source-Mesh bounds or topology.
| Name | Type | Default |
|---|---|---|
idx | int | — |
vertex | Vector3 | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
vertexNew local vertex position.
SetVertexBones2 overloads
public void SetVertexBones(int idx, int[] bones);Writes vertex-record four bone indices. Requires exactly 4 values and enables the channel. When first adding it, prepare matching bones/weights for every vertex; no normalization is performed.
| Name | Type | Default |
|---|---|---|
idx | int | — |
bones | int[] | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
bonesExactly four bone indices; prepare four corresponding weights.
public void SetVertexBones(int idx, ReadOnlySpan<int> bones);Writes vertex-record four bone indices. Requires exactly 4 values and enables the channel. When first adding it, prepare matching bones/weights for every vertex; no normalization is performed.
| Name | Type | Default |
|---|---|---|
idx | int | — |
bones | ReadOnlySpan<int> | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
bonesExactly four bone indices; prepare four corresponding weights.
SetVertexColorvoid
public void SetVertexColor(int idx, Color color);Writes vertex-record color. Enables the surface channel; populate all vertices. Does not automatically generate coherent remaining attributes.
| Name | Type | Default |
|---|---|---|
idx | int | — |
color | Color | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
colorVertex color; material must use this channel.
SetVertexMetavoid
public void SetVertexMeta(int idx, Variant meta);Stores element metadata only in the tool. Variant containers are not deep-cloned; Commit omits metadata and Clear/new import removes it.
| Name | Type | Default |
|---|---|---|
idx | int | — |
meta | Variant | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
metaMetadata Variant; explicitly copy shared containers when needed.
SetVertexNormalvoid
public void SetVertexNormal(int idx, Vector3 normal);Writes vertex-record stored normal. Enables the surface channel; populate all vertices. Does not automatically generate coherent remaining attributes.
| Name | Type | Default |
|---|---|---|
idx | int | — |
normal | Vector3 | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
normalUnit local vertex normal; not automatically normalized by the setter.
SetVertexTangentvoid
public void SetVertexTangent(int idx, Plane tangent);Writes vertex-record tangent in Plane (Normal=xyz, D=handedness). Enables the surface channel; populate all vertices. Does not automatically generate coherent remaining attributes.
| Name | Type | Default |
|---|---|---|
idx | int | — |
tangent | Plane | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
tangentPlane: Normal stores tangent xyz, D handedness, normally ±1.
SetVertexUVvoid
public void SetVertexUV(int idx, Vector2 uV);Writes vertex-record first UV. Enables the surface channel; populate all vertices. Does not automatically generate coherent remaining attributes.
| Name | Type | Default |
|---|---|---|
idx | int | — |
uV | Vector2 | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
uVCorresponding UV-channel value rather than a vertex position.
SetVertexUV2void
public void SetVertexUV2(int idx, Vector2 uV2);Writes vertex-record second UV. Enables the surface channel; populate all vertices. Does not automatically generate coherent remaining attributes.
| Name | Type | Default |
|---|---|---|
idx | int | — |
uV2 | Vector2 | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
uV2Corresponding UV-channel value rather than a vertex position.
SetVertexWeights2 overloads
public void SetVertexWeights(int idx, ReadOnlySpan<float> weights);Writes vertex-record four weights. Requires exactly 4 values and enables the channel. When first adding it, prepare matching bones/weights for every vertex; no normalization is performed.
| Name | Type | Default |
|---|---|---|
idx | int | — |
weights | ReadOnlySpan<float> | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
weightsExactly four nonnegative normalized weights; not normalized automatically.
public void SetVertexWeights(int idx, float[] weights);Writes vertex-record four weights. Requires exactly 4 values and enables the channel. When first adding it, prepare matching bones/weights for every vertex; no normalization is performed.
| Name | Type | Default |
|---|---|---|
idx | int | — |
weights | float[] | — |
idxLocal vertex ID: 0 ≤ idx < corresponding Count, not an Entity/resource ID.
weightsExactly four nonnegative normalized weights; not normalized automatically.