Geometry constructors
Every geometry a visual or an obstacle carries is a Geometry proto: a box, sphere,
capsule, mesh, or point cloud. The Python and Go SDKs construct that proto directly, with
no helper library; the box, sphere, and capsule primitives also have a machine config
(JSON) form. The transform or WorldState you attach the geometry to supplies its
reference frame and pose. For what a geometry means to the scene and to the planner, see
Visuals and collisions.
Box
A box takes its x, y, and z dimensions in millimeters.
{ "type": "box", "x": 100, "y": 100, "z": 100 }
from viam.proto.common import Geometry, RectangularPrism, Vector3
box = Geometry(
label="box",
box=RectangularPrism(dims_mm=Vector3(x=100, y=100, z=100)),
)
import commonpb "go.viam.com/api/common/v1"
box := &commonpb.Geometry{
Label: "box",
GeometryType: &commonpb.Geometry_Box{
Box: &commonpb.RectangularPrism{
DimsMm: &commonpb.Vector3{X: 100, Y: 100, Z: 100},
},
},
}
Sphere
A sphere takes a radius in millimeters: the r key in JSON, the radius_mm
field in the proto.
{ "type": "sphere", "r": 50 }
from viam.proto.common import Geometry, Sphere
sphere = Geometry(label="sphere", sphere=Sphere(radius_mm=50))
import commonpb "go.viam.com/api/common/v1"
sphere := &commonpb.Geometry{
Label: "sphere",
GeometryType: &commonpb.Geometry_Sphere{
Sphere: &commonpb.Sphere{RadiusMm: 50},
},
}
Capsule
A capsule takes a radius and a length in millimeters. The length must be at least twice the radius.
{ "type": "capsule", "r": 50, "l": 200 }
from viam.proto.common import Capsule, Geometry
capsule = Geometry(
label="capsule",
capsule=Capsule(radius_mm=50, length_mm=200),
)
import commonpb "go.viam.com/api/common/v1"
capsule := &commonpb.Geometry{
Label: "capsule",
GeometryType: &commonpb.Geometry_Capsule{
Capsule: &commonpb.Capsule{RadiusMm: 50, LengthMm: 200},
},
}
Mesh
A mesh comes from an STL or PLY file. Read the file and embed its bytes in the
geometry with a content_type. The renderer draws PLY, so convert an STL file
to PLY first.
from pathlib import Path
from viam.proto.common import Geometry, Mesh
mesh = Geometry(
label="mesh",
mesh=Mesh(content_type="ply", mesh=Path("model.ply").read_bytes()),
)
import (
"os"
commonpb "go.viam.com/api/common/v1"
)
plyBytes, err := os.ReadFile("model.ply")
if err != nil {
return err
}
mesh := &commonpb.Geometry{
Label: "mesh",
GeometryType: &commonpb.Geometry_Mesh{
Mesh: &commonpb.Mesh{ContentType: "ply", Mesh: plyBytes},
},
}
Point cloud
A point cloud is sensor output, so you read it as PCD bytes in binary PCD format and embed them in the geometry. Add a color per point in the PCD data itself. A point cloud has no machine config form, so you build it in code.
from pathlib import Path
from viam.proto.common import Geometry, PointCloud
point_cloud = Geometry(
label="point-cloud",
pointcloud=PointCloud(point_cloud=Path("cloud.pcd").read_bytes()),
)
import (
"os"
commonpb "go.viam.com/api/common/v1"
)
pcdBytes, err := os.ReadFile("cloud.pcd")
if err != nil {
return err
}
pointCloud := &commonpb.Geometry{
Label: "point-cloud",
GeometryType: &commonpb.Geometry_Pointcloud{
Pointcloud: &commonpb.PointCloud{PointCloud: pcdBytes},
},
}
What’s next
- Visuals and collisions: what a transform carries and why a scene visual is not automatically a planner obstacle.
- Geometry types: choosing a type to approximate a physical object.
- draw library: the Go helpers that assemble a geometry into a transform.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!