mapteksdk.data.spatial_filters module

Factory module for creating spatial filters.

The functions defined in this package can be used to create spatial filters which can then be combined with binary operators.

Examples

To hide all blocks of a dense block model where the block centroid is not between the picked top and bottom surface:

>>> from mapteksdk.data import Surface, DenseBlockModel, spatial_filters
>>> from mapteksdk.operations import object_pick
>>> from mapteksdk.project import Project
>>> def main(project: Project):
...     top_surface_oid = object_pick(
...         object_types=Surface, label="Pick top surface"
...     )
...     bottom_surface_oid = object_pick(
...         object_types=Surface, label="Pick bottom surface"
...     )
...     model_oid = object_pick(
...         object_types=DenseBlockModel,
...         label="Pick block models to filter blocks"
...     )
...     below_top = spatial_filters.below_surface(top_surface_oid)
...     above_bottom = spatial_filters.above_surface(bottom_surface_oid)
...
...     between_surfaces = below_top & above_bottom
...     with project.edit(model_oid) as model:
...         between_surfaces_blocks = between_surfaces.filter(model)
...         # The ~ inverts the match. Otherwise, this would hide the blocks
...         # between the surfaces.
...         model.block_visibility[~between_surfaces_blocks] = False
>>> if __name__ == "__main__":
...     with Project() as project:
...         with project.undo():
...             main(project)
class SpatialFilter(*args, **kwargs)

Bases: Protocol

Represents a filter which can be used to filter points spatially.

Examples

Multiple spatial filters can be combined using the “&” operator to create a filter which only accepts points which are matched by both filters. For example:

>>> block_model: DenseBlockModel
>>> first = spatial_filters.above_surface(bottom_surface)
>>> second = spatial_filters.below_surface(top_surface)
>>> compound = first & second
>>> blocks_between_surfaces = compound.filter(block_model)

To create a filter which accepts points matched by either filter, use the pipe operator “|” to combine them. For example:

>>> block_model: DenseBlockModel
>>> first = spatial_filters.below_surface(bottom_surface)
>>> second = spatial_filters.above_surface(top_surface)
>>> compound = first | second
>>> blocks_not_between_surfaces = compound.filter(block_model)

After calling the filter function, the result can be inverted using the ‘~’ operator:

>>> block_model: DenseBlockModel
>>> compound: SpatialFilter
>>> blocks_between_surfaces = compound.filter(block_model)
>>> blocks_not_between_surfaces = ~blocks_between_surfaces
filter(target)

Get points in target which match the filter.

True indicates matched points, False indicates non-matched points.

Examples

There are three main ways to call the filter function. The first is to pass the points directly:

>>> spatial_filter: SpatialFilter
>>> matched_point_mask = spatial_filter.filter([[0, 0, 0], [1, 2, 3]])

Secondly, to filter to blocks in a block model where the block centroid matches the filter:

>>> spatial_filter: SpatialFilter
>>> project: Project
>>> block_model_id: ObjectID[DenseBlockModel]
>>> with project.read(block_model_id, DenseBlockModel) as block_model:
...     filtered_block_mask = spatial_filter.filter(block_model)
...     # Make all the blocks which match the filter blue.
...     block_model.block_colours[filtered_block_mask] = [0, 0, 200, 255]

Thirdly, to filter to the points in any DataObject subclass with a points property:

>>> spatial_filter: SpatialFilter
>>> project: Project
>>> point_set_id: ObjectID[PointSet]
>>> with project.read(point_set_id, PointSet) as point_set:
...     filtered_point_mask = spatial_filter.filter(point_set)
...     # Make all the points which match the filter blue.
...     point_set.point_colours[filtered_point_mask] = [0, 0, 200, 255]
Parameters:

target (PointArrayLike | HasBlocks | HasPoints)

Return type:

BooleanArray

invert()

Invert this filter.

This returns a filter which matches any points not matched by this filter.

Return type:

SpatialFilter

accept_all_filter()

A spatial filter which accepts all points.

This is useful for when a spatial filter is syntactically required, but the caller does not expect to perform any filtering (e.g. When passing a filter as a function argument). This is also useful for creating a filter which matches points which are matched by all of a set of filters.

Examples

To create a filter which matches points which are inside of all of the solids in surface_ids:

>>> surface_ids: Sequence[ObjectID[Surface]]
>>> all_filter = spatial_filters.accept_all_filter()
>>> for surface_id in surface_ids:
...     all_filter &= spatial_filters.inside_solid(surface_id)
Return type:

SpatialFilter

reject_all_filter()

A spatial filter which accepts no points.

This is useful for creating a filter which matches points which are matched by any of a set of filters.

Examples

To create a filter which matches points which are inside of any of the solids in surface_ids:

>>> surface_ids: Sequence[ObjectID[Surface]]
>>> any_filter = spatial_filters.reject_all_filter()
>>> for surface_id in surface_ids:
...     any_filter |= spatial_filters.inside_solid(surface_id)
Return type:

SpatialFilter

any_filters(*filters)

Get a filter which matches points matched by any of the filters.

This is equivalent to combining every filter in filters with the | operator.

Parameters:

filters (SpatialFilter) – The filters to combine.

Raises:

ValueError – If no filters are given. Which points are matched by any of an empty set of filters is poorly defined.

Return type:

SpatialFilter

Examples

This function is primarily intended to make it easier to combine iterables of spatial filters together with an or operator. For example:

>>> spatial_filters: Iterable[SpatialFilter]
>>> any_filter = spatial_filters.any_filters(*spatial_filters)

This is most useful when the spatial filters can be created via a list comprehension. For example, to create a filter which matches points which are inside of any of the solids in surface_ids:

>>> surface_ids: Sequence[ObjectID[Surface]]
>>> any_filter = spatial_filters.any_filters(
...     *[
...           spatial_filters.inside_solid(surface_id)
...           for surface_id in surface_ids
...     ]
>>> )

You can also mix and match filters with this function:

>>> any_filter = spatial_filters.any_filters(
...     spatial_filters.inside_solid(solid_id),
...     spatial_filters.above_surface(surface_id),
>>> )
all_filters(*filters)

Get a filter which matches points matched by all of the filters.

This is equivalent to combining every filter in filters with the & operator.

Parameters:

filters (SpatialFilter) – The filters to combine.

Raises:

ValueError – If no filters are given. Which points are matched by all of an empty set of filters is poorly defined.

Return type:

SpatialFilter

Examples

This function is primarily intended to make it easier to combine iterables of spatial filters together with an and operator. For example:

>>> spatial_filters: Iterable[SpatialFilter]
>>> all_filter = spatial_filters.all_filters(*spatial_filters)

This is most useful when the spatial filters can be created via a list comprehension. For example, to create a filter which matches points which are inside of all of the solids in surface_ids:

>>> surface_ids: Sequence[ObjectID[Surface]]
>>> all_filter = spatial_filters.all_filters(
...     *[
...           spatial_filters.inside_solid(surface_id)
...           for surface_id in surface_ids
...     ]
>>> )

You can also mix and match filters with this function:

>>> all_filter = spatial_filters.all_filters(
...     spatial_filters.inside_solid(solid_id),
...     spatial_filters.above_surface(surface_id),
>>> )
above_facets(points, facets, *, include_on=False, bypass_validity_check=False)

Get a spatial filter which accepts all points above the given facets.

Parameters:
  • points (PointArrayLike) – Points of the surface.

  • facets (FacetArrayLike) – Facets of the surface.

  • include_on (bool) – If set to True, points on the surface will be included by the filter. If False (default), points on the surface will be filtered out.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations or self-intersections.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

above_plane(plane, include_on=False)

A filter which accepts all points above plane.

A plane divides space into two half-spaces separated by the plane. This matches points in the half-space the plane’s normal vector points in. i.e. Given the plane defined by the equation Ax + By + Cz + D = 0, the normal vector is (A, B, C) and the ‘above’ half-space is the half-space that normal vector points into.

Parameters:
  • plane (Plane) – The plane to match points above.

  • include_on (bool) – If True, points on the plane are also considered to be above the plane.

Return type:

SpatialFilter

above_surface(surface_or_id, *, include_on=False, bypass_validity_check=False)

Get a spatial filter which accepts all points above surface.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the Surface the filter will use.

  • include_on (bool) – If set to True, points on the surface will be included by the filter. If False (default), points on the surface will be filtered out.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Return type:

SpatialFilter

below_facets(points, facets, *, include_on=False, bypass_validity_check=False)

Get a spatial filter which accepts all points below the given facets.

Parameters:
  • points (PointArrayLike) – Points of the surface.

  • facets (FacetArrayLike) – Facets of the surface.

  • include_on (bool) – If set to True, points on the surface will be included by the filter. If False (default), points on the surface will be filtered out.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations or self-intersections.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

below_plane(plane, include_on=False)

A filter which accepts all points below plane.

This matches points in the opposite half-space to above_plane.

Parameters:
  • plane (Plane) – The plane to match points above.

  • include_on (bool) – If True, points on the plane are also considered to be above the plane.

Return type:

SpatialFilter

below_surface(surface_or_id, *, include_on=False, bypass_validity_check=False)

Get a spatial filter which accepts all points below surface.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the Surface the filter will use.

  • include_on (bool) – If set to True, points on the surface will be included by the filter. If False (default), points on the surface will be filtered out.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Return type:

SpatialFilter

inside_extent(extent)

Get a filter which accepts all points inside of extent.

Parameters:

extent (Extent)

Return type:

SpatialFilter

inside_facet_extent(points, facets, *, bypass_validity_check=False)

Get a filter which accepts all points within the extent of facets.

This will accept points which are above, below or on the surface. It rejects where if a line in the direction of the z-axis were drawn through the point, that line would not intersect the surface.

Parameters:
  • points (PointArrayLike) – Points of the surface.

  • facets (FacetArrayLike) – Facets of the surface.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations or self-intersections.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

inside_object_extent(topology_or_id)

A filter which accepts all points inside the extent of topology_or_id.

This accepts any points within the smallest possible axis-aligned rectangular prism such that the entire geometry of topology_or_id is contained within it.

This will not take into account any changes to the extent since the object was opened. If passing an open object, it is best to pass an object which was opened with Project.read() to ensure that the returned filter behaves as expected.

Raises:

ObjectClosedError – If topology_or_id is a Topology object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Parameters:

topology_or_id (Topology | ObjectID[Topology])

Return type:

SpatialFilter

inside_surface_extent(surface_or_id, *, bypass_validity_check=False)

Get a filter which accepts all points within the extent of surface.

This will accept points which are above, below or on the surface. It rejects where if a line in the direction of the z-axis were drawn through the point, that line would not intersect the surface.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the Surface the filter will use.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Return type:

SpatialFilter

inside_solid(surface_or_id, *, bypass_validity_check=False)

Get a filter which accepts all points inside the solid.

Points on the solid are considered to be inside.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the solid the filter must use. It must be a closed surface with consistent surface geometry.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations, self-intersections or is not closed.

Return type:

SpatialFilter

inside_solid_facets(points, facets, *, bypass_validity_check=False)

Get a filter which accepts all points inside the solid defined by facets.

Points on the solid are considered to be inside.

Parameters:
  • points (PointArrayLike) – Points of the solid.

  • facets (FacetArrayLike) – Facets of the solid.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations, self-intersections or is not closed.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

outside_extent(extent)

Get a filter which accepts all points outside of extent.

Parameters:

extent (Extent)

Return type:

SpatialFilter

outside_facet_extent(points, facets, *, bypass_validity_check=False)

Get a filter which accepts all points outside the extent of facets.

This only accepts points where if a line in the direction of the z-axis were drawn through the point, that line would not intersect the surface.

Parameters:
  • points (PointArrayLike) – Points of the surface.

  • facets (FacetArrayLike) – Facets of the surface.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations or self-intersections.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

outside_object_extent(topology_or_id)

A filter which rejects all points inside the extent of topology_or_id.

This accepts any points outside the smallest possible axis-aligned rectangular prism such that the entire geometry of topology_or_id is contained within it.

This will not take into account any changes to the extent since the object was opened. If passing an open object, it is best to pass an object which was opened with Project.read() to ensure that the returned filter behaves as expected.

Raises:

ObjectClosedError – If topology_or_id is a Topology object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Parameters:

topology_or_id (Topology | ObjectID[Topology])

Return type:

SpatialFilter

outside_surface_extent(surface_or_id, *, bypass_validity_check=False)

Get a filter which accepts all points outside the extent of surface.

This only accepts points where if a line in the direction of the z-axis were drawn through the point, that line would not intersect the surface.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the Surface the filter will use.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Return type:

SpatialFilter

outside_solid(surface_or_id, *, bypass_validity_check=False)

Get a filter which accepts all points outside the solid.

Points on the solid are considered to be inside.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the solid the filter must use. It must be a closed surface with consistent surface geometry.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations, self-intersections or is not closed.

Return type:

SpatialFilter

outside_solid_facets(points, facets, *, bypass_validity_check=False)

Get a filter which accepts all points outside the solid defined by facets.

Points on the solid are considered to be inside.

Parameters:
  • points (PointArrayLike) – Points of the solid.

  • facets (FacetArrayLike) – Facets of the solid.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations, self-intersections or is not closed.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

on_facets(points, facets, *, bypass_validity_check=False)

Get a filter which accepts all points on the surface.

Parameters:
  • points (PointArrayLike) – Points of the surface.

  • facets (FacetArrayLike) – Facets of the surface.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If points contains less than three points or if facets contains no facets.

  • SurfaceValidityError – If the surface has inconsistent facet normals, trifurcations or self-intersections.

  • ValueError – If any facet references a non-existent point.

Return type:

SpatialFilter

on_plane(plane)

A filter which accepts all points which are on plane.

Parameters:

plane (Plane)

Return type:

SpatialFilter

on_surface(surface_or_id, *, bypass_validity_check=False)

Get a filter which accepts all points on the surface.

Parameters:
  • surface_or_id (Surface | ObjectID[Surface]) – Open Surface or ObjectID of the Surface the filter will use.

  • bypass_validity_check (bool) – Disable the check for surface validity. Setting this to True will improve the performance of this function, especially for large objects. However, this should only be set to True if the caller is certain the surface geometry is valid (e.g. Due to calling fix_surface() on it). Setting this to True when the surface does not have valid geometry will cause this function to give inconsistent results.

Raises:
  • DegenerateTopologyError – If surface_or_id has less than three points or no facets.

  • ObjectClosedError – If surface_or_id is a Surface object and close() has been called on it (i.e. The Project.read(), Project.edit() or Project.new() block has ended).

Return type:

SpatialFilter