Text3D
Text3D is a text label with a 3D location, orientation and size that is maintained when zooming in and out.
Text3D properties
All properties for 2D text objects are applicable to 3D text objects. Additionally, use these properties to customise the look of your 3D text object.
| Name | Description |
direction
|
Use this property to set the direction from the start of the first character to the end of the last character. This property is a three dimensional vector [X, Y, Z]. |
up_direction
|
Use this property to set the direction from the bottom of the text to the top |
always_visible
|
Use this boolean property to set the visibility of the 3D text when there are objects between the text and the view. |
facing
|
Use this enum property to set where the text is facing. It can be set to the following values:
|
Creating a Text3D object
from mapteksdk.project import Project
from mapteksdk.data import Text3D
proj = Project() # Connect to default project
object_path = "scrapbook/text3d_example"
# Create Text
with proj.new(object_path, Text3D, overwrite=True) as text:
text.text = 'hello world'
text.location = [0, 0, 0]
# Colours are R,G,B,A, where A is Alpha (255 = opaque)
text.colour = [38, 128, 0, 255] # Light Green
text.size = 100
Editing Text3D properties
The following example will modify the colour, size, text, and position of the text object created in the last example.
from mapteksdk.project import Project
from mapteksdk.data import Text3D
proj = Project() # Connect to default project
object_path = "scrapbook/text3d_example"
# Create Text
with proj.edit(object_path) as text:
text.text = 'new text'
text.location = [50, 50, 50]
# Colours are R,G,B,A, where A is Alpha (255 = opaque)
text.colour = [255, 50, 50, 255]
text.size = 150
Labelling points at a particular height
The following example will add Text3D at each point, with its height, in any selected object that has point primitives.
from mapteksdk.project import Project
from mapteksdk.data import Text3D, Surface
import numpy as np
def colour_by_height(z_coordinates):
# Sets a basic colour map over points based on height value within height range
lowest, highest = np.min(z_coordinates), np.max(z_coordinates)
ratio = 2 * (z_coordinates - lowest) / (highest - lowest)
b = np.clip((255*(1-ratio)), 0, 255).astype(np.uint8)
r = np.clip((255*(ratio-1)), 0, 255).astype(np.uint8)
g = np.clip((255 - b - r), 0, 255).astype(np.uint8)
a = np.full(z_coordinates.shape, 255, dtype=np.uint8)
return np.column_stack((r,g,b,a))
proj = Project() # Connect to default project
selection = proj.get_selected()
for item in selection:
with proj.read(item) as obj:
if hasattr(obj, 'points'):
# Append _facet_index_labels/ to the surface path as the container to
# store the text objects in
parent_path = f"{obj.id.path}_point_heights"
for i in range(obj.point_count):
# For convenience, get z coordinates as an array
z = obj.points[: ,2]
# Create colours to assign to each value based on height in range
colours = colour_by_height(z)
with proj.new_or_edit(f"{parent_path}/{i}", Text3D, overwrite=True) as label:
# Position on the point
label.location = obj.points[i]
# Set label to point z coordinate
label.text = str(f"{round(z[i],1)}m")
label.size = 3
label.colour = colours[i]
Labelling point indices
The following example will add Text3D at each point, with its index position in the points array in any selected object that has point primitives.
from mapteksdk.project import Project
from mapteksdk.data import Text3D
import numpy as np
proj = Project() # Connect to default project
selection = proj.get_selected()
for item in selection:
with proj.read(item) as obj:
if hasattr(obj, 'points'): # Support anything with points
# Append _edge_index_labels/ to the surface path as the container to
# store the text objects in
parent_path = f"{obj.id.path}_point_index_labels"
for i in range(obj.point_count):
with proj.new_or_edit(f"{parent_path}/{i}", Text3D, overwrite=True) as label:
# Position on the point
label.location = obj.points[i]
# Set label to point index
label.text = str(i)
label.size = 1
label.colour = [0, 255, 0, 255]
Labelling edge indices
The following example will add Text3D at the centre of each edge, with its index position in the edges array in any selected object that has edges primitives.
from mapteksdk.project import Project
from mapteksdk.data import Text3D
import numpy as np
def edge_distances(edge_lines:np.ndarray) -> np.ndarray:
# Calculate distance for each edge
p1, p2 = edge_lines[:, 0, :], edge_lines[:, 1, :]
line_lengths = np.sqrt((p2-p1)**2)
return np.sum(line_lengths, axis=1)
proj = Project() # Connect to default project
selection = proj.get_selected()
for item in selection:
with proj.read(item) as obj:
if hasattr(obj, 'edges'): # Support lines or surfaces
# Append _edge_index_labels/ to the surface path as the container to
# store the text objects in
parent_path = f"{obj.id.path}_edge_index_labels"
edge_lines = obj.points[obj.edges]
edge_lengths = edge_distances(edge_lines)
edge_centres = np.mean(edge_lines, axis=1)
for i in range(edge_lines.shape[0]):
with proj.new_or_edit(f"{parent_path}/{i}", Text3D, overwrite=True) as label:
# Position in the centre of the edge
label.location = edge_centres[i]
# Set label to edge index
label.text = str(i)
# Variably size the text based on the length of the edge
label.size = edge_lengths[i] / 10
label.colour = [255, 0, 0, 255]
Labelling facet indices
The following example will add a Text3D object at the centre of each facet, with its index position in the facets array in any selected Surface.
from mapteksdk.project import Project
from mapteksdk.data import Text3D, Surface
import numpy as np
def triangle_perimeters(triangles:np.ndarray) -> np.ndarray:
# Calculate perimeter for each triangle
p1, p2, p3 = triangles[:, 0, :], triangles[:, 1, :], triangles[:, 2, :]
line_lengths = np.sqrt((p2-p1)**2 + (p3-p2)**2 + (p3-p1)**2)
return np.sum(line_lengths, axis=1)
proj = Project() # Connect to default project
selection = proj.get_selected()
for item in selection:
if item.is_a(Surface):
with proj.read(item) as surface:
# Append _facet_index_labels/ to the surface path as the container to
# store the text objects in
parent_path = f"{surface.id.path}_facet_index_labels"
triangles = surface.points[surface.facets]
perimiters = triangle_perimeters(triangles)
centroids = np.mean(triangles, axis=1)
for i in range(triangles.shape[0]):
with proj.new_or_edit(f"{parent_path}/{i}", Text3D, overwrite=True) as label:
# Position in the centre of the facet
label.location = centroids[i]
# Set label to facet index
label.text = str(i)
# Variably size the text based on the perimeter of the facet
label.size = perimiters[i] / 15