def example(cls): """Create a simple ProjectObjectDict.""" pose1 = Pose3() pose2 = Pose3(t=Vector3(2, 2, 0)) pose3 = Pose3(t=Vector3(4, 2, 0)) # Be explicit about unicode literal in case this code is called from python 2 data_path = parutil.get_dir_path( u"sumo/threedee/test_data") model1 = GltfModel.load_from_glb(os.path.join(data_path, "bed.glb")) model2 = GltfModel.load_from_glb(os.path.join(data_path, "bed.glb")) model3 = GltfModel.load_from_glb(os.path.join(data_path, "bed.glb")) obj1 = ProjectObject.gen_meshes_object( meshes=model1, id="1", pose=pose1, category="bed" ) obj2 = ProjectObject.gen_meshes_object( meshes=model2, id="2", pose=pose2, category="chair" ) obj3 = ProjectObject.gen_meshes_object( meshes=model3, id="3", pose=pose3, category="bed" ) project_object_dict = ProjectObjectDict() project_object_dict[obj1.id] = obj1 project_object_dict[obj2.id] = obj2 project_object_dict[obj3.id] = obj3 return project_object_dict
def convert_element(self, element, target_type): """ Convert <element> to <target_type> track. Makes a copy of the element. Inputs: element (ProjectObject) - element to convert target_type (string) - destination project type Return new_element (ProjectObject) - converted element See above for allowed conversions. """ if (element.project_type, target_type) not in self.allowed_conversions: raise ValueError("Invalid target_type ({}) for element with type \ {}".format(target_type, element.project_type)) source_type = element.project_type if target_type == "bounding_box": if source_type == "voxels": bounds = element.voxels.bounds() elif source_type == "meshes": bounds = ComputeBbox().from_gltf_object(element.meshes) else: raise ValueError( "Invalid target type") # this should not be possible new_element = ProjectObject.gen_bounding_box_object( id=element.id, bounds=bounds, pose=deepcopy(element.pose), category=element.category, symmetry=element.symmetry, score=element.score, evaluated=element.evaluated) elif target_type == "voxels": voxelizer = Voxelizer() voxels = voxelizer.run(element.meshes) new_element = ProjectObject.gen_voxels_object( id=element.id, bounds=voxels.bounds(), voxels=voxels, pose=deepcopy(element.pose), category=element.category, symmetry=element.symmetry, score=element.score, evaluated=element.evaluated) else: raise ValueError( "Invalid target type") # this should not be possible return new_element
def test_voxel_io(self): """Test reading and writing voxel objects.""" points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]]) vg = VoxelGrid(0.5, min_corner=Vector3f(0, 0, 0), points=points) po = ProjectObject.gen_voxels_object(id="foobar", voxels=vg, pose=self.pose, category="chair") self.assertIsInstance(self.temp_directory, str) po_xml = po.save(self.temp_directory) po2 = ProjectObject.load("voxels", po_xml, self.temp_directory) self.assertTrue(po2.almost_equal(po))
def test_meshes_io(self): """Test reading and writing gltf objects.""" po = ProjectObject( id="foobar", project_type="meshes", meshes=self.meshes, pose=self.pose, category="chair", ) object_xml = po.save(self.temp_directory) po2 = ProjectObject.load("meshes", object_xml, self.temp_directory) self.assertTrue(po2.almost_equal(po))
def test_bounding_box_io(self): """ Save and load a bounding_box project. Also try overwriting the project (should fail). """ project_scene = ProjectScene(project_type="bounding_box") bounds = Box3d([-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]) po = ProjectObject(id="1", bounds=bounds, category="chair") project_scene.elements["1"] = po # test saving project_scene.save(path=self.temp_directory, project_name="test") xml_path = os.path.join(self.temp_directory, "test", "test.xml") self.assertTrue(os.path.isfile(xml_path)) # test overwriting self.assertRaises(OSError, project_scene.save, path=self.temp_directory, project_name="test") # test loading project_scene = ProjectScene.load(path=self.temp_directory, project_name="test") self.assertIsInstance(project_scene, ProjectScene) self.assertIsInstance(project_scene.elements, ProjectObjectDict) # ::: TODO: improve check with equality test on project_scene # Check bounding box for the first ProjectObject po = project_scene.elements["1"] self.assertTrue(po.bounds.almost_equal(bounds, atol=0.01)) self.assertEqual(po.category, "chair")
def test_xml(self): """Test converting to and from xml.""" s = """<element><id>floor1</id><category>floor</category><bounds>\ <corner1>0., 0., 0.</corner1><corner2>0., 0., 0.</corner2></bounds>\ <pose><translation>-131.596614 , -39.9279011, 92.1260558</translation>\ <rotation><c1>1., 0., 0.</c1><c2>0., 1., 0.</c2><c3>0., 0., 1.</c3></rotation>\ </pose><symmetry><x>twoFold</x><y>twoFold</y><z>fourFold</z></symmetry>\ <detectionScore>0.23</detectionScore><evaluated>True</evaluated></element>""" object_xml = ET.fromstring(s) (id, pose, category, bounds, symmetry, score, evaluated) = \ ProjectObject._parse_xml(object_xml) project_object = ProjectObject.gen_bounding_box_object( id, bounds, pose, category, symmetry, score, evaluated) object_xml2 = project_object._to_xml() self.assertEqual(ET.tostring(object_xml2, encoding="unicode"), s)
def load(cls, project_type, base_elem, path=None): """ Factory method to create a ProjectObjectDict by reading it from disk and xml. Note: If project_type of contained ProjectObjects is bounding_box, no file is read and <path> is not used. Note: Assumes tag of base element has been verified by caller. Inputs: project_type (string) - Specifies the project type to construct (valid values are "bounding_box", "voxels", or "meshes") base_elem - An Element with appropriate sub-elements (objects). path (string) - Path to project directory. Return: New ProjectObjectDict Exceptions: ValueError - If sub-elements are not ProjectObjects. """ # loop over sub-elements, converting and adding to new dict project_object_dict = ProjectObjectDict() for elem in base_elem: if elem.tag == "element": po = ProjectObject.load(project_type, elem, path) project_object_dict[po.id] = po return project_object_dict
def test_factory_methods(self): """Test the gen_<X> methods for the 3 project_types""" po = ProjectObject.gen_bounding_box_object(id="1", bounds=self.bounds) self.assertEqual(po.project_type, "bounding_box") self.assertAlmostEqual(po.bounds, self.bounds) self.assertEqual(po.id, "1") po = ProjectObject.gen_voxels_object(id="2", voxels=self.voxels) self.assertEqual(po.project_type, "voxels") self.assertAlmostEqual(po.voxels.bounds(), self.voxels.bounds()) self.assertEqual(po.id, "2") po = ProjectObject.gen_meshes_object(id="3", meshes=self.meshes) self.assertEqual(po.project_type, "meshes") self.assertEqual(po.meshes.num_primitive_meshes(), self.meshes.num_primitive_meshes()) self.assertEqual(po.id, "3")
def test_bounding_box_io(self): """ Test reading and writing a bounding_box object. """ s = """<element><id>floor1</id><category>floor</category><bounds>\ <corner1>0., 0., 0.</corner1><corner2>0., 0., 0.</corner2></bounds>\ <pose><translation>-131.596614 , -39.9279011, 92.1260558</translation>\ <rotation><c1>1., 0., 0.</c1><c2>0., 1., 0.</c2><c3>0., 0., 1.</c3></rotation>\ </pose><symmetry><x>twoFold</x><y>twoFold</y><z>fourFold</z></symmetry>\ <detectionScore>0.23</detectionScore><evaluated>True</evaluated></element>""" object_xml = ET.fromstring(s) project_object = ProjectObject.load("bounding_box", object_xml) object_xml2 = project_object.save("bounding_box") self.assertEqual(ET.tostring(object_xml2, encoding="unicode"), s)
def test_init(self): """Test common construction.""" po = ProjectObject.example() self.assertTrue(isinstance(po.pose, Pose3)) self.assertTrue(isinstance(po.meshes, GltfModel)) self.assertEqual(po.meshes.num_primitive_meshes(), 1) self.assertEqual(po.meshes.num_nodes(), 1) self.assertEqual(po.meshes.num_buffers(), 1) self.assertEqual(po.meshes.num_images(), 2) self.assertTrue(isinstance(po.category, "".__class__)) self.assertTrue(isinstance(po.symmetry, ObjectSymmetry)) self.assertEqual(po.category, "chair") self.assertEqual(po.id, "1") self.assertAlmostEqual(po.score, 0.57)
def test_constructor(self): """ Test constructor. """ po = ProjectObject(id="1", project_type="bounding_box", bounds=self.bounds) self.assertTrue(isinstance(po.pose, Pose3)) self.assertTrue(isinstance(po.category, "".__class__)) po.pose.assert_almost_equal(Pose3()) self.assertTrue(po.bounds.almost_equal(self.bounds)) self.assertIs(po.meshes, None) self.assertIs(po.voxels, None) self.assertTrue(po.category == "unknown") self.assertEqual(po.id, "1") self.assertEqual(po.symmetry, ObjectSymmetry()) self.assertAlmostEqual(po.score, -1)
def test_setting(self): """Test setting elements.""" po = ProjectObject.gen_meshes_object(id="-1", meshes=self.meshes) po.pose = self.pose po.category = "table" po.symmetry = ObjectSymmetry.example() po.score = 0.23 self.assertTrue(isinstance(po.pose, Pose3)) self.assertAlmostEqual(po.pose, self.pose) self.assertTrue(isinstance(po.meshes, GltfModel)) self.assertTrue(isinstance(po.category, "".__class__)) self.assertTrue(isinstance(po.symmetry, ObjectSymmetry)) self.assertEqual(po.category, "table") self.assertEqual(po.id, "-1") self.assertEqual(po.symmetry, ObjectSymmetry.example()) self.assertAlmostEqual(po.score, 0.23)
def test_almost_equal(self): object1 = ProjectObject.example(id="foobar") self.assertTrue(object1.almost_equal(object1)) object2 = ProjectObject.example(id="not_foobar") self.assertFalse(object1.almost_equal(object2))
def test_transform_pose(self): po = ProjectObject(id="1", bounds=self.bounds, pose=Pose3()) po2 = po.transform_pose(self.pose) self.assertTrue(po2.pose.almost_equal(self.pose))