Accessing Object Primitives

As discussed in Data and Objects, spatial objects are composed of fundamental geometrical structures called primitives. The five primitive types are points, edges, facets, cells, and blocks. The primitives that make up a spatial object can be accessed through various properties on the object. In addition, other properties exist that correspond to each primitive, such as colours or visibilities.

Accessing points

The points of any object are stored in its points property. Because most point-based objects contain multiple points, the points property is represented as a two-dimensional NumPy array. A single point is stored in an array of three elements [X, Y, Z], representing the X, Y and Z coordinates, respectively. A points array is then an array of point arrays.

A PointSet is the simplest kind of point-based spatial object.

from mapteksdk.project import Project
from mapteksdk.data import PointSet
 
project = Project()
 
with project.new("cad/points", PointSet) as new_points:
    new_points.points = [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0]]

In the example above, we create a PointSet containing four points in a square shape in the XY plane.

As the Maptek Python SDK leverages the NumPy library, we can use NumPy indexing to access points as illustrated below.

from mapteksdk.project import Project
from mapteksdk.data import PointSet
 
project = Project()
 
with project.new("cad/points", PointSet) as point_set:
    point_set.points = [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0]]
 
    print("First point: ", point_set.points[0])
    print("Last point: ", point_set.points[-1])
    print("X of point 1: ", point_set.points[1, 0])
    print("Y of point 2: ", point_set.points[2, 1])
    print("Z of point 0: ", point_set.points[0, 2])
    print("X coordinates: ", point_set.points[:, 0])
    print("Y coordinates: ", point_set.points[:, 1])
    print("Z coordinates: ", point_set.point_z)
    # point_set.points[:, 2] will also give the z coordinates.

Use the following properties and methods to manipulate the points of an object:

Name Description
point_z Use this property to change the z-coordinate of a point.
point_colours

Use this property to change the colour of a point. The colour of each point is represented by an array containing four values [R, G, B, A] where:

  • R, G and B are each values between 0 and 255.

  • A is a value between 0 and 255 where 0 represents full transparency and 255 represents no transparency.

point_visibility Use this boolean property to make a point visible or invisible.
point_selection Use this property to select a group of points.
point_count Use this property to count the number of points in an object.
remove_points(point_indices) Use this method to remove a set of points from an object. This method takes an array of point indices.
point_attributes Use this method to save or return custom point attributes in an object. To set a particular point attribute, you can use the notation point_attributes[attribute_name] = data.
save_point_attribute(attribute_name, data) Use this method to save a point attribute and allocate data to it.

There is one method that can be applied to any point-based object — the dataframe method. It returns the following values:

  • The X, Y and Z coordinates of each point

  • The R, G, B and A values of each point

  • The point visibility of each point

  • The point selection of each point

  • Point primitive attributes

Here is a code example:

from mapteksdk.project import Project
from mapteksdk.project import PointSet
project = Project() # Connect to default project
 
 
point_path = "scrapbook/my_points"
 
 
#1. Create points
with project.new(point_path, PointSet, overwrite=True) as points:
    points.points = [[0, 1, 0], [0.5, 1, 0.5], [1, 1, 0],
                     [0, 0.5, 0.5], [0.5, 0.5, 1], [1, 0.5, 0.5],
                     [0, 0, 0], [0.5, 0, 0.5], [1, 0, 0]]
    points:PointSet
    #2. Print frame values
    with points.dataframe(save_changes=False) as frame:
        print(frame)

If you run this code, you should be able to print the following information:

While facet-based and cell-based objects are also point-based, only PointSet is purely based on point primitive types. To learn more about point sets, see the extended topic Point Sets. You can also refer to the mapteksdk.data.primitives.point_properties module in the API reference.

Accessing edges

An edge is a line segment between two points. As a result, all objects that contain edges also contain points. The Maptek Python SDK represents the edge as an array containing two items, with each item representing a point.

The edges of any object are stored in its edges property. Because most edge-based objects contain multiple edges, the edges property is represented as a NumPy array. Each element of the array represents a single edge, which in turn is an array of the two point indices defining the edge.

An EdgeNetwork is the simplest edge-based spatial object. We can use it to illustrate how to store its edges with the example below.

from mapteksdk.project import Project
from mapteksdk.data import EdgeNetwork
import numpy
 
project = Project()
 
with project.new("cad/edge_network", EdgeNetwork) as network:
  network.points = [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0],
                    [-1, 1.2, 0], [1, 1.2, 0]]
  network.edges = [[0, 1], [1, 2], [2, 3], [0, 3], [4, 5]]
  for i, edge in enumerate(network.edges):
    start = network.points[edge[0]]
    end = network.points[edge[1]]
    length = numpy.linalg.norm(end - start)
    print(f"Edge {i} goes from {start} to {end} and is {length} "
          "meters long")

In the example above, we create an EdgeNetwork with six points and five edges, and then print each edge out by accessing each point from the start of an edge to the end of an edge.

Use the following properties and methods to manipulate the edges of an object:

Name Description
edge_colours Use this property to change the colour of an edge. The colour of each edge is represented by an array containing four values [R, G, B, A] where:
  • R, G and B are each values between 0 and 255.

  • A is a value between 0 and 255 where 0 represents full transparency and 255 represents no transparency.

edge_count Use this property to get the total number of edges for an edge-based object. For example, you may want to preallocate NumPy arrays to the correct length. In this case, using edge_count is advised for performance reasons with very large objects.
edge_attributes Use this method to save or return custom edge attributes in an object. To set a particular edge attribute, you can use the notation edge_attributes[attribute_name] = data.
save_edge_attribute(attribute_name, data) Use this method to save an edge attribute and allocate data to it.
delete_edge_attribute(attribute_name) Use this method to delete an edge attribute.

Accessing facets

A facet is a primitive defined by three points. A facet in the SDK does not store the actual points, but instead references the three points by their index in the points property array. Thus a single facet is represented by an array of three point indices.

The facets of any object are stored in its facets property. Because most facet-based objects contain multiple facets, the facets property is represented as a NumPy array. Each element of the array represents a facet, which in turn is an array of the three point indices defining the facet.

A Surface is the simplest facet-based spatial object. We can use it to illustrate how to store facets with the example below.

from mapteksdk.project import Project
from mapteksdk.data import Surface
 
project = Project()
 
with project.new("surfaces/cube", Surface) as new_surface:
  new_surface.points = [[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
                        [-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]
  new_surface.facets = [[0, 1, 2], [2, 0, 3], # The bottom face.
                        [4, 5, 6], [6, 4, 7], # The top face.
                        [0, 1, 5], [5, 4, 0], # The front face.
                        [1, 2, 5], [5, 6, 2], # The right face.
                        [2, 3, 7], [7, 6, 2], # The back face.
                        [0, 3, 7], [4, 7, 0]] # The left face.

Use the following properties and methods to manipulate the facets of an object:

Name Description
facet_colours Use this property to change the colour of a facet. The colour of each facet is represented by an array containing four values [R, G, B, A] where:
  • R, G and B are each values between 0 and 255.

  • A is a value between 0 and 255 where 0 represents full transparency and 255 represents no transparency.

facet_count Use this property to count the total number of facets within an object. For example, you may want to preallocate NumPy arrays to the correct length. In this case, using facet_count is advised for performance reasons with very large objects.
remove_facets(facet_indices) Use this method to remove facets from an object. Specify the facets you want to remove by using the argument facet_indices, which can be in the form of an integer or an array of integers.
facet_attributes Use this method to save or return custom facet attributes in an object. To set a particular edge attribute, you can use the notation facet_attributes[attribute_name] = data.
save_facet_attribute(attribute_name, data) Use this method to save a facet attribute and allocate data to it.
delete_facet_attribute(attribute_name) Use this method to delete a facet attribute.

Accessing cells

A cell is a primitive containing four points. The Maptek Python SDK represents a cell as an array containing the indices of four points.

Cells are point-based objects. Therefore, the cells of any object are set and accessed using the points property. We define points for a cell to be an array of n*4 points, where n is the number of cells. Below is an example of points for a cell:

You can only access the cells of an object via the cells property. The cells property is a read-only property. Because most cell-based objects contain multiple cells, the cells property is represented as a NumPy array. Each element of the array represents a cell, which in turn is an array of the four point indices defining the cell.

A GridSurface is the simplest cell-based spatial object. We can use it to illustrate how to create cells with the example below.

from mapteksdk.project import Project
from mapteksdk.data import GridSurface
project = Project()
points = [[1.1, 1.15, 1.11], [1.98, 1.17, 1.08], [3.02, 1.13, 1.07],
          [1.08, 1.99, 1.07], [2.01, 2.03, 1.37], [3.00, 2.11, 1.33],
          [1.13, 3.08, 1.08], [2.00, 3.01, 0.99], [3.18, 3.07, 1.34]]
with project.new("surfaces/grid_surface", GridSurface(
        major_dimension_count=3, minor_dimension_count=3
        )) as new_grid:
    new_grid: GridSurface # Added to enable IntelliSense
    new_grid.points = points
    # Accessing cells requires PointStudio 2021.1 or higher,
    # SDK version 1.2 (from Extend Plugins 2021.1).
    print(new_grid.cells)

Use the following properties and methods to manipulate the cells of an object:

Name Description
major_dimension_count Use this property to define the number of rows of cells in a cell-based object.
minor_dimension_count Use this property to define the number of columns of cells in a cell-based object.
cell_count Use this property to return the total number of cells in an object.
cell_point_count Use this property to return the number of cell points in a cell-based object. This is usually equal to the major_dimension_count multiplied by the minor_dimension count properties, but may be less if the object contains invalid points.
cell_visibility Use this property to set the visibility of each cell. This is represented by an array of boolean values, where a False value indicates that the cell is invisible and a True value indicates that the cell is visible.
cell_attributes Use this method to save or return custom cell attributes in an object. To set a particular cell attribute, you can use the notation cell_attributes[attribute_name] = data.
save_cell_attribute(attribute_name, data) Use this method to save a cell attribute and allocate data to it.
delete_cell_attribute(attribute_name) Use this method to delete a cell attribute.

Accessing blocks

A block is a cuboid with a size in each of the three directions and with a location defined by its centroid. The Maptek Python SDK only supports rectangular, prism-shaped blocks. Blocks are used to make more complex objects called block models. How blocks are created depends on the type of block model being created. There are three kinds of block models supported by the Maptek Python SDK, as follows:

  • Dense block models

    A kind of block model where each block has the same size. The model is dense in that a block is defined at every location within the 3D grid structure over the model’s extent. Use DenseBlockModel to represent dense blocks. See Dense Block Models for more information.

  • Subblocked block models

    A kind of block model that allows blocks to be subdivided into subblocks, allowing for the efficient representation of finer-grainer detail within the model. Use SubblockedBlockModel to represent a block model with subblocks. See Subblocked Block Models for more information.

  • Sparse blocks models
    Similar to dense block models in that each block has the same size, but the model is sparse in that blocks are only defined at given locations within the 3D grid structure. Sparse block models allow for the more efficient storage of models that contain many holes or voids. Use SparseBlockModel to build a sparse block model. See Sparse Block Models for more information.

The following is a list of properties and methods that can be used to query and configure all block models, irrespective of type:

block_count Use this read-only property to return the number of blocks in a model. This could be useful for when you want to perform an operation on a number of blocks. You can use this property to iterate over each block in a model.
block_resolution Use this read-only property to return the resolution of blocks in a block model.
block_centroids Use this read-only property to return the centroid of each block in a model.
block_sizes Use this read-only property to return the block sizes of each block in a model.
block_colours Use this property to set the colours of each block in a model. The colour of each block is represented by an array containing four values [R, G, B, A] where:
  • R, G and B are each a value between 0 and 255.

  • A is a value between 0 and 255 where 0 represents full transparency and 255 represents no transparency (fully opaque). This value is optional; you can use the format [R, G, B] for full opacity.

slice_count Use this read-only property to return the number of slices in a block model. If the block model hasn’t rotated, the number of slices in a block model will equal the number of blocks in the z-direction.
row_count Use this read-only property to return the number of rows in a block model. If the block model hasn’t been rotated, the number of rows in a block model will equal the number of blocks in the y-direction.
column_count Use this read-only property to return the number of columns in a block model. If the block model hasn’t been rotated, the number of columns in a block model will equal the number of blocks in the x-direction.
block_selection Use this property to select blocks in a block model. The selection of each block is represented by a boolean value in an array. True means that the block is selected while False means that the block is not selected. By default, block_selection is set to False.
block_visibility Use this property to set the visibility of each block in a block model. The visibility of each block is represented by a boolean value in an array. True means that the block is visible while False means that the block is not visible. By default, block_visibility is set to True.
block_attributes Use this property to set or return the custom block attributes of a model. To set a particular block attribute, you can use the notation block_attributes[attribute_name] = data.
origin Use this property to set the origin of a block model.
block_to_grid_index Use this property to retrieve the row, column and slice that contains the centroid for each block. Each item in the array is an array in the form [row, column, slice].
orientation Use this read-only property to retrieve the orientation of a block model. Returns a tuple of the form (dip, plunge, bearing).
set_orientation(dip, plunge, bearing) Use this method to set the orientation of a block model. This method takes three parameters: dip, plunge and bearing.
grid_index(start, end) Use this method to return all of the subblocks within a parent block. The parent block is defined by its row, count and slice. The start and end parameters are arrays of three items: [row, count, slice].
rotate(angle, axis) Use this method to rotate a block model by the specified angle around the specified axis.