Apply Transform to Point Cloud
SUMMARY
Apply Transform to Point Cloud applies a 4x4 rigid-body (or affine) transform to every point in a point cloud.
It transforms every point's position — and its normal, if present — by transformation_matrix, rotating, translating, and/or scaling the whole point cloud at once. It's the natural next step after any of the register_point_clouds_using_* Skills, which compute exactly this kind of transform and are demonstrated feeding straight into this function in their own reference examples.
Use this Skill when you need to move, rotate, or align a point cloud into a common coordinate frame, such as after registration or pose estimation.
The Skill
from telekinesis import vitreous
import numpy as np
transformed_point_cloud = vitreous.apply_transform_to_point_cloud(
point_cloud=point_cloud,
transformation_matrix=np.eye(4),
modify_inplace=False,
)Data Transfer Notice
There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.
Example
Raw Pointcloud
Unprocessed point cloud. The origin of the point cloud corresponds with the origin of the scene.
Transformed Pointcloud
The origin of the point cloud is transformed according to the transformation matrix.
The Code
"""
Demonstrates applying a 6-DOF rigid transformation (rotation + translation) to a point cloud.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def apply_transform_to_point_cloud_example():
"""
Applies a 6-DOF rigid transformation (rotation + translation) to a point cloud.
Transforms points using a 4x4 homogeneous transformation matrix.
"""
# ===================== Load Data ==========================================
point_cloud_url = (
"https://assets.telekinesis.ai/examples/v1/point_clouds/plastic_centered.ply"
)
point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)
# ===================== Run Skill ==========================================
transformed_point_cloud = vitreous.apply_transform_to_point_cloud(
point_cloud=point_cloud,
transformation_matrix=[
[1, 0, 0, 15],
[0, 1, 0, 15],
[0, 0, 1, 5],
[0, 0, 0, 1],
],
modify_inplace=False,
)
# ===================== Log ================================================
logger.success(f"Applied transform to {point_cloud}")
logger.success(f"Results: {transformed_point_cloud}")
logger.info(
f"Transformed point cloud positions shape: {transformed_point_cloud.positions.shape}"
)
logger.info(
f"Transformed point cloud has normals shape: "
f"{transformed_point_cloud.normals.shape if transformed_point_cloud.has_normals else None}"
)
logger.info(
f"Transformed point cloud has colors shape: "
f"{transformed_point_cloud.colors.shape if transformed_point_cloud.has_colors else None}"
)
# ===================== Visualization (Optional) ===========================
rr.init("apply_transform_to_point_cloud_example", spawn=True)
datatypes.visualize(point_cloud, entity_path="/1-source_point_cloud")
datatypes.visualize(
transformed_point_cloud, entity_path="/2-transformed_point_cloud"
)
if __name__ == "__main__":
apply_transform_to_point_cloud_example()Runnable examples are available in the Telekinesis examples repository.
Follow the README in that repository to set up the environment, run this specific example with:
cd telekinesis-examples
python examples/point_cloud/apply_transform_to_point_cloud.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to transform |
transformation_matrix | datatypes.Mat4x4 | np.ndarray | list[list[float]] | required | The 4x4 transform to apply, typically [[R | t], [0, 0, 0, 1]] — a 3x3 rotation R plus a translation t — though any invertible 4x4 matrix is accepted |
modify_inplace | datatypes.Bool | bool | None | False | Hint for how the server reuses buffers internally while transforming. Does not mutate your local point_cloud variable either way — always use the function's return value |
Returns
| Type | Description |
|---|---|
datatypes.PointCloud | The point cloud with every point (and normal, if present) transformed by transformation_matrix. Use .positions for the transformed (N, 3) position array. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ValueError | transformation_matrix is not shape (4, 4), or (for a list input) it doesn't contain only numeric elements |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Vitreous service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
transformation_matrix
- Controls: The rotation, translation, and/or scaling applied to every point.
- Units: N/A — a
(4, 4)homogeneous transform matrix; rotation/scaling terms are dimensionless, translation terms are in meters - Default: required — no default, must be supplied
- Typically a rigid-body transform
[[R | t], [0, 0, 0, 1]]produced by aregister_point_clouds_using_*Skill, ornp.eye(4)for the identity (no-op) transform - Must be shape
(4, 4)(checked client-side, raisingValueErrorotherwise), but its contents are not otherwise validated before the request is sent — a non-invertible or non-rigid matrix can still be applied and produce a degenerate result (e.g. points collapsed onto a plane)
modify_inplace
- Controls: A hint to the server about whether to reuse the input's buffer or allocate a new one internally while transforming. This is purely a server-side, remote-call detail.
- Units: Boolean
- Default:
False - Important: Since
apply_transform_to_point_cloudis a remote API call, it does not mutate your localpoint_cloudvariable either way — always use this function's return value to get the transformed result.
TIP
Feed the output of a register_point_clouds_using_* Skill (e.g. register_point_clouds_using_point_to_point_icp) directly into transformation_matrix — that's the transform this Skill is designed to consume.
Where to Use the Skill
Common pipelines include:
- Post-registration alignment – apply the transform returned by a
register_point_clouds_using_*Skill to bring a scan into a shared frame - Multi-view fusion prep – align each view's point cloud into a common frame before combining them with
add_point_clouds - Robot coordinate conversion – move a point cloud from sensor space into robot base or world coordinates
- Pose-driven repositioning – move a point cloud to reflect a newly estimated 6-DOF pose
Alternative Skills
| Skill | vs. Apply Transform to Point Cloud |
|---|---|
| scale_point_cloud | Handles only uniform scaling about a center point, with a simpler two-number interface. Use it instead of building a scaling matrix by hand when you don't also need rotation or translation. |
| register_point_clouds_using_point_to_point_icp | Computes the transformation_matrix this Skill applies, rather than applying one. Run it first to get a transform out of two point clouds. |
When Not to Use the Skill
Do not use Apply Transform to Point Cloud when:
- You only need uniform scaling about a point —
scale_point_cloudoffers a simpler two-parameter interface for that specific case - You only need to transform a subset of points — filter or segment the point cloud first, then transform the result
- You need a genuinely non-rigid deformation — this Skill applies a single linear 4x4 transform (rigid or affine) to every point, not a per-point or non-linear warp
- You don't yet have a transform to apply — compute one first, e.g. with a
register_point_clouds_using_*Skill - You're relying on
modify_inplace=Trueto mutate your local variable — it won't; this is a remote call, so only the return value carries the result either way
WARNING
transformation_matrix must be shape (4, 4) or a ValueError is raised, but its contents are otherwise unchecked. A non-invertible or non-rigid matrix will still be applied and can produce a degenerate result without raising an error.

