GeometryScript¶
69 tools. Back to the index.
append_mesh_primitive¶
Additive.
Append a Box, Sphere, Cylinder or Cone to the live dynamic mesh of a DynamicMeshActor in the editor world, keeping the geometry already there: size is the box edge or the diameter and height of the round shapes, centred at location in mesh-local space. Each call adds another copy, inside an editor transaction; nothing is saved to an asset. An unknown actor or primitive is an error; appended is true when the triangle count grew. To merge another actor's mesh use append_mesh_to_dynamic_mesh; to persist the result, copy_dynamic_mesh_to_static_mesh.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
primitive |
string | no | Box, Sphere, Cylinder, or Cone, default Box |
size |
number | no | Dominant dimension in cm, default 100 |
location |
array | no | Optional local [x, y, z] offset for the primitive |
dimensions |
number | no | Fallback alias for size when size is omitted (cm) |
material_id |
number | no | Optional MaterialID stamped on the appended triangles (default 0). Non-zero enables the mesh MaterialID attribute first, so a later copy_dynamic_mesh_to_static_mesh (bUseSectionMaterials=true) emits this piece as its own section/material slot. This is how one dynamic mesh becomes a multi-slot static mesh. |
Returns: { actor_name: string, primitive: string, size: number, material_id: int, triangle_count: int, triangles_added: int, vertex_count: int, appended: bool }
append_mesh_to_dynamic_mesh¶
Additive.
Merge another UDynamicMesh into the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_MeshBasicEditFunctions::AppendMesh.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor (the receiver) |
source_actor_name |
string | yes | Label or name of the DynamicMeshActor whose dynamic mesh will be merged in |
append_transform |
array | no | Optional [x,y,z] world-space transform applied to the source mesh before merging (default identity) |
Returns: { actor_name, source_actor_name, triangles_before, triangles_after, triangles_added, vertex_count_after, appended: true }
apply_adaptive_remesh¶
Destructive.
Adaptive-remesh a DynamicMeshActor's dynamic mesh using a target edge length and optional weight map
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
max_edge_length |
number | yes | Target edge length for adaptive remesh (sets TargetType=TargetEdgeLength + TargetEdgeLength). Required. |
min_edge_length |
number | no | Soft floor for adaptive edge length (default 1.0). NOTE: FGeometryScriptAdaptiveRemeshOptions has no explicit min field — this is echoed back in the result for traceability but is NOT consulted by the engine call. |
relative_density |
number | no | Density adjustment in [-2.0, 2.0] passed to FGeometryScriptAdaptiveRemeshOptions::RelativeDensity (default 0.0). |
weight_map_name |
string | no | Optional name of an existing vertex weight map (resolved via UGeometryScriptLibrary_MeshQueryFunctions::GetWeightMapHandle). If omitted or the mesh does not have such a layer, the engine runs adaptive remesh without a weight map (its default invalid handle). |
Returns: { actor_name: string, min_edge_length: number, max_edge_length: number, relative_density: number, weight_map_name: string, weight_map_resolved: bool, target_type: string, triangle_count: int, triangle_count_before: int, vertex_count: int, remeshed: bool }
apply_mesh_boolean¶
Destructive.
Apply a CSG boolean (Subtract by default, Union or Intersect) between the live dynamic mesh of a DynamicMeshActor in the editor world and a temporary primitive tool: other_primitive (Sphere by default) of size cm, offset by location in mesh-local space. The target is changed in place inside an editor transaction, nothing is saved, and each call cuts or merges again. An unknown actor, operation or primitive is an error. When the engine refuses the result (an empty one, such as subtracting from an empty mesh) the mesh is left unchanged, boolean_applied is false and the call fails. To use another actor's mesh as the tool call apply_mesh_boolean_actor_to_actor.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
operation |
string | no | Union, Subtract, or Intersect, default Subtract |
other_primitive |
string | no | Tool primitive shape, default Sphere |
size |
number | no | Tool primitive size in cm, default 100 |
location |
array | no | Optional tool [x, y, z] offset |
dimensions |
number | no | Fallback alias for size when size is omitted (cm) |
Returns: { actor_name: string, operation: string, other_primitive: string, triangle_count: int, triangle_count_before: int, vertex_count: int, boolean_applied: bool }
apply_mesh_boolean_actor_to_actor¶
Destructive.
Apply a CSG boolean using a second DynamicMeshActor as the cutting tool. Unlike apply_mesh_boolean (which builds a transient primitive tool), the tool geometry is the live dynamic mesh of source_actor_name. The target mesh is mutated in place; the source mesh is left untouched. NOT idempotent: re-running keeps cutting/merging the same tool against the already-modified target. When the engine refuses the result (an empty one) the target is left unchanged, boolean_applied is false and the call fails.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor (the receiver, mutated in place) |
source_actor_name |
string | yes | Label or name of the DynamicMeshActor whose live dynamic mesh is used as the boolean tool |
operation |
string | no | Union, Subtract, or Intersect, default Subtract |
use_world_transforms |
boolean | no | Optional bool, default true. When true the tool is positioned by the relative world transform (source relative to target) so the boolean respects the actors' placement; when false the tool is applied at identity (co-located). |
fill_holes |
boolean | no | Optional bool override for FGeometryScriptMeshBooleanOptions.bFillHoles (default true) |
simplify_output |
boolean | no | Optional bool override for FGeometryScriptMeshBooleanOptions.bSimplifyOutput (default true) |
Returns: { actor_name: string, source_actor_name: string, operation: string, triangle_count: int, triangle_count_before: int, vertex_count: int, boolean_applied: bool }
apply_mesh_morphology¶
Destructive.
Apply an SDF-based morphology op (dilate/contract/close/open) to a DynamicMeshActor's dynamic mesh. Replaces the mesh with an SDF-based offset mesh approximation.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
operation |
string | yes | Required. One of: dilate, contract, close, open. |
distance |
number | yes | Required positive float. Offset distance in cm (SDF-based). |
Returns: { actor_name, operation, distance, triangle_count, triangle_count_before, vertex_count, morphed }
apply_mesh_solidify¶
Destructive.
Voxel-wrap a DynamicMeshActor's dynamic mesh (replaces the mesh with a voxelised-and-meshed approximation).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
winding_threshold |
number | no | Optional [0..1], default 0.5. Space with generalised winding number above this is considered inside. |
extend_bounds |
number | no | Optional positive float, default 1.0. Bounds extension applied to the default input-mesh-based bounds. |
surface_search_steps |
number | no | Optional int >= 1, default 3. Marching-cubes vertex search steps. |
thicken_shells |
boolean | no | Optional bool, default false. Thicken open shells into closed solids (expensive on large meshes). |
shell_thickness |
number | no | Optional positive float, default 1.0. Offset distance for shell thickening. |
Returns: { actor_name, triangle_count, triangle_count_before, vertex_count, solidified }
apply_uniform_remesh¶
Destructive.
Remesh the live dynamic mesh of a DynamicMeshActor in the editor world into evenly sized triangles, aiming at target_edge_length (cm) or target_tri_count: exactly one is required, else an error. The mesh changes in place inside an editor transaction and the actor's package is marked dirty, not saved. smoothing_type picks uniform, UV-preserving or mixed smoothing; an unknown value is an error. The reply echoes the settings the engine was given. remeshed is true when the triangle or vertex count changed. For variable density use apply_adaptive_remesh; to only reduce triangles, simplify_mesh.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
target_edge_length |
number | no | Target uniform edge length in mesh units (sets TargetType=TargetEdgeLength). Mutually exclusive with target_tri_count; at least one is required. |
target_tri_count |
number | no | Approximate target triangle count (sets TargetType=TriangleCount). Mutually exclusive with target_edge_length. |
preserve_sharp_edges |
boolean | no | Approximate 'preserve sharp edges' by enabling bPreventNormalFlips on the shared RemeshOptions (default true; UE's FGeometryScriptUniformRemeshOptions has no explicit preserve-sharp flag, so the closest equivalent is the shared RemeshOptions.bPreventNormalFlips). |
smoothing_type |
string | no | One of 'uniform' | 'uv_preserving' | 'mixed' (default 'mixed'); maps to EGeometryScriptRemeshSmoothingType on the shared RemeshOptions. |
auto_compact |
boolean | no | Auto-compact the index space after remesh on the shared RemeshOptions (default true). |
Returns: { actor_name: string, target_edge_length: number, target_tri_count: int, preserve_sharp_edges: bool, smoothing_type: string, auto_compact: bool, target_type: string, triangle_count: int, triangle_count_before: int, vertex_count: int, remeshed: bool }
auto_generate_mesh_uvs¶
Destructive.
Compute a real UV UNWRAP for the whole mesh via UGeometryScriptLibrary_MeshUVFunctions::AutoGeneratePatchBuilderMeshUVs or AutoGenerateXAtlasMeshUVs. This is what sits behind the editor's "Auto UV" button. Use it when a projection is not enough (organic or mixed-orientation geometry); for plank-and-post shapes set_mesh_uvs_from_projection with box is usually cleaner and far cheaper. Both methods PACK the result into standard UV space by default, so island layout is handled too. SLOW on dense meshes: this is a solver, not a projection. A UV channel the mesh does not have, or an empty mesh, is an error; applied is false, and the call fails, when the solver reports an error (xatlas needs a compact mesh: run compact_mesh first).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
method |
string | no | 'patch_builder' (default, the editor's Auto UV) or 'xatlas'. |
uv_channel |
number | no | UV channel to write (default 0). |
initial_patch_count |
number | no | patch_builder: how many patches to seed (default 100). More patches = less distortion, more seams. |
min_patch_size |
number | no | patch_builder: minimum triangles per patch (default 2). |
merging_threshold |
number | no | patch_builder: patch merging metric threshold (default 1.5). Higher merges more aggressively, giving fewer islands. |
max_angle_deg |
number | no | patch_builder: max angle in degrees between merged patches (default 45). |
respect_polygroups |
boolean | no | patch_builder: seed patches from the existing polygroups instead of curvature (default false). Useful right after append_mesh_primitive, where each appended face is already its own group. |
auto_pack |
boolean | no | Pack the resulting islands into standard UV space (default true). |
max_iterations |
number | no | xatlas: solver iterations (default 2). Higher is slower and slightly tighter. |
Returns: { actor_name, method, uv_channel, triangle_count: int, uv_channel_count: int, applied: bool }
build_mesh_bvh¶
Read-only.
Build a BVH (bounding volume hierarchy) for the live dynamic mesh of a DynamicMeshActor in the editor world with BuildBVHForMesh, and read it back with IsBVHValidForMesh. The plugin keeps no BVH between calls: this one is dropped on return, and the spatial-query tools (find_nearest_point_on_mesh, find_nearest_ray_intersection_with_mesh, is_point_inside_mesh) build their own on every call, so they never need this first. It checks that a BVH can be built for the mesh as it is now: built is true when the engine reported no error and the BVH reads back as valid; the call fails otherwise. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
b_only_if_invalid |
boolean | no | Optional bool, default true; it has no effect, since no earlier BVH is kept and every call builds a new one. |
Returns: { actor_name, built: bool, b_only_if_invalid: bool, bvh_valid: bool, vertex_count, triangle_count } -- actor_name is the dynamic mesh component's name, not the actor label; b_only_if_invalid echoes the request; the counts are those of the mesh the BVH was built for.
clear_dynamic_mesh¶
Destructive, idempotent.
Empty a DynamicMeshActor's live UDynamicMesh in place (keep the actor, drop the geometry).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the DynamicMeshActor to clear (required). |
Returns: { actor_name: string, triangle_count_before: int, triangle_count_after: int, vertex_count_before: int, vertex_count_after: int, cleared: bool }
compact_mesh¶
Destructive.
Compact vertex and triangle ID lists on a DynamicMeshActor's dynamic mesh
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
Returns: { actor_name: string, triangle_count: int, vertex_count: int, compacted: bool }
copy_dynamic_mesh_to_static_mesh¶
Destructive, idempotent.
Write the live dynamic mesh of a DynamicMeshActor INTO an EXISTING /Game UStaticMesh asset's LOD via UGeometryScriptLibrary_StaticMeshFunctions::CopyMeshToStaticMesh (7-arg V2, bUseSectionMaterials=true; engine-default options). Editor-only (the engine function is WITH_EDITOR-gated and touches GEditor + FlushRenderingCommands). Idempotent: overwrites the target LOD in place, no duplication. HONEST GATES: the target asset must already exist (create it first, e.g. via create_editable_static_mesh) and must NOT live under /Engine/ (the engine refuses to modify built-in engine assets). A lod_index outside 0 to 7 (a static mesh has at most 8 LODs) is an error checked before anything changes; one past the asset's last LOD adds the LODs in between, which the engine sets up to be reduced from an earlier LOD.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the source DynamicMeshActor. |
target_static_mesh_path |
string | yes | Content path of an EXISTING /Game UStaticMesh to overwrite. |
lod_index |
number | no | Optional target LOD index, 0 to 7 (default 0); a negative index or one of 8 or more is refused. |
materials |
array | no | Optional ordered list of UMaterialInterface content paths, one per MaterialID (index 0 = MaterialID 0). Supplying it flips bReplaceMaterials on, so the target asset gets exactly these material slots. WITHOUT this the asset keeps its existing slots and a multi-MaterialID mesh collapses into whatever slots already existed — this is the parameter that makes per-triangle MaterialIDs visible on the saved asset. |
material_slot_names |
array | no | Optional slot names matching materials 1:1 (default: the engine names them). Ignored when materials is absent. |
Returns: { actor_name, target_static_mesh_path, lod_index, outcome_success: bool, source_triangle_count, material_count: int, replaced_materials: bool, wrote: bool }. NOTE: this marks the target package dirty (transaction) but does NOT save to disk — persistence requires a separate save (e.g. via save_asset).
copy_mesh_uv_channel¶
Additive.
Copy UV data from one UV channel to another on the same mesh. A dest_channel the mesh does not have yet is added first (the channel count only grows, and channels added in between have no UVs set); a source_channel the mesh does not have, or a dest_channel of 8 or more, is an error checked before anything changes. copied is false, and the call fails, when the engine reports an error; the same channel for both is a no-op that succeeds with copied false and a note. No undo entry, nothing saved.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
source_channel |
number | yes | Source UV channel index (required) |
dest_channel |
number | yes | Destination UV channel index, 0 to 7 (required, added to the mesh when it does not have it yet) |
Returns: { actor_name: string, source_channel: int, dest_channel: int, copied: bool, num_uv_channels_after: int, note?: string } -- actor_name is the dynamic mesh component's name, not the actor label; copied is false when source_channel equals dest_channel, and note says so or that the mesh grew new channels to reach dest_channel.
copy_static_mesh_to_dynamic_mesh¶
Destructive, idempotent.
Copy the geometry of a UStaticMesh asset INTO the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_StaticMeshFunctions::CopyMeshFromStaticMesh (engine-default options: build settings applied, tangents on). Destructive replace of the actor's current mesh. Idempotent-ish: re-running re-extracts the same source geometry (result depends only on the source asset + LOD). Reads the MaxAvailable LOD (LODIndex clamped to the asset's available LODs) so it is robust across meshes with fewer LODs.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_static_mesh_path |
string | yes | Content path of the source UStaticMesh (e.g. "/Engine/BasicShapes/Cube"). |
actor_name |
string | yes | Label or name of the target DynamicMeshActor whose GetDynamicMesh() receives the geometry. |
lod_index |
number | no | Optional source LOD index (default 0). LODType is MaxAvailable, so the index is silently clamped to the asset's LOD count. |
Returns: { source_static_mesh_path, actor_name, lod_index, outcome_success: bool, triangle_count, vertex_count, copied: bool }
delete_selected_triangles_from_mesh¶
Destructive.
Delete the listed triangle IDs from a DynamicMeshActor's live dynamic mesh in the editor world; IDs that do not exist are skipped, so compare num_deleted with requested_count. No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
triangle_ids |
array | yes | Non-empty array of non-negative integer triangle IDs, e.g. [0, 5, 12]; any negative or non-numeric entry fails the call. |
Returns: { actor_name, num_deleted, requested_count, triangle_count, previous_triangle_count }
delete_triangle_from_mesh¶
Destructive.
Delete one triangle by ID from a DynamicMeshActor's live dynamic mesh in the editor world; a missing ID is not an error, deleted just comes back false. No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
triangle_id |
number | yes | Non-negative integer ID of the triangle to delete. |
Returns: { actor_name, triangle_id, deleted, triangle_count, previous_triangle_count }
find_nearest_point_on_mesh¶
Read-only.
Find the nearest point on the live dynamic mesh of a DynamicMeshActor to a 3D query point via UGeometryScriptLibrary_MeshSpatial::FindNearestPointOnMesh. Every call builds a fresh BVH from the mesh as it is now (the plugin keeps none), then queries it, so the answer always reflects the latest mesh edits. found is false when no triangle lies within max_distance, or the mesh is empty. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
query_point |
array | no | [x, y, z] query point in the mesh's local space. |
max_distance |
number | no | Optional float; max search distance (0 = unlimited). |
allow_unsafe_modified |
boolean | no | Optional; maps to bAllowUnsafeModifiedQueries (default false). It has no effect: the BVH is built fresh on every call, so it always matches the mesh. |
Returns: { actor_name, found: bool, valid: bool, triangle_id, position_x/y/z, bary_coords_x/y/z } -- actor_name is the dynamic mesh component's name, not the actor label.
find_nearest_ray_intersection_with_mesh¶
Read-only.
Cast a ray against the live dynamic mesh of a DynamicMeshActor and return the nearest hit via UGeometryScriptLibrary_MeshSpatial::FindNearestRayIntersectionWithMesh. Every call builds a fresh BVH from the mesh as it is now (the plugin keeps none), so the answer always reflects the latest mesh edits. The engine normalizes ray_direction, so ray_parameter is the distance from ray_origin to the hit. hit is false when nothing is hit within max_distance. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
ray_origin |
array | no | [x, y, z] origin point of the ray in mesh-local space. |
ray_direction |
array | no | [x, y, z] direction of the ray; the engine normalizes it, so its length does not matter. |
max_distance |
number | no | Optional float; max search distance (0 = unlimited). |
allow_unsafe_modified |
boolean | no | Optional; maps to bAllowUnsafeModifiedQueries (default false). It has no effect: the BVH is built fresh on every call, so it always matches the mesh. |
Returns: { actor_name, hit: bool, ray_parameter, hit_triangle_id, hit_position_x/y/z, hit_bary_coords_x/y/z } -- actor_name is the dynamic mesh component's name, not the actor label; ray_parameter is a distance along the normalized direction.
generate_mesh_uvs¶
Destructive, idempotent.
Planar-project UVs for the whole live dynamic mesh of a DynamicMeshActor in the editor world into channel uv_channel, overwriting it: the projection runs down mesh-local Z with 1 UV unit per cm, not fitted to 0-1. A missing channel is added first (the channel count only grows, so higher channels such as a lightmap UV1 are kept). uv_channel 8 or more, or an empty mesh, is an error checked before anything changes; uvs_generated is false (the call fails) when the engine reports an error. Idempotent, in an editor transaction, nothing saved. For box, cylinder or region projections use set_mesh_uvs_from_projection; for a real unwrap, auto_generate_mesh_uvs.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
uv_channel |
number | no | UV set index to write, 0 to 7, default 0 |
Returns: { actor_name: string, uv_channel: int, uv_channel_count: int, triangle_count: int, vertex_count: int, uvs_generated: bool }
get_dynamic_mesh_info¶
Read-only.
Read geometry stats off a DynamicMeshActor's live dynamic mesh
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
Returns: { actor_name: string, actor_internal_name: string, triangle_count: int, vertex_count: int, is_closed: bool, is_empty: bool }
get_is_dense_mesh¶
Read-only.
Return true if the mesh's triangle IDs are dense (no gaps after deletions).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
Returns: { actor_name, is_dense }
get_mesh_bounding_box¶
Read-only.
Read the local-space axis-aligned bounding box of a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetMeshBoundingBox.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset (e.g. "/Game/Meshes/SM_Cube") |
lod_index |
number | no | Optional LOD index to query (default 0, MaxAvailable) |
Returns: { static_mesh_path, lod_index, min_x, min_y, min_z, max_x, max_y, max_z, extent_x, extent_y, extent_z, center_x, center_y, center_z }
get_mesh_components_detail¶
Read-only.
Enumerate the connected components (physical pieces) of a DynamicMeshActor's live dynamic mesh via UE::Geometry::FMeshConnectedComponents, reporting for EACH island its triangle count, its local-space bounding box, its triangle_id range and which MaterialIDs it carries. Read-only (unlike the engine's SplitMeshByComponents, which consumes the mesh). This is the map of a mesh in ONE call, and the tool to reach for BEFORE painting anything: get_mesh_material_ids says how many triangles carry each material, and this says what those triangles physically ARE. HONEST GATE: it names nothing — it gives you sizes and positions, and which island is which part is still a human call; what it prevents is deriving that from a triangle-count assumption.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
max_components |
number | no | Cap on how many islands to return (default 64). components_truncated says whether the cap cut the list; component_count is always the real total. |
include_triangle_ids |
boolean | no | Also return each island's full triangle ID list (default false; use the reported id_min/id_max range instead unless the island is non-contiguous). |
Returns: { actor_name, component_count: int, components_truncated: bool, components: [ { index, triangle_count, id_min, id_max, id_contiguous: bool, material_ids: [int], bounds: { min_x, min_y, min_z, max_x, max_y, max_z, center_x, center_y, center_z, size_x, size_y, size_z }, triangle_ids: [int] } ] }
get_mesh_connected_components¶
Read-only.
Count the number of topologically separate connected components (islands) in a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetNumConnectedComponents.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, connected_components }
get_mesh_has_attribute_set¶
Read-only.
Return true if the mesh has at least one attribute set registered.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
Returns: { actor_name, has_attribute_set }
get_mesh_is_closed¶
Read-only.
Test whether a static mesh has no topological boundary edges (i.e. is a closed manifold) via UGeometryScriptLibrary_MeshQueryFunctions::GetIsClosedMesh.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, is_closed }
get_mesh_material_ids¶
Read-only.
Read the per-triangle MaterialID distribution of a DynamicMeshActor's live dynamic mesh via UGeometryScriptLibrary_MeshMaterialFunctions::GetMaxMaterialID + GetAllTriangleMaterialIDs. Read-only. This is the ORACLE for every MaterialID write: it returns a per-ID triangle histogram, so "did the paint actually land?" is answerable with a read instead of trusting a success flag. IMPORTANT: has_material_ids=false means the mesh has no MaterialID attribute at all, which is exactly the state in which writes are silently dropped by the engine.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
Returns: { actor_name, has_material_ids: bool, max_material_id: int, triangle_count: int, distinct_material_ids: int, histogram: [ { material_id: int, triangle_count: int } ] }
get_mesh_open_border_loops¶
Read-only.
Count the number of open border loops (topological "holes") in a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetNumOpenBorderLoops.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, open_border_loops, ambiguous_topology }
get_mesh_selection_bounds¶
Read-only.
Resolve a region into a selection and report its local-space BOUNDING BOX via UGeometryScriptLibrary_MeshSelectionQueryFunctions::GetMeshSelectionBoundingBox. Read-only. Takes exactly the same region parameters as select_mesh_triangles and set_mesh_material_id_in_region, so a region measured here is the same one painted there. This is what turns a bisection answer ("the piece is somewhere in X>0") into actual numbers: centre and size, which is what lets you tell a 150x100x40 slab from a 14x230x75 rail without opening the editor.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
region |
string | no | 'all' (default) | 'box' | 'sphere' | 'plane' | 'normal_angle' | 'material_id' | 'polygroup' | 'connected_component'. |
component_index |
integer | no | Island index when region='connected_component'. Get it from get_mesh_components_detail, which reports each piece's size and bounding box. |
center |
array | no | Local [x,y,z] centre. Used by box/sphere, and as the plane origin. |
extent |
array | no | Local [x,y,z] HALF-size in cm. Required by region='box'. |
radius |
number | no | Radius in cm. Required by region='sphere'. |
normal |
array | no | [x,y,z] direction. Plane normal for region='plane', facing direction for 'normal_angle'. Default [0,0,1]. |
max_angle_deg |
number | no | Max angle from normal in degrees for region='normal_angle' (default 15). |
source_material_id |
integer | no | MaterialID to select when region='material_id'. |
polygroup_id |
integer | no | Polygroup to select when region='polygroup'. |
polygroup_layer |
integer | no | Optional extended polygroup layer index for region='polygroup'. |
min_triangle_points |
integer | no | How many of a triangle's 3 points must be inside for it to count, 1-3 (default 3). |
invert |
boolean | no | Invert the spatial selection (default false). |
Returns: { actor_name, region, triangles_selected: int, is_empty: bool, bounds: { min_x, min_y, min_z, max_x, max_y, max_z, center_x, center_y, center_z, size_x, size_y, size_z } }
get_mesh_triangle_count¶
Read-only.
Count the triangles in a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetNumTriangleIDs. This is the canonical triangle count after copy-from-asset; GetTriangleCount is also surfaced on UDynamicMesh directly (always == NumTriangleIDs for a freshly copied mesh).
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, triangle_count, triangle_id_count, has_triangle_id_gaps }
get_mesh_uv_area¶
Read-only.
Compute the total UV-space area of all triangles in a static mesh's UV channel via UGeometryScriptLibrary_MeshQueryFunctions::GetMeshUVArea. bIsValidUVChannel is false if the mesh has no UVs in that channel.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
uv_channel |
number | no | UV channel index (default 0) |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, uv_channel, uv_area, is_valid_uv_channel }
get_mesh_uv_channel_count¶
Read-only.
Read the number of UV channels in a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetNumUVSets.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, uv_channel_count }
get_mesh_vertex_count¶
Read-only.
Count the vertices in a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetVertexCount.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, vertex_count, vertex_id_count, has_vertex_id_gaps }
get_mesh_volume_area¶
Read-only.
Read the surface area and signed volume of a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetMeshVolumeArea.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, surface_area, volume, is_closed }
get_mesh_volume_area_center¶
Read-only.
Read surface area, signed volume, and center-of-mass of a static mesh via UGeometryScriptLibrary_MeshQueryFunctions::GetMeshVolumeAreaCenter.
| Parameter | Type | Required | Description |
|---|---|---|---|
static_mesh_path |
string | yes | Content path to the UStaticMesh asset |
lod_index |
number | no | Optional LOD index to query (default 0) |
Returns: { static_mesh_path, lod_index, surface_area, volume, center_of_mass_x, center_of_mass_y, center_of_mass_z, is_closed }
get_num_connected_islands¶
Read-only.
Get the number of separate connected components in the mesh (alias of GetNumConnectedComponents).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
Returns: { actor_name, num_connected_islands }
get_num_extended_polygroup_layers¶
Read-only.
Count the extended polygroup layers (those beyond the default polygroup layer) on a DynamicMeshActor's live dynamic mesh in the editor world, as num_polygroup_layers. Read-only; reply actor_name is the component name, not the actor label. Change the count with set_num_extended_polygroup_layers.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
Returns: { actor_name, num_polygroup_layers }
get_num_open_border_edges¶
Read-only.
Count the open boundary edges (edges with a single adjacent triangle) of a DynamicMeshActor's live dynamic mesh in the editor world; 0 means the mesh is closed. Read-only; get the loops with get_mesh_open_border_loops. Reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
Returns: { actor_name, num_open_border_edges }
get_num_uv_islands¶
Read-only.
Get the number of UV islands in a UV channel.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
uv_channel |
number | yes | UV channel index (required) |
Returns: { actor_name, uv_channel, num_uv_islands, is_valid_uv_channel }
is_bvh_valid_for_mesh¶
Read-only.
Report whether a BVH built for the live dynamic mesh of a DynamicMeshActor in the editor world is valid for it, via BuildBVHForMesh then UGeometryScriptLibrary_MeshSpatial::IsBVHValidForMesh. The plugin keeps no BVH between calls (build_mesh_bvh and rebuild_mesh_bvh drop theirs, and the spatial-query tools build their own on every call), so no kept BVH can go stale after a mesh edit and that staleness is not tracked: this builds a BVH for the mesh as it is now and checks it, as each spatial query does. bvh_valid false means no valid BVH could be built for the mesh. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
Returns: { actor_name, bvh_valid: bool } -- actor_name is the dynamic mesh component's name, not the actor label.
is_point_inside_mesh¶
Read-only.
Test whether a 3D point is inside the live dynamic mesh of a DynamicMeshActor using Fast Winding Number via UGeometryScriptLibrary_MeshSpatial::IsPointInsideMesh. Every call builds a fresh BVH and fast winding tree from the mesh as it is now (the plugin keeps none), so the answer always reflects the latest mesh edits. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
query_point |
array | no | [x, y, z] point in the mesh's local space. |
winding_threshold |
number | no | Optional float; default 0.5 (standard parity test). Higher values shrink the "inside" region. |
max_distance |
number | no | Optional float; it has no effect on this query, whose winding-number test uses no search distance. |
allow_unsafe_modified |
boolean | no | Optional; maps to bAllowUnsafeModifiedQueries (default false). It has no effect: the BVH is built fresh on every call, so it always matches the mesh. |
Returns: { actor_name, is_inside: bool, containment_outcome: string } -- actor_name is the dynamic mesh component's name, not the actor label.
rebuild_mesh_bvh¶
Read-only.
Build a BVH for the live dynamic mesh of a DynamicMeshActor with RebuildBVHForMesh and read it back with IsBVHValidForMesh. The BVH is a temporary that is not kept: the spatial-query tools build their own on every call, so this only checks that a BVH can be built for the mesh as it is now. bvh_rebuilt is true when the engine reported no error and the BVH reads back as valid; the call fails otherwise. The mesh is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
b_only_if_invalid |
boolean | no | Optional, default true; it has no effect, since every call starts from an empty temporary BVH that the engine always rebuilds |
Returns: { actor_name, bvh_rebuilt: bool, b_only_if_invalid, bvh_valid } -- actor_name is the dynamic mesh component's name, not the actor label.
recompute_mesh_normals¶
Destructive, idempotent.
Recompute the normals of the live dynamic mesh of a DynamicMeshActor in the editor world, overwriting the values of its existing normal overlay while keeping its hard-edge splits; a mesh without normals first gets per-vertex normals. Face contributions are weighted by area and by corner angle (both on by default; both off gives a plain average). Idempotent, in an editor transaction, nothing saved. An empty mesh is an error, and recomputed is false (the call fails) when the engine reports an error. Use it when shading looks wrong after geometry edits; copy_dynamic_mesh_to_static_mesh persists the result.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
angle_weighted |
boolean | no | Weight contributing face normals by corner angle, default true |
area_weighted |
boolean | no | Weight contributing face normals by face area, default true |
Returns: { actor_name: string, angle_weighted: bool, area_weighted: bool, triangle_count: int, vertex_count: int, recomputed: bool }
recompute_mesh_uvs¶
Destructive.
Recompute UVs on a UV channel using the configured flatten method. A channel the mesh does not have, or an empty mesh, is an error; recomputed is false, and the call fails, when the engine refuses (for example polygroups on a mesh without polygroups).
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
uv_channel |
number | no | UV channel index (default 0) |
island_source |
string | no | "uv_islands" | "polygroups" | "existing_groups" | "selection" (default "uv_islands") |
method |
string | no | flatten method: "spectral_conformal" (default), "conformal" or "exp_map" |
Returns: { actor_name, uv_channel, island_source, method, recomputed }
remap_material_ids¶
Destructive.
Renumber MaterialIDs on a DynamicMeshActor's live dynamic mesh. Two modes: pass from_material_id + to_material_id to merge one ID into another (UGeometryScriptLibrary_MeshMaterialFunctions::RemapMaterialIDs), or pass compact=true with the material list to close gaps left by deleted/merged IDs (CompactMaterialIDs) and get back the compacted list to hand to copy_dynamic_mesh_to_static_mesh. Gaps matter: MaterialIDs index into that list positionally, so an unused ID in the middle costs a wasted material slot on the baked asset. The materials list may be shorter than the IDs in use (or absent): the missing entries count as no material. When no triangle carries from_material_id, or from and to are the same ID, the mesh is left unchanged and the call succeeds with applied false, triangles_remapped 0 and a note. Otherwise applied is measured (remap: the triangles that carried from_material_id no longer do; compact: the engine reported no error) and the call fails when it is false.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
compact |
boolean | no | Compact mode: renumber IDs to be contiguous from 0 (default false). |
from_material_id |
number | no | Remap mode: the MaterialID to replace. Required unless compact is true. |
to_material_id |
number | no | Remap mode: the MaterialID to replace it with. Required unless compact is true. |
materials |
array | no | Compact mode: ordered UMaterialInterface content paths, one per current MaterialID. The compacted list is returned in compacted_materials, in the new ID order. |
remove_duplicate_materials |
boolean | no | Compact mode: also merge IDs that point at the SAME material asset (default false). |
Returns: { actor_name, mode: string, from_material_id: int, to_material_id: int, triangles_remapped?: int, max_material_id_after: int, distinct_material_ids_after: int, compacted_materials: [string], applied: bool, note?: string }
remove_dynamic_mesh_actor¶
Destructive.
Destroy a DynamicMeshActor in the editor world, found by label or object name, inside an undoable transaction. Returns the label, internal name and triangle_count_before of the destroyed actor; fails if the name matches no DynamicMeshActor. Create one with spawn_dynamic_mesh_actor.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the DynamicMeshActor to destroy. |
Returns: { actor_name: string, actor_internal_name: string, destroyed: bool, triangle_count_before: int, note?: string }
remove_unused_vertices¶
Destructive.
Remove the vertices no triangle references from a DynamicMeshActor's live dynamic mesh in the editor world and refresh its render data. Remaining vertex IDs are not renumbered and a clean mesh is a no-op; returns vertex_count_before, vertex_count, vertices_removed and removed.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
Returns: { actor_name: string, triangle_count: int, vertex_count: int, vertex_count_before: int, vertices_removed: int, removed: bool }
repack_mesh_uvs¶
Destructive.
Pack existing UV islands on a UV channel into standard UV space. A channel the mesh does not have, or an empty mesh, is an error checked before anything changes. A channel with no UVs set has no islands to pack: the call succeeds with repacked false and a note, leaving the mesh unchanged. Otherwise repacked is false, and the call fails, when the engine reports an error. No undo entry, nothing saved.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
uv_channel |
number | no | UV channel index (default 0) |
target_image_width |
number | no | target image width in pixels (default 512) |
optimize_island_rotation |
boolean | no | whether to optimize island rotation (default true) |
Returns: { actor_name, uv_channel, target_image_width, optimize_island_rotation, num_uv_islands, repacked, note? }
repair_mesh_self_intersections¶
Destructive.
Boolean-union a DynamicMeshActor's dynamic mesh with itself to repair self-intersections, remove internal/floating geometry and resolve non-manifold overlaps (UGeometryScriptLibrary_MeshBooleanFunctions::ApplyMeshSelfUnion). Convergent: the first pass mutates the mesh, but a second pass on the already-cleaned mesh is a no-op (repaired reports false). NOTE: the engine impl ignores its internal success flag and always returns the target mesh, so success is measured by comparing the triangle count, not by the return value.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor (mutated in place) |
fill_holes |
boolean | no | Optional bool override for FGeometryScriptMeshSelfUnionOptions.bFillHoles (default true) |
trim_flaps |
boolean | no | Optional bool override for FGeometryScriptMeshSelfUnionOptions.bTrimFlaps (default true) |
simplify_output |
boolean | no | Optional bool override for FGeometryScriptMeshSelfUnionOptions.bSimplifyOutput (default true) |
winding_threshold |
number | no | Optional [0..1] float override for FGeometryScriptMeshSelfUnionOptions.WindingThreshold (default 0.5). Space with generalised winding number above this is considered inside. |
Returns: { actor_name: string, triangle_count: int, triangle_count_before: int, vertex_count: int, is_closed: bool, repaired: bool }
rotate_dynamic_mesh¶
Destructive.
Rotate every vertex of the live dynamic mesh of a DynamicMeshActor in the editor world about the mesh-local origin, baking the rotation into the geometry; the actor transform is not touched. Rotations accumulate: each call turns the current mesh again. Runs in an editor transaction, nothing saved. An empty mesh is an error; a zero rotation succeeds with applied false and a note, leaving the mesh unchanged. Use transform_dynamic_mesh to move, rotate and scale in one call, set_actor_transform to turn the actor itself, rotate_mesh_uvs to rotate UVs.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
rotation |
array | yes | [pitch, yaw, roll] Euler rotation in degrees, applied on top of the current mesh |
Returns: { actor_name: string, rotation_pitch: number, rotation_yaw: number, rotation_roll: number, applied: bool, note?: string }
rotate_mesh_uvs¶
Destructive.
Rotate all UVs of one channel on a DynamicMeshActor's live dynamic mesh in the editor world by an angle in degrees around a UV-space pivot; 0 degrees changes nothing (rotated false). No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
uv_channel |
number | yes | 0-based UV channel index; a channel the mesh does not have fails the call. |
rotation_angle_deg |
number | yes | Rotation angle in degrees; 0 leaves the UVs untouched. |
rotation_origin_u |
number | no | U coordinate of the rotation pivot (default 0). |
rotation_origin_v |
number | no | V coordinate of the rotation pivot (default 0). |
Returns: { actor_name, uv_channel, rotation_angle_deg, rotation_origin: {u, v}, rotated: bool }
scale_dynamic_mesh¶
Destructive.
Scale the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_MeshTransformFunctions::ScaleMesh, in an editor transaction. A scale that is not three numbers, or an empty mesh, is an error. A scale of 1,1,1 succeeds with applied false and a note, leaving the mesh unchanged.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
scale |
array | no | [x, y, z] scale factor (1.0 = no change) |
Returns: { actor_name: string, scale_x: number, scale_y: number, scale_z: number, applied: bool, note?: string }
scale_mesh_uvs¶
Destructive.
Scale all UVs of one channel on a DynamicMeshActor's live dynamic mesh in the editor world by separate U and V factors; zero factors are refused and 1, 1 changes nothing (scaled false). No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
uv_channel |
number | yes | 0-based UV channel index; a channel the mesh does not have fails the call. |
scale_u |
number | yes | Scale factor along U; must be non-zero (1 keeps U unchanged). |
scale_v |
number | yes | Scale factor along V; must be non-zero (1 keeps V unchanged). |
scale_origin_u |
number | no | U coordinate of the point the scaling is centred on (default 0). |
scale_origin_v |
number | no | V coordinate of the point the scaling is centred on (default 0). |
Returns: { actor_name: string, uv_channel: int, scale_u: number, scale_v: number, scale_origin: { u, v }, scaled: bool }
select_mesh_triangles¶
Destructive.
Resolve a region into a triangle selection and REPORT it, without modifying anything. Read-only companion of set_mesh_material_id_in_region: same region parameters, same resolver, so a region previewed here paints exactly those triangles there. Use it to avoid the failure mode where a mis-specified box selects 0 triangles and the paint call still returns success. Coordinates are LOCAL to the dynamic mesh, not world.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
region |
string | no | 'all' (default) | 'box' | 'sphere' | 'plane' | 'normal_angle' | 'material_id' | 'polygroup' | 'connected_component' (one physical PIECE, by the island index that get_mesh_components_detail reports). |
center |
array | no | Local [x,y,z] centre. Used by box/sphere, and as the plane origin. |
extent |
array | no | Local [x,y,z] HALF-size in cm. Required by region='box'. |
radius |
number | no | Radius in cm. Required by region='sphere'. |
normal |
array | no | [x,y,z] direction. Plane normal for region='plane', facing direction for 'normal_angle'. Default [0,0,1]. |
max_angle_deg |
number | no | Max angle from normal in degrees for region='normal_angle' (default 15). |
source_material_id |
integer | no | MaterialID to select when region='material_id'. |
polygroup_id |
integer | no | Polygroup to select when region='polygroup'. |
polygroup_layer |
integer | no | Optional extended polygroup layer index for region='polygroup'. |
component_index |
integer | no | Island index when region='connected_component'. Get it from get_mesh_components_detail, which reports each piece's size and bounding box. |
min_triangle_points |
integer | no | How many of a triangle's 3 points must be inside for it to count, 1-3 (default 3 = fully contained). |
invert |
boolean | no | Invert the spatial selection (default false). |
include_triangle_ids |
boolean | no | Also return the resolved triangle IDs (default false; they can be thousands). The returned array is what set_mesh_material_id scope='triangles' consumes. |
max_triangle_ids |
number | no | Cap on how many IDs to return when include_triangle_ids is on (default 1000). When the cap truncates, triangle_ids_truncated is true — the count in triangles_selected is still the real one. |
Returns: { actor_name, region, triangles_selected: int, mesh_triangle_count: int, is_empty: bool, triangle_ids: [int], triangle_ids_truncated: bool }
set_dynamic_mesh_material¶
Destructive, idempotent.
Assign a UMaterialInterface asset to a slot on a DynamicMeshActor's UDynamicMeshComponent, in an editor transaction. applied is the slot read back after the assignment; the call fails when it does not hold the material.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor (required). |
material_path |
string | yes | Asset path of the UMaterialInterface (e.g. /Engine/EngineMaterials/DefaultMaterial) (required). |
slot_index |
number | no | Material slot to assign. Default 0 (the dynamic mesh only uses slot 0). |
Returns: { actor_name: string, material_path: string, material_name: string, slot_index: int, applied: bool, note?: string }
set_mesh_material_id¶
Destructive, idempotent.
Stamp a MaterialID onto triangles of a DynamicMeshActor's live dynamic mesh. scope='all' repaints every triangle (UGeometryScriptLibrary_MeshMaterialFunctions::ClearMaterialIDs); scope='triangles' repaints the listed triangle IDs (SetMaterialIDOnTriangles). Calls EnableMaterialIDs first, because on a mesh without that attribute the engine drops the write. An ID in triangle_ids that is not a triangle, or an empty mesh, is an error checked before anything is painted. The targeted triangles are read back: applied is true when all of them carry material_id, and the call fails otherwise.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
material_id |
number | no | MaterialID to write (>= 0). Index into the material list later passed to copy_dynamic_mesh_to_static_mesh. |
scope |
string | no | 'all' (default) or 'triangles'. |
triangle_ids |
array | no | Required when scope='triangles': array of triangle IDs to repaint (e.g. from select_mesh_triangles). |
Returns: { actor_name, material_id, scope, triangles_targeted: int, triangles_painted: int, max_material_id_after: int, distinct_material_ids_after: int, applied: bool }
set_mesh_material_id_in_region¶
Destructive, idempotent.
Stamp a MaterialID onto every triangle inside a region, via the engine's SelectMeshElements* family + SetMaterialIDForMeshSelection. Use this when polygroups are not usable — after a boolean, appended pieces are fused and set_polygroup_material_id cannot address them separately. Coordinates are LOCAL to the dynamic mesh, not world. Preview any region with select_mesh_triangles before painting: a region that selects 0 triangles still returns success.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
material_id |
number | no | MaterialID to write (>= 0). |
region |
string | no | 'all' (default) | 'box' | 'sphere' | 'plane' | 'normal_angle' | 'material_id' | 'polygroup' | 'connected_component' (one physical PIECE, by the island index that get_mesh_components_detail reports). |
center |
array | no | Local [x,y,z] centre. Used by box/sphere, and as the plane origin. |
extent |
array | no | Local [x,y,z] HALF-size in cm. Required by region='box'. |
radius |
number | no | Radius in cm. Required by region='sphere'. |
normal |
array | no | [x,y,z] direction. Plane normal for region='plane', facing direction for 'normal_angle'. Default [0,0,1]. |
max_angle_deg |
number | no | Max angle from normal in degrees for region='normal_angle' (default 15). |
source_material_id |
integer | no | The MaterialID to SELECT when region='material_id'. Separate from material_id, which is the one being written, so 'repaint 1 as 2' is expressible. |
polygroup_id |
integer | no | Polygroup to select when region='polygroup'. |
polygroup_layer |
integer | no | Optional extended polygroup layer index for region='polygroup'. |
component_index |
integer | no | Island index when region='connected_component'. Get it from get_mesh_components_detail, which reports each piece's size and bounding box. |
min_triangle_points |
integer | no | How many of a triangle's 3 points must be inside for it to count, 1-3 (default 3 = fully contained). Only used by the spatial regions. |
invert |
boolean | no | Invert the spatial selection (default false). |
Returns: { actor_name, material_id, region, triangles_selected: int, max_material_id_after: int, distinct_material_ids_after: int, applied: bool }
set_mesh_uv_element_position¶
Destructive, idempotent.
Set the (u, v) of one element of a UV channel overlay on a DynamicMeshActor's live dynamic mesh in the editor world; an invalid element ID writes nothing and returns is_valid_element false, not an error. No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
uv_channel |
number | yes | 0-based UV channel index; a channel the mesh does not have fails the call. |
element_id |
number | yes | ID of the element in the UV overlay of that channel, not a vertex, edge or triangle ID. |
u |
number | yes | New U coordinate of the element. |
v |
number | yes | New V coordinate of the element. |
Returns: { actor_name, uv_channel, element_id, new_position: {u, v}, is_valid_element, set: bool }
set_mesh_uvs_from_projection¶
Destructive, idempotent.
Replace the UVs of one channel on a DynamicMeshActor's live dynamic mesh in the editor world with a box, plane or cylinder projection, optionally only inside a region. Box suits plank-and-post geometry (each face takes the axis it faces), plane only flat pieces, cylinder wrapped shapes. Returns triangles_affected and applied.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
projection |
string | no | 'box' (default) | 'plane' | 'cylinder'. |
uv_channel |
number | no | UV channel to write (default 0). |
location |
array | no | Local [x,y,z] origin of the projection shape (default the mesh origin). |
rotation |
array | no | [pitch, yaw, roll] of the projection shape (default none). For 'plane', this is what chooses which way the plane faces. |
scale |
array | no | [x,y,z] size of the projection shape (default [100,100,100]). THIS IS THE UV DENSITY KNOB: bigger scale = texture repeats fewer times. A tileable material that reads too big or too small is fixed here, not in the material. |
min_island_tri_count |
number | no | box only: islands smaller than this are merged into a neighbour (default 2). |
split_angle |
number | no | cylinder only: angle in degrees at which the wrap is split (default 45). |
region |
string | no | Optional region to limit the projection to; same vocabulary as select_mesh_triangles (default 'all'). |
component_index |
integer | no | Island index when region='connected_component'. |
center |
array | no | Region parameter (box/sphere centre, plane origin). |
extent |
array | no | Region parameter: box HALF-size. |
radius |
number | no | Region parameter: sphere radius. |
normal |
array | no | Region parameter: plane/normal_angle direction. |
max_angle_deg |
number | no | Region parameter for region='normal_angle'. |
source_material_id |
integer | no | Region parameter for region='material_id'. |
polygroup_id |
integer | no | Region parameter for region='polygroup'. |
polygroup_layer |
integer | no | Region parameter for region='polygroup': extended polygroup layer index (default the mesh's default polygroup layer). |
min_triangle_points |
integer | no | Region parameter, 1-3. |
invert |
boolean | no | Select the complement of a box, sphere, plane or normal_angle region (default false); the other regions ignore it. |
Returns: { actor_name, projection, uv_channel, region, triangles_affected: int, uv_channel_count: int, applied: bool }
set_num_extended_polygroup_layers¶
Destructive, idempotent.
Set the number of extended polygroup layers on the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_MeshPolygroupFunctions::SetNumExtendedPolygroupLayers. Idempotent: the engine dedups (only reshapes attributes when the count actually differs from the current one), so re-setting the same count is a no-op. The layer count is read back AFTER the set via GetNumExtendedPolygroupLayers: applied is true when it equals the request, and the call fails when it does not.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
num_layers |
number | no | Desired number of extended polygroup layers (>= 0). |
Returns: { actor_name, requested_num_layers, num_polygroup_layers, applied: bool }
set_num_uv_channels¶
Destructive, idempotent.
Set how many UV channels the live dynamic mesh of a DynamicMeshActor in the editor world has: added channels start without UVs, and channels from num_uv_channels upward are discarded with their UVs (note says so). The current count is a no-op (changed false). The engine allows at most 8, so a count above 8 is an error; num_uv_channels is the count read back after the call, and the call fails if it differs from the request. No undo entry, nothing saved; reply actor_name is the component name, not the actor label. Fill a channel with copy_mesh_uv_channel or generate_mesh_uvs; clear_uv_channel works on static mesh assets.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | DynamicMeshActor name (required) |
num_uv_channels |
number | yes | Desired count, 0 to 8 (required) |
Returns: { actor_name: string, num_uv_channels: int, previous_num_uv_channels: int, changed: bool, note?: string } -- actor_name is the dynamic mesh component's name, not the actor label; num_uv_channels is read back; note when channels were removed, whose UV data is dropped.
set_polygroup_material_id¶
Destructive, idempotent.
Stamp a MaterialID onto every triangle of one polygroup via UGeometryScriptLibrary_MeshMaterialFunctions::SetPolygroupMaterialID. This is usually the cheapest way to paint a part: append_mesh_primitive lays primitives down with PerFace polygroups, so each appended piece is already its own group. HONEST GATE: the engine reports whether the polygroup ID actually existed, and that flag is surfaced as polygroup_id_valid — a false there means nothing was painted, even though the call succeeded.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor. |
polygroup_id |
number | no | Polygroup ID to repaint. |
material_id |
number | no | MaterialID to write (>= 0). |
polygroup_layer |
number | no | Optional extended polygroup layer index. Omit for the default layer. |
Returns: { actor_name, polygroup_id, material_id, polygroup_id_valid: bool, max_material_id_after: int, distinct_material_ids_after: int, applied: bool }
simplify_mesh¶
Destructive.
QEM-simplify a DynamicMeshActor's dynamic mesh to a target triangle count
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
target_triangle_count |
number | yes | Target triangle count to simplify down to (must be > 0) |
Returns: { actor_name: string, target_triangle_count: int, triangle_count_before: int, triangle_count_after: int, vertex_count: int, simplified: bool }
spawn_dynamic_mesh_actor¶
Destructive.
Spawn an empty ADynamicMeshActor into the editor world (not PIE) at an optional location and rotation, ignoring collisions, in an undoable transaction. Returns the label of the new actor as actor_name, its internal name and triangle_count (0). Remove it with remove_dynamic_mesh_actor.
| Parameter | Type | Required | Description |
|---|---|---|---|
location |
array | no | World location [x, y, z] in cm (default the world origin). |
rotation |
array | no | World rotation in degrees as [pitch, yaw, roll] (default no rotation). |
Returns: { actor_name: string, actor_internal_name: string, actor_class: string, has_dynamic_mesh_component: bool, has_dynamic_mesh: bool, triangle_count: int, spawned: bool }
transform_dynamic_mesh¶
Destructive.
Apply a full FTransform (translation + rotation + scale) to the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_MeshTransformFunctions::TransformMesh, in an editor transaction. A location or scale that is not three numbers, or an empty mesh, is an error. An identity transform succeeds with applied false and a note, leaving the mesh unchanged.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
location |
array | no | Optional [x, y, z] translation; default (0,0,0) |
rotation |
array | no | Optional [pitch, yaw, roll] rotation; default (0,0,0) |
scale |
array | no | Optional [x, y, z] scale; default (1,1,1) |
Returns: { actor_name: string, location_x: number, location_y: number, location_z: number, rotation_pitch: number, rotation_yaw: number, rotation_roll: number, scale_x: number, scale_y: number, scale_z: number, applied: bool, note?: string }
translate_dynamic_mesh¶
Destructive.
Translate the live dynamic mesh of a DynamicMeshActor via UGeometryScriptLibrary_MeshTransformFunctions::TranslateMesh, in an editor transaction. A translation that is not three numbers, or an empty mesh, is an error. A zero translation succeeds with applied false and a note, leaving the mesh unchanged.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
translation |
array | no | [x, y, z] translation delta in local space |
Returns: { actor_name: string, translation_x: number, translation_y: number, translation_z: number, applied: bool, note?: string }
translate_mesh_uvs¶
Destructive.
Offset all UVs of one channel on a DynamicMeshActor's live dynamic mesh in the editor world by (translate_u, translate_v); a zero offset changes nothing (translated false). No undo entry; reply actor_name is the component name, not the actor label.
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or object name (case-insensitive) of the target DynamicMeshActor in the editor world. |
uv_channel |
number | yes | 0-based UV channel index; a channel the mesh does not have fails the call. |
translate_u |
number | yes | Offset added to every U coordinate (1.0 shifts by one full tile). |
translate_v |
number | yes | Offset added to every V coordinate (1.0 shifts by one full tile). |
Returns: { actor_name: string, uv_channel: int, translate_u: number, translate_v: number, translated: bool }
weld_mesh_edges¶
Destructive.
Weld coincident open boundary edges of a DynamicMeshActor's dynamic mesh
| Parameter | Type | Required | Description |
|---|---|---|---|
actor_name |
string | yes | Label or name of the target DynamicMeshActor |
tolerance |
number | no | Coincident-edge distance threshold in mesh units (default 1e-06) |
only_unique_pairs |
boolean | no | Only merge unambiguous pairs with unique duplicate-edge matches (default true) |
Returns: { actor_name: string, tolerance: number, only_unique_pairs: bool, triangle_count: int, vertex_count: int, welded: bool }