Geometry Script Users Guide

A guide to using Geometry Script Fuctions and Blueprint Nodes

What is Geometry Script?

Geometry Script is an Unreal Engine plugin containing a set of Function Libraries that provide the ability to generate and edit mesh geometry via Blueprints and Python.

Geometry Script UFunctions and Blueprint Nodes operate on UDynamicMesh objects, which are objects created using the FDynamicMesh3 C++ triangle mesh data structure. This is the same data structure used by the Geometry Processing Plugin and Modeling Editor Mode.

Geometry Script can be used in Editor Utility Widgets and Asset Actions to create custom mesh analysis / processing / editing tools. It can also be used in Actor Blueprints to create "procedural objects" and implement complex geometric queries.

Geometry Script has a variety of potential uses:

  • Testing and quality analysis of third-party mesh importers.

  • Analyzing mesh UVs to identify assets with wasted texture space.

  • Scripted merging of mesh assets for production workflows.

  • Procedural mesh Actors such as the Level Design Tool Objects used in the Lyra Sample Game.

DynamicMesh Objects

Geometry Script operates on several new object types:

  • UDynamicMesh

  • UDynamicMeshComponent

  • ADynamicMeshActor

Similar to the Static Mesh / StaticMeshComponent / StaticMeshActor architecture, these classes are not specifically part of the Geometry Script plugin - they are located in the Geometry Framework engine module, and can be used separately from Geometry Script.

UDynamicMesh

The core component that enables Geometry Script is the UDynamicMesh object. This UObject is a container for a mesh data structure that is not tied to a specific Component. This diverges from previous Unreal Engine approaches like UProceduralMeshComponent in that mesh geometry can be created and manipulated without an explicit scene representation.

For example, a UDynamicMesh can be initialized based on a UStaticMesh Asset, edited, and then stored back in the Asset. Combined with Editor Utility Widgets to provide the user interface, this approach allows tech artists to create custom purpose-built mesh editing tools in Blueprint, or to script Mesh Asset query/editing operations via Python.

Various other Editor mesh geometry types can also be converted to/from UDynamicMesh, such as Gameplay Volumes.

DynamicMeshComponent

In addition to UDynamicMesh, UDynamicMeshComponent has been promoted into a "real" (non-transient, serializable) Component. This Component is similar in spirit to a UProceduralMeshComponent, however it is backed by a UDynamicMesh, which can then be manipulated via GeometryScript.

UDynamicMeshComponent has been developed over the past several years as part of the Mesh Modeling Toolset, where it has been used to provide realtime previews of mesh editing. Similar to UProceduralMeshComponent, it supports updates to the mesh geometry - not just updating vertex attributes, but also creating and modifying the entire mesh topology. This can be done both in-Editor and at Runtime. Raytracing is supported, however Nanite and Lumen are not.

DynamicMeshActor

ADynamicMeshActor is similar to AStaticMeshActor in that it is largely a container for a UDynamicMeshComponent. However, DynamicMeshActor does provide some specific support for Actor Blueprints that wish to implement procedural mesh generation based on UDynamicMesh.

Modeling Mode Tools that previously could only create new StaticMesh Assets can now also create new DynamicMeshActors, and the editing Tools can edit either type of mesh Actor (in addition to Volumes).

GeneratedDynamicMeshActor

AGeneratedDynamicMeshActor is a subclass of ADynamicMeshActor that provides additional support for implementing Blueprint-based procedural mesh Actors. Specifically, this class provides the function On Rebuild Generated Mesh that can be implemented in BP Subclasses to generate a mesh, instead of doing so in the Construction Script. This provides better in-Editor interactive performance, and leaves the door open to more carefully managed large-scale procedural geometry generation in the future.

GeneratedDynamicMeshActor is currently Editor-Only.

Key Differences between UStaticMesh and UDynamicMesh

Unlike UStaticMesh, UDynamicMesh is not an Asset. A UDynamicMeshComponent "owns" its UDynamicMesh, it is not shared between multiple Components like a UStaticMesh is. This means, for example, that Instanced rendering is not available. The UStaticMesh is stored as part of the Component (and the Actor), similar to ProceduralMeshComponent. This means that the mesh is stored "In the Level", not in a separate asset file. Duplicating a UDynamicMeshComponent creates a copy of the mesh, and transferring between levels or projects must be done via copy-paste.

In many ways, UDynamicMeshComponent behaves much more like mesh objects in a DCC tool, such as Autodesk 3ds Max, Autodesk Maya, or Blender. This does introduce potential problems with huge meshes dramatically increasing the size of the level file. However, with One File Per Actor, the mesh data will be stored with the OFPA Actor file, rather than the level (so, still potentially huge, but in a separate file).

GeometryScript Function/Node Pattern

The majority of Geometry Script functions/nodes follow a very standard pattern similar to the Apply Mesh Plane Cut node shown below.

The first argument, Target Mesh, is the UDynamicMesh that will be edited by the operation. Generally, Geometry Script operations modify the input mesh, rather than creating a new mesh, to avoid creating several temporary mesh objects. The input UDynamicMesh is always also returned as an output, also called Target Mesh (same name == same object). This makes it easy to chain multiple operations in sequence.

Geometry Script nodes have many parameters and settings. The most frequently used options are exposed as arguments, but more options are provided via an operation-specific Options structure. The most common way to create the right Options structure is to drag off the empty Options pin. This is not necessary unless you wish to modify the defaults. In addition, you can right-click on the Options pin and use the Split Struct Pin context menu item to directly expand the Options structure in the node, as shown below.

Most nodes also have a Debug pin to provide geometric debugging support for mesh generators. This is not actively being used, but is a placeholder for future functionality.

Using UDynamicMesh Pools

It is common to need to create temporary meshes inside a mesh generator, for example creating a primitive mesh to be subtracted from the "main" mesh. To do this, a temporary UDynamicMesh is needed. While one can be created using ConstructObjectFromClass, if this is done in a procedural generator, that mesh must be Garbage Collected after usage. If the generator is run frequently then it is more efficient to re-use the mesh across runs.

DynamicMeshActor has built-in support for this using a UDynamicMeshPool. This can be done by calling AllocateComputeMesh to get a temporary mesh, and then release it somewhere before the end of the Blueprint execution path. Each temporary mesh can be explicitly released using ReleaseComputeMesh, or by calling ReleaseAllComputeMeshes, which will release any temporary meshes currently allocated from the pool.

In an Editor Utility Widget, there is no default DynamicMeshPool instance to allocate meshes from, however you can use CreateDynamicMeshPool to create one (for example, as a variable in the Editor Utility Widget or Utility Blueprint.)

Creating a Procedural Mesh Object using Actor Blueprints

As noted above, one exciting use case for GeometryScript is to create procedural mesh "objects" using Actor Blueprints. An example is shown below, using a BP subclass of GeneratedDynamicMeshActor. The On Rebuild Generated Mesh Event is used to populate the UDynamicMesh of a UDynamicMeshComponent. These classes are described in the Geometry Script Reference. The UDynamicMesh is passed to a GeometryScript function Append Box, which creates a mesh based on the input variables.

The clip below shows an example of using an instance of this BP Actor - essentially we have created a parametric box primitive mesh, with just a few BP nodes. By adding additional nodes we can build increasingly complex mesh generators directly in Blueprints. The current GeometryScript library contains over 150 functions/nodes for mesh generation and editing.

Procedural Mesh with Geometry Scripting