Reading mesh files

To read a 2DM mesh file, instantiate a py2dm.Reader and pass it the path of the 2DM file to read.

The preferred way to use this class is via the context manager interface:

>>> with py2dm.Reader('path/to/mesh.2dm') as mesh:
...   print(mesh)
...
Py2DM Reader
   5 nodes
   4 elements
   2 node strings

Basic usage

Metadata

The py2dm.Reader class exposes properties for the node, element, node string, and element material count of a mesh via its num_* and materials_per_element properties.

Additionally, the py2dm.Reader.extent property allows finding the extreme X and Y values of a mesh. While this method is expensive for large meshes as it checks the entire list of nodes, it is also cached, meaning that subsequent calls will reuse the first value:

with py2dm.Reader('path/to/mesh.2dm') as mesh:

   start = time.time()
   _ = mesh.extent
   print(time.time() - start)  # ~1.6 seconds

   start = time.time()
   _ = mesh.extent
   print(time.time() - start)  # ~0.0 seconds

Sequential access

When retrieving mesh entities in bulk, it is generally recommended using the iterator factory methods py2dm.Reader.iter_nodes(), py2dm.Reader.iter_elements(), and py2dm.Reader.iter_node_strings().

As a shorthand, you can also use the py2dm.Reader.nodes, py2dm.Reader.elements, and py2dm.Reader.node_strings properties respectively. These behave exactly the same as if the corresponding iterator were called with default arguments.

>>> with py2dm.Reader('path/to/mesh.2dm') as mesh:
...   for node in mesh.nodes:
...    if node.id % 10 == 0:
...      print(node)
...
Node #10: (1200.0, 200.0, 20.0)
Node #20: (1120.0, 220.0, 10.0)
(...)

Random access

To access elements randomly (i.e. by their unique ID), you can use the py2dm.Reader.node(), py2dm.Reader.element(), and py2dm.Reader.node_string() methods.

Note that these use the unique identifier for a given entity. For nodes and elements, this is their ID. For node strings, this would be their unique ID when using a subformat that supports unique identifiers for node strings.

Reader class interface

class py2dm.Reader

Default Py2DM reader class used to parse and validate 2DM files.

This reader loads the entire mesh file into memory, allowing for fast ID-based access and iteration without needing to wait for the storage medium.

Do note that this implementation also keeps the Python representation of all mesh entities in memory until the instance is destroyed, which can consume a significant amount of memory for very large meshes.

__init__(self, filepath: str, **kwargs)None

Instantiate a new reader for filepath.

Parameters
  • filepath (str | pathlib.Path) – Path to the mesh file to open.

  • encoding (str) – Encoding to use when reading the file.

name: str

Display name of the mesh.

If the GM "<name>" or MESHNAME "<name>" cards are provided, their specified name will be used here. If neither card is given, the mesh name will default to Unnamed mesh.

Type

str

property closed

Return whether the underlying file is closed.

After closing (either via the close() method or by leaving the reader’s context manager), any operations requiring use of the underlying file will raise a py2dm.errors.FileIsClosedError.

Type

bool

property elements

Return an iterator over all elements in the mesh.

This is synonymous to calling py2dm.Reader.iter_elements() with default arguments.

If you prefer a list of elements, cast this iterator to list.

with py2dm.Reader('mesh.2dm') as mesh:
    elements = list(mesh.elements)
Yield

Elements from the mesh in order.

Type

py2dm.Element

property nodes

Return an iterator over all nodes in the mesh.

This is synonymous to calling py2dm.Reader.iter_nodes() with default arguments.

If you prefer a list of nodes, cast this iterator to list.

with py2dm.Reader('mesh.2dm') as mesh:
    nodes = list(mesh.nodes)
Yield

Nodes from the mesh in order.

Type

py2dm.Node

property node_strings

Iterate over the node strings in the mesh.

This is synonymous to calling py2dm.Reader.iter_node_strings() with default arguments.

If you prefer a list of node strings instead, pass this iterator into the list() constructor instead:

with py2dm.Reader('mesh.2dm') as mesh:
    nodes = list(mesh.nodes)
Yield

Node strings from the mesh in order.

Type

py2dm.NodeString

property materials_per_element

Number of materials per element.

This value will be set by the NUM_MATERIALS_PER_ELEM <count> card. Alternatively, the user may specify the number of materials to use via the materials keyword argument.

If the number of materials is not specified in the file or via the materials argument, the number of elements will default to 0.

Type

int

property num_elements

Return the number of elements in the mesh.

Type

int

property num_nodes

Return the number of nodes in the mesh.

Type

int

property num_node_strings

Return the number of node strings in the mesh.

Type

int

property extent

Return the extents of the mesh as a tuple of four floats.

The tuple is structured as [minX, maxX, minY, maxY].

If the given mesh is empty, the returned tuple will consist of four nan (not a number) values.

Note

The 2DM format does not cache the mesh extents. The first time this property is accessed, all nodes are checked to find the extreme values, which can take considerable time for very large meshes (i.e. ones with millions of nodes).

Any successive calls will re-use this value.

Type

tuple [float, float, float, float]

close()None

Close the mesh reader.

This closes the underlying text file and discards any cached objects or metadata. The instance will become unusable after this call.

Note

This method is called automatically when using the class via the context manager.

open()None

Open the mesh reader.

This performs the initial metadata read and sets up the class for continued access.

When calling this function manually, be sure to call close() once you no longer require file access. Alternatively, you can use the context manager interface, in which case both methods will be called automatically.

element(id_: int)py2dm.Element

Return a mesh element by its unique ID.

Parameters

id (int) – The ID of the element to return.

Raises

KeyError – Raised if the given id_ is invalid.

Returns

The element matching the given ID.

Return type

py2dm.Element

node(id_: int)py2dm.Node

Return a mesh node by its unique ID.

Parameters

id (int) – The ID of the node to return.

Raises

KeyError – Raised if the given id_ is invalid.

Returns

The node matching the given ID.

Return type

py2dm.Node

node_string(name: str)py2dm.NodeString

Return a node string by its unique name.

This is only available if the node strings define a name. For meshes whose node strings are not named, convert Reader.node_strings to a list and access the node strings by index.

with py2dm.Reader('my-mesh.2dm') as mesh:
    node_strings = list(mesh.node_strings)
    node_string_two = node_strings[1]
Parameters

name – Unique name of the node string

Raises

KeyError – Raised if no node string of the given name exists

Returns

The node string of the given name, if any.

Return type

py2dm.NodeString

iter_elements(start: int = - 1, end: int = - 1)collections.abc.Iterator[py2dm.Element]

Iterator over the mesh elements.

Parameters
  • start (int) – The starting element ID. If not specified, the first node in the mesh is used as the starting point.

  • end (int) – The end element ID (excluding the end ID). If negative, the entire range of elements is yielded.

Raises

IndexError – Raised if the start ID is less than 1, or if the end ID is less than or equal to the start ID, or if either of the IDs exceeds the number of elements in the mesh.

Yield

Mesh elements from the given range of IDs.

Type

py2dm.Element

iter_nodes(start: int = - 1, end: int = - 1)collections.abc.Iterator[py2dm.Node]

Iterator over the mesh nodes.

Parameters
  • start (int) – The starting node ID. If not specified, the first node in the mesh is used as the starting point.

  • end (int) – The end node ID (excluding the end ID). If negative, the entire range of nodes is yielded.

Raises

IndexError – Raised if the start ID is less than 1, or if the end ID is less than or equal to the start ID, or if either of the IDs exceeds the number of nodes in the mesh.

Yield

Mesh nodes from the given range of IDs.

Type

py2dm.Node

iter_node_strings(start: int = 0, end: int = - 1)collections.abc.Iterator[py2dm.NodeString]

Iterator over the mesh’s node strings.

Note

Unlike Reader.iter_elements() or Reader.iter_nodes(), this method uses Python slicing notation for its ranges due to node strings not having explicit IDs.

Even if the mesh is using one-indexed IDs, starting iteration on the second node string still requires setting start to 1 when using this function.

Parameters
  • start (int) – Starting offset for the iterator.

  • end (int) – End index for the node strings (exclusive).

Raises

IndexError – Raised if the start ID is less than 0, or if the end ID is less than or equal to the start ID, or if either of the IDs reaches the number of node strings in the mesh.

Yield

Mesh node strings in order of definition.

Type

py2dm.NodeString