Skip to main content
Version: 3.4.3

Python Scripting

VRGS embeds a Python 3.13 interpreter and exposes the current project to it through a built-in module called vrgs. Scripts run inside the running application against the project you have open — this is not a batch interface that loads a project from disk.

The API is deliberately small: ten functions that let you read geometry and attributes out of meshes and point clouds, read the project's orientations, and push a computed attribute back onto a mesh so it can be coloured, filtered and saved like any other. Anything you can express in NumPy, scikit-learn or SciPy can therefore be run against a VRGS model and its result brought back into the 3D view.

Opening the editor

Home ribbon → Windows → Python Script

This opens a script editor window, and with it a context-sensitive Python ribbon tab:

PanelCommandWhat it does
SaveSave ScriptWrite the script to its file.
DisplayIncrease Size / Decrease Size / FontEditor font controls.
RunRunExecute the script in the embedded interpreter.
RunPython OutputOpen the console window that shows the script's output in real time. Its dropdown has Clear Console.
RunCommand PromptOpen a Windows command prompt — this is how you run pip install.

A new script starts from a template that shows the shape of the thing:

import numpy as np
import vrgs

print("List Of Meshes", vrgs.mesh_list())
print("List Of Point Clouds", vrgs.pointcloud_list())

Output

print() and any error traceback are captured and routed to VRGS:

  • With the Python Output console open, output appears there as it is produced.
  • With no console open, output is collected and written to the messages panel when the script finishes.

For a long-running script, open the console first — otherwise you see nothing until it is over.

Installing packages

The interpreter is a normal Python installation, so pip works. Use Command Prompt on the Python ribbon tab, then:

pip install scipy scikit-learn matplotlib

Packages installed this way are available to scripts on the next run. NumPy is already present.

Where the interpreter lives

The Python home is set by Python Path in Project PropertiesAdvanced & Diagnostics — the folder containing the Python 3.13 runtime. If scripts fail to start, check that first; VRGS logs the Python version it found when it initialises.

The vrgs module

Ten functions, all of them free functions on the module. Object names are the names shown in the project tree.

Listing what is in the project

vrgs.mesh_list() # -> [(name, record_id), ...]
vrgs.pointcloud_list() # -> [(name, record_id), ...]

Both return a list of (name, record_id) tuples covering every mesh or point cloud in the project, including those inside groups.

Geometry

vrgs.mesh_vertices(mesh_name) # -> [[x, y, z], ...]
vrgs.pointcloud_vertices(cloud_name) # -> [[x, y, z], ...]

Every vertex of the named object, in project coordinates. Returns None if no object of that type has that name.

Attributes

vrgs.mesh_attribute_list(mesh_name) # -> [attribute_name, ...]
vrgs.pointcloud_attribute_list(cloud_name) # -> [attribute_name, ...]

vrgs.mesh_attribute(mesh_name, attribute_name) # -> [value, ...]
vrgs.pointcloud_attribute(cloud_name, attribute_name) # -> [value, ...]

The list functions give you the attribute layers an object carries; the value functions give you one layer's values, in vertex order — so element i of the attribute list corresponds to vertex i of the geometry list.

Writing an attribute back

vrgs.mesh_add_attribute(mesh_name, attribute_name, values) # -> True / False

Creates a new per-vertex attribute layer on the named mesh and fills it from values, which must be a list as long as the mesh's vertex count. Returns True on success, False if the mesh was not found or the list was not usable.

The new layer's range and histogram are computed automatically, the display is refreshed, and the project is marked as needing a save — so the attribute is immediately available for colouring and filtering, and persists once you save.

The new layer is integer-typed

mesh_add_attribute creates an integer attribute layer, so floating-point values are truncated. It is the right function for a class label, a cluster ID or a boolean flag. To bring a continuous value back, scale it to a useful integer range first (for example curvature × 1000), or compute it inside VRGS instead — see Attributes.

Orientations

vrgs.orientations()
# -> [(name, tree_path, record_id, x, y, z, dip, azimuth), ...]

Every orientation measurement in the project, each as an eight-element tuple: its name, its full path in the interpretation tree, its record number, its position, and its dip and dip-azimuth. This is the route to running your own clustering or statistics over a structural dataset — see Basic Interpretation for how orientations are made in the first place.

A worked example

Classify a mesh's vertices by elevation and write the class back as an attribute you can colour by:

import numpy as np
import vrgs

# Take the first mesh in the project.
meshes = vrgs.mesh_list()
if not meshes:
print("No meshes in this project")
else:
name = meshes[0][0]
print("Working on", name)

verts = np.array(vrgs.mesh_vertices(name))
z = verts[:, 2]

# Five equal-interval elevation bands, as integer class IDs.
bands = np.digitize(z, np.linspace(z.min(), z.max(), 6)[1:-1])

ok = vrgs.mesh_add_attribute(name, "Elevation Band", bands.tolist())
print("Attribute written:", ok)

Run it, then colour the mesh by Elevation Band from its attribute list.

The same shape works for anything: read vertices and existing attributes, do the work in NumPy or scikit-learn, write an integer result back.

Limits worth knowing

  • The API is read-mostly. You can read geometry, attributes and orientations, and write one thing back — a per-vertex integer attribute on a mesh. There is no scripted access to creating polylines, running commands, or driving the camera.
  • Point clouds are read-only. There is no pointcloud_add_attribute.
  • Names must match the tree exactly, and a name that does not resolve returns None rather than raising — check for it.
  • Scripts run on the UI thread. A long computation makes VRGS unresponsive while it runs. Print progress so you can see it is alive.
  • help(vrgs) is not reliable. Several functions carry a copy-pasted docstring that describes a different function. The reference above is the behaviour; the docstrings are not.

Tips and troubleshooting

  • Nothing happens when I click Run. Open Python Output first — the error is almost certainly there. With the console closed, output only appears at the end.
  • import vrgs fails. The module is registered by VRGS's own interpreter, so it only exists inside a script run from the Python tab. It cannot be imported from an external Python.
  • import numpy fails. Check Python Path in Project Properties points at the runtime VRGS ships with, not another Python on the machine.
  • The attribute appears but everything is one colour. Integer truncation — your values were all between 0 and 1. Scale them up.
  • The vertex count does not match my array. mesh_vertices returns every vertex including those hidden by filtering; do not assume it matches a filtered view.

See also