mapteksdk.data.blocks module¶
Module containing classes for interaction with block models.
There are several different kinds of block models, though only DenseBlockModels and Subblocked block models are currently supported by the SDK.
- exception mapteksdk.data.blocks.InvalidBlockCentroidError¶
Bases:
ValueError
Error raised for block centroids which lie outside of the block model.
- exception mapteksdk.data.blocks.InvalidBlockSizeError¶
Bases:
ValueError
Error raised for invalid block sizes.
- class mapteksdk.data.blocks.DenseBlockModel(object_id=None, lock_type=LockType.READWRITE, x_res=1, y_res=1, z_res=1, x_count=1, y_count=1, z_count=1)¶
Bases:
mapteksdk.data.base.Topology
,mapteksdk.data.primitives.block_properties.BlockProperties
,mapteksdk.data.rotation.RotationMixin
A dense block model consists of blocks which are the same size arranged in a three dimensional grid structure. The block model is dense because it does not allow ‘holes’ in the model - every region in the grid must contain a block.
For example, a dense block model with an x_res of 1, a y_res of 2 and a z_res of 3 means all of the blocks in the model are 1 by 2 by 3 units in size. If the dense block model’s x_count was 10, the y_count was 15 and the z_count was 5 then the model would consist of 10 * 15 * 5 = 750 blocks each of which was 1x2x3 units. These blocks would be arranged in a grid with 10 rows, 15 columns and 5 slices with no gaps.
The blocks of a dense block model are defined at creation and cannot be changed.
- Parameters
x_res (float) – The x resolution. Must be greater than zero. Default 1.
y_res (float) – The y resolution. Must be greater than zero. Default 1.
z_res (float) – The z resolution. Must be greater than zero. Default 1.
x_count (int) – The number of columns in the block model. Must be greater than zero. Default 1.
y_count (int) – The number of rows in the block model. Must be greater than zero. Default 1.
z_count (int) – The number of slices in the block model. Must be greater than zero. Default 1.
Notes
Parameters should only be passed for new block models.
- Raises
ValueError – If x_res, y_res, z_res, x_count, y_count or z_count is less than or equal to zero.
TypeError – If x_res, y_res, z_res, x_count, y_count or z_count is not numeric.
TypeError – If x_count, y_count or z_count are numeric but not integers.
Examples
Create a block model as described above and make every second block invisible.
>>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel >>> project = Project() >>> with project.new("blockmodels/model", DenseBlockModel( >>> x_res=1, y_res=2, z_res=3, x_count=10, y_count=15, z_count=5 >>> )) as new_model: >>> new_model.block_visibility = [True, False] * ((10 * 15 * 5) // 2)
- classmethod static_type()¶
Return the type of dense block model as stored in a Project.
This can be used for determining if the type of an object is a dense block model.
- property block_count¶
The count of blocks in the model.
- property block_visibility_3d¶
A view of the block visibility reshaped into 3 dimensions. block_visibility_3d[slice, row, column] gives the visibility for the specified slice, row and column.
Examples
Make a 10x10x10 block model and make every block in the 4th row invisible, excluding blocks in the 0th slice.
>>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel >>> project = Project() >>> with project.new("blockmodels/visibility_3d", DenseBlockModel( ... x_count=10, y_count=10, z_count=10, x_res=1, y_res=1, z_res=0.5 ... )) as new_blocks: ... new_blocks.block_visibility_3d[:, 5, :] = False ... new_blocks.block_visibility_3d[0, :, :] = True
- property block_selection_3d¶
A view of the block selection reshaped into 3 dimensions. block_selection_3d[slice, row, column] gives the visibility for the block in the specified slice, row and column.
- save()¶
Save the changes made to the object.
Generally a user does not need to call this function because it is called automatically at the end of a with block using Project.new() or Project.edit().
- class mapteksdk.data.blocks.SubblockedBlockModel(object_id=None, lock_type=LockType.READWRITE, x_res=1, y_res=1, z_res=1, x_count=1, y_count=1, z_count=1)¶
Bases:
mapteksdk.data.base.Topology
,mapteksdk.data.primitives.block_properties.BlockProperties
,mapteksdk.data.rotation.RotationMixin
A dense subblocked block model. Each primary block can contain subblocks allowing for the model to hold greater detail in areas of greater interest and less detail in areas of less interest.
Block attributes, such as block_visibility and block_colour, have one value per subblock. A subblocked block model is empty when created and contains no blocks. Use the add_subblocks function to add additional subblocks to the model.
Note that it is possible for a subblocked block model to include invalid subblocks. For example, subblocks which are outside of the extents of the block model. These blocks will not be displayed in the viewer.
If interoperability with Vulcan is desired, the subblock sizes should always be a multiple of the primary block sizes (the resolution defined on construction) and you should be careful to ensure subblocks do not intersect each other.
- Parameters
x_res (float) – The x resolution. Must be greater than zero. Default 1.
y_res (float) – The y resolution. Must be greater than zero. Default 1.
z_res (float) – The z resolution. Must be greater than zero. Default 1.
x_count (int) – The number of columns in the block model. Must be greater than zero. Default 1.
y_count (int) – The number of rows in the block model. Must be greater than zero. Default 1.
z_count (int) – The number of slices in the block model. Must be greater than zero. Default 1.
Notes
Parameters should only be passed for new block models.
- Raises
ValueError – If x_res, y_res, z_res, x_count, y_count or z_count is less than or equal to zero.
TypeError – If x_res, y_res, z_res, x_count, y_count or z_count is not numeric.
TypeError – If x_count, y_count or z_count are numeric but not integers.
Examples
Creating a subblocked block model with two parent blocks, one of which is completely filled by a single subblock and another which is split into three subblocks. Each subblock is made invisible individually. Though the block model has two primary blocks, it has four subblocks so four values are required for the visibility.
>>> from mapteksdk.project import Project >>> from mapteksdk.data import SubblockedBlockModel >>> centroids = [[0, 0, 0], [-1, 3, 0], [1, 3, 0], [0, 5, 0]] >>> sizes = [[4, 4, 4], [2, 2, 4], [2, 2, 4], [4, 2, 4]] >>> visibility = [True, True, False, False] >>> project = Project() >>> with project.new("blockmodels/subblocked_model", SubblockedBlockModel( ... x_count=1, y_count=2, z_count=1, x_res=4, y_res=4, z_res=4 ... )) as new_blocks: ... new_blocks.add_subblocks(centroids, sizes) ... new_blocks.block_visibility = visibility
- classmethod static_type()¶
Return the type of subblocked block model as stored in a Project.
This can be used for determining if the type of an object is a subblocked block model.
- property block_count¶
The count of blocks in the model.
- add_subblocks(block_centroids, block_sizes, use_block_coordinates=True)¶
Adds an array of subblocks to the subblocked block model.
By default the block_centroids should be in block model coordinates rather than world coordinates. See convert_to_world_coordinates() for more information.
- Parameters
block_centroid (array_like) – An array of block centroids of the new blocks. This is of the form: [x, y, z].
block_sizes (array_like) – An array of block sizes of the new blocks, each containing three floats. This is of the form: [x_size, y_size, z_size].
use_block_coordinates (bool) – If True (default) then the coordinates of the block centroids will be interpreted as block model coordinates (They will be passed through convert_to_world_coordinates()). If False, then the coordinates of the block centroids will be interpreted as world coordinates.
- Raises
InvalidBlockSizeError – If any block_size is less than zero or greater than the primary block size.
InvalidBlockCentroidError – If any block_centroid is not within the block model.
ReadOnlyError – If called when in read-only mode.
Notes
Calling this function in a loop is very slow. You should calculate all of the subblocks and pass them to this function in a single call.
Examples
The block centroids are specified in block model coordinates relative to the bottom left hand corner of the block model. In the below example, the block model is rotated around all three axes and translated away from the origin. By specifying the centroids in block model coordinates, the centroids remain simple. The output shows the resulting block centroids of the model. To get the same model with use_block_coordinates=False these are the centroids which would be required. As you can see they are significantly more complicated.
>>> import math >>> from mapteksdk.project import Project >>> from mapteksdk.data import SubblockedBlockModel, Axis >>> centroids = [[-1.5, -1, -1], [-0.5, -1, -1], [-1, 1, -1], ... [-1.5, -1, 1], [-0.5, -1, 1], [-1, 1, 1], ... [-1.5, -1, 3], [-0.5, -1, 3], [-1, 1, 3]] >>> sizes = [[1, 2, 2], [1, 2, 2], [2, 2, 2], ... [1, 2, 2], [1, 2, 2], [2, 2, 2], ... [1, 2, 2], [1, 2, 2], [2, 2, 2]] >>> project = Project() >>> with project.new("blockmodels/transformed", SubblockedBlockModel( ... x_count=1, y_count=2, z_count=3, x_res=4, y_res=4, z_res=4 ... )) as new_blocks: ... new_blocks.origin = [94, -16, 12] ... new_blocks.rotate(math.pi / 3, Axis.X) ... new_blocks.rotate(-math.pi / 4, Axis.Y) ... new_blocks.rotate(math.pi * 0.75, Axis.Z) ... new_blocks.add_subblocks(centroids, sizes) ... print(new_blocks.block_centroids) [[ 95.95710678 -16.64693601 11.96526039] [ 95.45710678 -15.86036992 12.32763283] [ 94.70710678 -16.09473435 10.42170174] [ 94.54289322 -17.87168089 12.67236717] [ 94.04289322 -17.08511479 13.03473961] [ 93.29289322 -17.31947922 11.12880852] [ 93.12867966 -19.09642576 13.37947395] [ 92.62867966 -18.30985966 13.74184639] [ 91.87867966 -18.54422409 11.8359153 ]]
Specifying the block centroids in world coordinates is useful when the centroids are already available in world coordinates. This example shows copying the blocks from the model created in the previous example into a new model. Notice that the origin and rotations are the same for the copy. If this were not the case the centroids would likely lie outside of the block model and would not appear in the viewer.
>>> import math >>> from mapteksdk.project import Project >>> from mapteksdk.data import SubblockedBlockModel, Axis >>> project = Project() >>> with project.new("blockmodels/transformed_copy", SubblockedBlockModel( ... x_count=1, y_count=2, z_count=3, x_res=4, y_res=4, z_res=4 ... )) as new_blocks: ... new_blocks.origin = [94, -16, 12] ... new_blocks.rotate(math.pi / 3, Axis.X) ... new_blocks.rotate(-math.pi / 4, Axis.Y) ... new_blocks.rotate(math.pi * 0.75, Axis.Z) ... with project.read("blockmodels/transformed") as read_blocks: ... new_blocks.add_subblocks(read_blocks.block_centroids, ... read_blocks.block_sizes, ... use_block_coordinates=False)
- remove_block(index)¶
Deletes the block at the specified index.
This operation is performed directly on the project to ensure that all properties (such as block_visibility and block_attributes) for the deleted block are deleted as well.
Does nothing if requesting to delete a nonexistent block.
- Parameters
index (int) – Index of the block to the delete.
Warning
Any unsaved changes to the object when this function is called are discarded before the block is deleted. If you wish to keep these changes, call save() before calling this function.
- rotate(angle, axis)¶
Rotates the object by the specified angle around the specified axis.
- Parameters
angle (float) – The angle to rotate by in radians. Positive is clockwise, negative is anticlockwise (When looking in the direction of axis).
axis (Axis) – The axis to rotate by.
Examples
Create a 2x2x2 dense block model which is rotated by pi / 4 radians (45 degrees) around the X axis.
>>> import math >>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel, Axis >>> project = Project() >>> with project.new("blockmodels/dense_rotated", DenseBlockModel( ... x_res=1, y_res=1, z_res=1, ... x_count=2, y_count=2, z_count=3)) as new_model: ... new_model.rotate(math.pi / 4, Axis.X)
If you want to specify the angle in degrees instead of radians, use the math.radians function. Additionally rotate can be called multiple times to rotate the block model in multiple axes. Both of these are shown in the below example. The resulting block model is rotated 32 degrees around the Y axis and 97 degrees around the Z axis.
>>> import math >>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel, Axis >>> project = Project() >>> with project.new("blockmodels/dense_rotated_degrees", DenseBlockModel( ... x_res=1, y_res=1, z_res=1, ... x_count=2, y_count=2, z_count=3)) as new_model: ... new_model.rotate(math.radians(32), Axis.Y) ... new_model.rotate(math.radians(97), Axis.Z)
- set_rotation(angle, axis)¶
Overwrites the existing rotation with a rotation around the specified axis by the specified angle.
This is useful for resetting the rotation to a known point.
- Parameters
angle (float) – Angle to set the rotation to in radians. Positive is clockwise, negative is anticlockwise.
axis (Axis) – Axis to rotate around.
- set_orientation(dip, plunge, bearing)¶
Overwrite the existing rotation with a rotation defined by the specified dip, plunge and bearing.
An orientation of (dip, plunge, bearing) radians is equivalent to rotating the model -dip radians around the X axis, -plunge radians around the Y axis and -(bearing - pi / 2) radians around the Z axis.
- Parameters
dip (float) – Relative rotation of the Y axis around the X axis in radians. This should be between -pi and pi (inclusive).
plunge (float) – Relative rotation of the X axis around the Y axis in radians. This should be between -pi / 2 and pi / 2 (exclusive).
bearing (float) – Absolute bearing of the X axis around the Z axis in radians. This should be between -pi and pi (inclusive).
- Raises
TypeError – If dip, plunge or bearing are not numbers.
Examples
Set orientation of a new 3x3x3 block model to be plunge = 45 degrees, dip = 30 degrees and bearing = -50 degrees
>>> import math >>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel >>> project = Project() >>> with project.new("blockmodels/model_1", DenseBlockModel( ... x_res=1, y_res=1, z_res=1, ... x_count=3, y_count=3, z_count=3)) as new_model: >>> new_model.set_orientation(math.radians(45), ... math.radians(30), ... math.radians(-50))
Copy the rotation from one block model to another. Requires two block models.
>>> from mapteksdk.project import Project >>> from mapteksdk.data import DenseBlockModel >>> project = Project() >>> with project.edit("blockmodels/model_1") as model_1: ... with project.edit("blockmodels/model_2") as model_2: ... model_2.set_orientation(*model_1.orientation)
- save()¶
Save the changes made to the object.
Generally a user does not need to call this function because it is called automatically at the end of a with block using Project.new() or Project.edit().