def testMeshPlaneIntersection(self): np.array([[1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]]) vertices = np.array([[1.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) indices = np.array([0, 1, 2, 0, 2, 3]) mesh = Mesh(vertices, indices) # plane is above geometry plane = Plane.fromCoefficient(1.0, 0.0, 0.0, 2.0) segments = mesh_plane_intersection(mesh, plane) self.assertEqual(len(segments), 0) # plane is intersects edge plane = Plane.fromCoefficient(1.0, 0.0, 0.0, -1.0) segments = mesh_plane_intersection(mesh, plane) self.assertEqual(len(segments), 2) # plane is intersects face plane = Plane.fromCoefficient(1.0, 0.0, 0.0, -0.5) segments = mesh_plane_intersection(mesh, plane) self.assertEqual(len(segments), 4) # plane is flush with face # This is currently expected to return nothing plane = Plane.fromCoefficient(0.0, 0.0, 1.0, 0.0) segments = mesh_plane_intersection(mesh, plane) self.assertEqual(len(segments), 0)
def testNodeBounds(self): mesh = create_plane( Plane(np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]))) mesh_1 = create_plane( Plane(np.array([0.0, 1.0, 0.0]), np.array([0.0, 0.0, 0.0]))) mesh_2 = create_plane( Plane(np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]))) node = Node() self.assertTrue(node.isEmpty()) node.addChild(Node(mesh)) node.addChild(Node(mesh_1)) node.addChild(Node(mesh_2)) box = node.bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.8660254, 5) box = node.children[0].bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.0, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([0.0, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.707106, 5) box = node.children[1].bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.0, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, 0.0, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.707106, 5)
def testSegmentPlaneIntersection(self): point_a, point_b = np.array([1.0, 0.0, 0.0]), np.array([-1.0, 0.0, 0.0]) plane = Plane.fromCoefficient(1.0, 0.0, 0.0, 0.0) intersection = segment_plane_intersection(point_a, point_b, plane) np.testing.assert_array_almost_equal(intersection, [0.0, 0.0, 0.0], decimal=5) # segment lies on plane # This is currently expected to return None point_a, point_b = np.array([0.0, 1.0, 0.0]), np.array([0.0, -1.0, 0.0]) intersection = segment_plane_intersection(point_a, point_b, plane) self.assertIsNone(intersection) # segment end is on plane point_a, point_b = np.array([0.5, 1.0, 0.0]), np.array([0.0, -1.0, 0.0]) intersection = segment_plane_intersection(point_a, point_b, plane) np.testing.assert_array_almost_equal(intersection, [0.0, -1.0, 0.0], decimal=5) # segment that above plane point_a, point_b = np.array([0.5, 1.0, 0.0]), np.array([1.0, -1.0, 0.0]) intersection = segment_plane_intersection(point_a, point_b, plane) self.assertIsNone(intersection)
def updateInitialPlane(self): """Computes the initial plane when 3 or more points have been picked""" if len(self.parent.gl_widget.picks) > 2: points = list(zip(*self.parent.gl_widget.picks))[0] self.initial_plane = Plane.fromBestFit(points) d = self.initial_plane.normal.dot(self.initial_plane.point - self.sample_center) self.initial_plane.point = self.sample_center + self.initial_plane.normal * d self.parent.scenes.drawPlane(self.initial_plane, 2 * self.plane_size, 2 * self.plane_size) else: self.initial_plane = None self.parent.scenes.removePlane()
def testNodeProperties(self): mesh = create_plane( Plane(np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]))) node = Node() node.render_mode = Node.RenderMode.Solid node.selected = False node.visible = True node.colour = Colour.black() child_node = Node(mesh) child_node.render_mode = Node.RenderMode.Transparent child_node.selected = True child_node.visible = False child_node.colour = Colour.white() node.addChild(child_node) self.assertIs(node, child_node.parent) self.assertEqual(child_node.render_mode, Node.RenderMode.Transparent) child_node.render_mode = None self.assertEqual(child_node.render_mode, Node.RenderMode.Solid) self.assertTrue(child_node.selected) child_node.selected = None self.assertFalse(child_node.selected) self.assertFalse(child_node.visible) child_node.visible = None self.assertTrue(child_node.visible) np.testing.assert_array_almost_equal(child_node.colour.rgbaf, [1.0, 1.0, 1.0, 1.0], decimal=5) child_node.colour = None np.testing.assert_array_almost_equal(child_node.colour.rgbaf, [0.0, 0.0, 0.0, 1.0], decimal=5)
def testPlane(self): normal = np.array([1.0, 0.0, 0.0]) point = np.array([0.0, 0.0, 0.0]) plane = Plane(normal, point) np.testing.assert_array_almost_equal(plane.normal, normal, decimal=5) np.testing.assert_array_almost_equal(plane.point, point, decimal=5) point_2 = np.array([0.0, 1.0, 0.0]) point_3 = np.array([0.0, 1.0, 1.0]) plane_2 = Plane.fromPlanarPoints(point, point_2, point_3) np.testing.assert_array_almost_equal(plane_2.normal, normal, decimal=5) np.testing.assert_array_almost_equal(plane_2.point, point, decimal=5) # bad normal self.assertRaises(ValueError, Plane, point, point) self.assertRaises(ValueError, Plane.fromCoefficient, 0, 0, 0, 0) self.assertRaises(ValueError, Plane.fromPlanarPoints, point, point_2, point_2) self.assertAlmostEqual(plane.distanceFromOrigin(), 0.0, 5) plane = Plane(normal, normal) self.assertAlmostEqual(plane.distanceFromOrigin(), 1.0, 5) normal = np.array([1.0, 1.0, 0.0]) plane = Plane(normal, point) # normal vector should be normalize np.testing.assert_array_almost_equal(plane.normal, Vector3(normal).normalized, decimal=5) np.testing.assert_array_almost_equal(plane.point, point, decimal=5) plane_2 = Plane.fromCoefficient(1, 1, 0, 0) np.testing.assert_array_almost_equal(plane.normal, plane_2.normal, decimal=5) np.testing.assert_array_almost_equal(plane.point, plane_2.point, decimal=5) self.assertNotEqual(repr(plane_2), str(plane_2)) points = [ [20.8212362, -9.3734531, 70.5337096], [-56.8372955, -9.5676188, 46.7159424], [-72.2471016, -9.3954792, -0.1111806], [-49.1049504, -9.3734125, -54.1452751], [26.9184367, -9.1761998, -68.1036148], ] plane = Plane.fromBestFit(points) np.testing.assert_array_almost_equal( plane.normal, [0.0019415, -0.999997, -0.0014657], decimal=5) np.testing.assert_array_almost_equal( plane.point, [-26.089934, -9.377232, -1.022083], decimal=5) self.assertRaises(ValueError, Plane.fromBestFit, points[:2])
def testNodeChildren(self): node = Node() self.assertTrue(node.isEmpty()) node.addChild(Node()) self.assertTrue(node.isEmpty()) self.assertEqual(len(node.children), 0) mesh = create_plane( Plane(np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]))) mesh_1 = create_plane( Plane(np.array([0.0, 1.0, 0.0]), np.array([0.0, 0.0, 0.0]))) mesh_2 = create_plane( Plane(np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]))) node = Node() self.assertTrue(node.isEmpty()) node.addChild(Node(mesh)) node.addChild(Node(mesh_1)) node.addChild(Node(mesh_2)) self.assertFalse(node.isEmpty()) self.assertEqual(len(node.children), 3) box = node.bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.8660254, 5) # Nested Nodes node = Node() self.assertTrue(node.isEmpty()) child_node = Node(mesh) child_node.addChild(Node(mesh_1)) child_node.addChild(Node(mesh_2)) node.addChild(child_node) # Nested Copy copied_node = node.copy(transform=np.identity(4) * 2) self.assertIsNot(node, copied_node) self.assertIsNot(node.transform, copied_node.transform) self.assertIs(node.vertices, copied_node.vertices) self.assertEqual(len(copied_node.children), 1) self.assertIs(child_node.vertices, copied_node.children[0].vertices) self.assertIsNot(child_node, copied_node.children[0]) self.assertEqual(len(copied_node.children[0].children), 2) self.assertIsNot(child_node.children[0], copied_node.children[0].children[0]) self.assertIs(copied_node.children[0].children[0].parent, copied_node.children[0]) self.assertIs(child_node.children[0].parent, child_node) self.assertFalse(node.isEmpty()) self.assertEqual(len(node.children), 1) self.assertEqual(len(node.children[0].children), 2) box = node.bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.8660254, 5) # Flatten Node node = node.flatten() self.assertFalse(node.isEmpty()) self.assertEqual(len(node.children), 3) box = node.bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.8660254, 5)
def testScene(self, mock_instrument_entity, _): s = Scene() self.assertTrue(s.isEmpty()) empty_node = Node() self.assertTrue(s.isEmpty()) s.addNode("new", empty_node) # empty key will not be added self.assertNotIn("new", s) # bad key should return empty node self.assertTrue(s["random"].isEmpty()) mesh_1 = create_plane( Plane(np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]))) sample_1 = {"1": mesh_1} node_1 = SampleEntity(sample_1).node() s.addNode("1", node_1) self.assertIs(node_1, s["1"]) mesh_2 = create_plane( Plane(np.array([0.0, 1.0, 0.0]), np.array([0.0, 0.0, 0.0]))) sample_2 = {"2": mesh_2} node_2 = SampleEntity(sample_2).node() s.addNode("2", node_2) self.assertIs(node_2, s["2"]) self.assertTrue("2" in s) self.assertEqual(len(s.nodes), 2) box = s.bounding_box np.testing.assert_array_almost_equal(box.max, np.array([0.5, 0.5, 0.5]), decimal=5) np.testing.assert_array_almost_equal(box.min, np.array([-0.5, -0.5, -0.5]), decimal=5) np.testing.assert_array_almost_equal(box.center, np.array([0.0, 0.0, 0.0]), decimal=5) self.assertAlmostEqual(box.radius, 0.8660254, 5) s.removeNode("2") self.assertFalse("2" in s) self.assertEqual(len(s.nodes), 1) s.removeNode("1") self.assertEqual(len(s.nodes), 0) s.addNode(Attributes.Sample, node_1) s.addNode("other", node_2) Scene.sample_render_mode = Node.RenderMode.Solid self.assertIs( s.nodes[0], node_1) # sample node is first if render mode is not transparent node_1.render_mode = Node.RenderMode.Wireframe self.assertIs(s.nodes[0], node_1) node_1.render_mode = Node.RenderMode.Transparent self.assertIs(s.nodes[-1], node_1) max_extent = Scene.max_extent mock_instrument_entity.return_value.vertices = np.array([[1, 1, 0], [-1, 0, 0]]) Scene.max_extent = 2.0 self.assertTrue(validate_instrument_scene_size(None)) Scene.max_extent = 0.5 self.assertFalse(validate_instrument_scene_size(None)) Scene.max_extent = max_extent
def testNodeCreation(self): node = Node() self.assertEqual(node.vertices.size, 0) self.assertEqual(node.indices.size, 0) self.assertEqual(node.normals.size, 0) self.assertTrue(node.isEmpty()) mesh = create_plane( Plane(np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]))) node = Node(mesh) np.testing.assert_array_almost_equal(node.vertices, mesh.vertices) np.testing.assert_array_equal(node.indices, mesh.indices) np.testing.assert_array_almost_equal(node.normals, mesh.normals) node = SampleEntity({}).node() self.assertTrue(node.isEmpty()) sample_mesh = Mesh( np.array([[0, 0, 0], [0, 1, 0], [0, 1, 1]]), np.array([0, 1, 2]), np.array([[1, 0, 0], [1, 0, 0], [1, 0, 0]]), ) node = SampleEntity({"demo": sample_mesh}).node() self.assertEqual(len(node.per_object_transform), 1) np.testing.assert_array_almost_equal(node.vertices, sample_mesh.vertices) np.testing.assert_array_equal(node.indices, sample_mesh.indices) np.testing.assert_array_almost_equal(node.normals, sample_mesh.normals) self.assertEqual(node.render_primitive, Node.RenderPrimitive.Triangles) points = np.rec.array( [([11.0, 12.0, 13.0], True), ([14.0, 15.0, 16.0], False), ([17.0, 18.0, 19.0], True)], dtype=[("points", "f4", 3), ("enabled", "?")], ) size = np.array([0, 1, 2]) volume = Volume(np.zeros([3, 4, 5], np.float32), size, size, size) self.assertEqual(volume.shape, (3, 4, 5)) node = VolumeEntity(None).node() self.assertTrue(node.isEmpty()) with mock.patch('sscanss.core.scene.node.Texture3D'), mock.patch( 'sscanss.core.scene.node.Texture1D'): node = VolumeEntity(volume).node() np.testing.assert_array_almost_equal(node.top, [1.5, 2., 2.5]) np.testing.assert_array_almost_equal(node.bottom, [-1.5, -2., -2.5]) box = node.bounding_box np.testing.assert_array_almost_equal(box.max, [2.5, 3., 3.5], decimal=5) np.testing.assert_array_almost_equal(box.min, [-0.5, -1., -1.5], decimal=5) np.testing.assert_array_almost_equal(box.center, [1., 1., 1.], decimal=5) self.assertAlmostEqual(box.radius, 3.535533, 5) node = MeasurementPointEntity(np.array([])).node() self.assertTrue(node.isEmpty()) node = MeasurementPointEntity(points).node() self.assertEqual(len(node.per_object_transform), points.size) node = MeasurementVectorEntity(np.array([]), np.array([]), 0).node() self.assertTrue(node.isEmpty()) vectors = np.ones((3, 3, 2)) node = MeasurementVectorEntity(points, vectors, 0).node() self.assertTrue(node.children[0].visible) self.assertFalse(node.children[1].visible) self.assertEqual(len(node.children), vectors.shape[2]) node = PlaneEntity( Plane(np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0])), 1.0, 1.0).node() np.testing.assert_array_almost_equal(node.vertices, mesh.vertices) np.testing.assert_array_equal(node.indices, mesh.indices) np.testing.assert_array_almost_equal(node.normals, mesh.normals)