def draw_open3d_point_cloud(meshcat, path, pcd, normals_scale=0.0, point_size=0.001): pts = np.asarray(pcd.points) assert (pcd.has_colors()) # TODO(russt): handle this case better cloud = PointCloud(pts.shape[0], Fields(BaseField.kXYZs | BaseField.kRGBs)) cloud.mutable_xyzs()[:] = pts.T cloud.mutable_rgbs()[:] = 255 * np.asarray(pcd.colors).T meshcat.SetObject(path, cloud, point_size=point_size) if pcd.has_normals() and normals_scale > 0.0: assert ('need to implement LineSegments in meshcat c++') normals = np.asarray(pcd.normals) vertices = np.hstack( (pts, pts + normals_scale * normals)).reshape(-1, 3).T meshcat["normals"].set_object( g.LineSegments(g.PointsGeometry(vertices), g.MeshBasicMaterial(color=0x000000)))
class TestPointCloudConcatenation(unittest.TestCase): def setUp(self): builder = DiagramBuilder() X_WP_0 = RigidTransform.Identity() X_WP_1 = RigidTransform.Identity() X_WP_1.set_translation([1.0, 0, 0]) id_list = ["0", "1"] self.pc_concat = builder.AddSystem(PointCloudConcatenation(id_list)) self.num_points = 10000 xyzs = np.random.uniform(-0.1, 0.1, (3, self.num_points)) # Only go to 254 to distinguish between point clouds with and without # color. rgbs = np.random.uniform(0., 254.0, (3, self.num_points)) self.pc = PointCloud(self.num_points, Fields(BaseField.kXYZs | BaseField.kRGBs)) self.pc.mutable_xyzs()[:] = xyzs self.pc.mutable_rgbs()[:] = rgbs self.pc_no_rgbs = PointCloud(self.num_points, Fields(BaseField.kXYZs)) self.pc_no_rgbs.mutable_xyzs()[:] = xyzs diagram = builder.Build() simulator = Simulator(diagram) self.context = diagram.GetMutableSubsystemContext( self.pc_concat, simulator.get_mutable_context()) self.context.FixInputPort( self.pc_concat.GetInputPort("X_FCi_0").get_index(), AbstractValue.Make(X_WP_0)) self.context.FixInputPort( self.pc_concat.GetInputPort("X_FCi_1").get_index(), AbstractValue.Make(X_WP_1)) def test_no_rgb(self): self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_0").get_index(), AbstractValue.Make(self.pc_no_rgbs)) self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_1").get_index(), AbstractValue.Make(self.pc_no_rgbs)) fused_pc = self.pc_concat.GetOutputPort("point_cloud_FS").Eval( self.context) self.assertEqual(fused_pc.size(), 2 * self.num_points) # The first point cloud should be from [-0.1 to 0.1]. # Tthe second point cloud should be from [0.9 to 1.1]. self.assertTrue(np.max(fused_pc.xyzs()[0, :]) >= 1.0) self.assertTrue(np.min(fused_pc.xyzs()[0, :]) <= 0.0) # Even if both input point clouds don't have rgbs, the fused point # cloud should contain rgbs of the default color. self.assertTrue(fused_pc.has_rgbs()) self.assertTrue( np.all(fused_pc.rgbs()[:, 0] == np.array([255, 255, 255]))) self.assertTrue( np.all(fused_pc.rgbs()[:, -1] == np.array([255, 255, 255]))) def test_rgb(self): self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_0").get_index(), AbstractValue.Make(self.pc)) self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_1").get_index(), AbstractValue.Make(self.pc)) fused_pc = self.pc_concat.GetOutputPort("point_cloud_FS").Eval( self.context) self.assertEqual(fused_pc.size(), 2 * self.num_points) # The first point cloud should be from [-0.1 to 0.1]. # The second point cloud should be from [0.9 to 1.1]. self.assertTrue(np.max(fused_pc.xyzs()[0, :]) >= 1.0) self.assertTrue(np.min(fused_pc.xyzs()[0, :]) <= 0.0) self.assertTrue(fused_pc.has_rgbs()) self.assertTrue( np.all(fused_pc.rgbs()[:, 0] != np.array([255, 255, 255]))) self.assertTrue( np.all(fused_pc.rgbs()[:, -1] != np.array([255, 255, 255]))) def test_mix_rgb(self): self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_0").get_index(), AbstractValue.Make(self.pc)) self.context.FixInputPort( self.pc_concat.GetInputPort("point_cloud_CiSi_1").get_index(), AbstractValue.Make(self.pc_no_rgbs)) fused_pc = self.pc_concat.GetOutputPort("point_cloud_FS").Eval( self.context) self.assertEqual(fused_pc.size(), 2 * self.num_points) # The first point cloud should be from [-0.1 to 0.1]. # The second point cloud should be from [0.9 to 1.1]. self.assertTrue(np.max(fused_pc.xyzs()[0, :]) >= 1.0) self.assertTrue(np.min(fused_pc.xyzs()[0, :]) <= 0.0) self.assertTrue(fused_pc.has_rgbs()) # We don't know in what order the two point clouds will be combined. rgb_first = np.all(fused_pc.rgbs()[:, 0] != np.array([255, 255, 255])) rgb_last = np.all(fused_pc.rgbs()[:, -1] != np.array([255, 255, 255])) no_rgb_first = np.all(fused_pc.rgbs()[:, 0] == np.array([255, 255, 255])) no_rgb_last = np.all(fused_pc.rgbs()[:, -1] == np.array([255, 255, 255])) self.assertTrue((rgb_first and no_rgb_last) or (no_rgb_first and rgb_last))