예제 #1
0
    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)
예제 #2
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)
예제 #3
0
    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)
예제 #4
0
 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()
예제 #5
0
    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)
예제 #6
0
    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])
예제 #7
0
    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)
예제 #8
0
    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
예제 #9
0
    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)