Vixen
02b45cc4
csharp
public sealed class EditMesh

An editable mesh: faces over shared positions, with the two graphs kept apart.

Read the guide page for this →

Remarks

Doc 24's D2, and the shape of it is an argument rather than a preference. This is an indexed face set — faces as n-gon loops of corners, corners over shared positions — with an explicit edge table beside it. It is deliberately not a half-edge structure: a half-edge cannot represent a non-manifold edge, and blockout geometry is non-manifold constantly — a wall meeting a floor in a T, a boolean result, an imported mesh with a stray internal face. A kernel that refuses those refuses the ordinary case.

⚠ The position graph and the shading graph are different graphs, and conflating them is the bug this design exists to prevent. A cube's corner is one position and three corners, each with its own normal, its own texture coordinate and possibly its own material. Vertex snapping, welding, edge loops and "drag this corner" run on positions; normals, texture coordinates, materials and smoothing run per corner. One vertex list either splits smooth shading every time it extrudes or welds texture coordinates every time it merges, and both are discovered late, by an artist, in a mesh that is already in a level.

⚠ Faces carry a group id, which is Unreal's PolyGroups and the reason to have them even in a polygon kernel. A boolean returns triangles, and a face that was one wall before the cut has to still be one wall afterwards or the next extrude acts on a sliver. A group is what a tool selects and what a material is assigned to; every operation propagates it.

⚠ Non-manifoldness is reported, not refused. Validate says which edges have more than two faces so that a tool can say "this operation needs a manifold edge" — which is a sentence a designer can act on — instead of producing something wrong or throwing halfway through an edit.

Mutable, and cloned rather than rebuilt for undo. Doc 24's D3: a position change records the positions it touched, and a topology change records the whole mesh, because a boolean has no inverse to record and an undo implemented as an inverse operation is a second implementation of every tool that will disagree with the first.

Fields and properties (13)

  • public const float DefaultWeldTolerance

    How near two positions must be to count as one when a mesh is built from triangles.

  • public const float DefaultCoplanarTolerance

    How nearly parallel two faces must be to be grouped together.

  • public ReadOnlySpan<Vector3> Positions

    The shared positions — the graph a snap, a weld and a drag run on.

  • public ReadOnlySpan<int> Corners

    Every face's corners, in face order: a position index per corner.

  • public IReadOnlyList<MeshFace> Faces

    The faces.

  • public ReadOnlySpan<Vector3> Normals

    Per-corner normals, or empty when the mesh carries none.

  • public ReadOnlySpan<Vector2> TexCoords

    Per-corner texture coordinates, or empty.

  • public int PositionCount

    How many shared positions there are.

  • public int CornerCount

    How many corners there are, over every face.

  • public int FaceCount

    How many faces there are.

  • public bool IsEmpty

    Whether there is anything in it.

  • public IReadOnlyList<MeshEdge> Edges

    The edges, each exactly once, rebuilt when the topology has changed.

  • public BoundingBox Bounds

    The box round every position.

Methods (21)

  • public EditMesh()

    An empty mesh.

  • public EditMesh(EditMesh other)

    A copy of another one.

  • public ReadOnlySpan<int> FacesOf(int edge)

    Which faces an edge belongs to.

  • public int EdgeBetween(int a, int b)

    Which edge runs between two positions.

  • public ReadOnlySpan<int> EdgesAt(int position)

    Which edges meet at a position.

  • public ReadOnlySpan<int> FacesAt(int position)

    Which faces meet at a position.

  • public ReadOnlySpan<int> CornersOf(int face)

    The position indices a face runs through.

  • public int AddPosition(Vector3 position)

    Adds a shared position.

  • public int AddFace(ReadOnlySpan<int> loop, int group = 0, int smoothing = 0)

    Adds a face over positions that are already in the mesh.

  • public void Clear(bool keepPositions = false)

    Empties the face table, and optionally the positions with it.

  • public void MovePosition(int index, Vector3 position)

    Moves one shared position.

  • public void SetGroup(int face, int group)

    Puts a face in a group.

  • public void SetSmoothing(int face, int smoothing)

    Puts a face in a smoothing group.

  • public void SetNormals(ReadOnlySpan<Vector3> values)

    Gives the mesh a per-corner normal layer, sized to its corners.

  • public void SetTexCoords(ReadOnlySpan<Vector2> values)

    Ditto for texture coordinates.

  • public int[] Triangulate()

    Turns the faces into triangles.

  • public static EditMesh FromTriangles(ReadOnlySpan<Vector3> source, ReadOnlySpan<int> indices, float weld = 0.0001, float coplanar = 0.99996)

    Builds a mesh from a triangle soup, welding its positions and grouping its faces.

  • public void Regroup(float coplanar = 0.99996)

    Puts every face into a group with the coplanar faces it is connected to.

  • public Vector3 Normal(int face)

    A face's normal, from its winding.

  • public float Area(int face)

    A face's area.

  • public MeshReport Validate()

    Everything that is true of the mesh that a tool might need to know.

Used by (45, showing 40)

  • EditMeshTestsVixen.Geometry.Tests
  • MeshBooleanVixen.Geometry
  • MeshBooleanPropertyTestsVixen.Geometry.Tests
  • MeshBooleanTestsVixen.Geometry.Tests
  • MeshCollisionVixen.Geometry
  • MeshOperationTestsVixen.Geometry.Tests
  • MeshOperationsVixen.Geometry
  • MeshPropertyTestsVixen.Geometry.Tests
  • MeshSelectionVixen.Geometry
  • MeshSelectionTestsVixen.Geometry.Tests
  • MeshShapeTestsVixen.Geometry.Tests
  • MeshShapesVixen.Geometry
  • MeshSurfaceTestsVixen.Geometry.Tests
  • MeshSurfacesVixen.Geometry
  • MeshTopologyVixen.Geometry
  • MeshTopologyTestsVixen.Geometry.Tests
  • TestShapesVixen.Geometry.Tests
  • BlockoutBooleanVixen.Editor.Blockout
  • BlockoutBooleanTestsVixen.Editor.Blockout.Tests
  • BlockoutCreateVixen.Editor.Blockout
  • BlockoutCreateTestsVixen.Editor.Blockout.Tests
  • BlockoutCubeGridVixen.Editor.Blockout
  • BlockoutGeometryVixen.Editor.Blockout
  • BlockoutGeometryTestsVixen.Editor.Blockout.Tests
  • BlockoutHandoffVixen.Editor.Blockout
  • BlockoutHistoryTestsVixen.Editor.Blockout.Tests
  • BlockoutSelectionVixen.Editor.Blockout
  • BlockoutSelectionTestsVixen.Editor.Blockout.Tests
  • BlockoutSurfaceTestsVixen.Editor.Blockout.Tests
  • BlockoutSurfacesVixen.Editor.Blockout
  • EditMeshCommandVixen.Editor.SceneView
  • EditMeshSceneTestsVixen.Editor.SceneView.Tests
  • EditMeshesVixen.Editor.SceneView
  • ExportPieceVixen.Editor.SceneView
  • MeshEditVixen.Editor.SceneView
  • MeshEditTestsVixen.Editor.SceneView.Tests
  • MeshElementsVixen.Editor.SceneView
  • MeshExportVixen.Editor.SceneView
  • MeshGizmoTargetVixen.Editor.SceneView
  • SceneCsgVixen.Editor.SceneView