From cebdc9244c019224846cb8d2668080fe386a6adc Mon Sep 17 00:00:00 2001 From: Alexandre Marie Date: Mon, 17 Dec 2018 12:28:24 +0100 Subject: New upstream version 0.9.0+dfsg --- silx/gui/plot3d/test/__init__.py | 25 ++- silx/gui/plot3d/test/testGL.py | 2 +- silx/gui/plot3d/test/testScalarFieldView.py | 29 ++- silx/gui/plot3d/test/testSceneWidgetPicking.py | 267 +++++++++++++++++++++++++ 4 files changed, 309 insertions(+), 14 deletions(-) create mode 100644 silx/gui/plot3d/test/testSceneWidgetPicking.py (limited to 'silx/gui/plot3d/test') diff --git a/silx/gui/plot3d/test/__init__.py b/silx/gui/plot3d/test/__init__.py index bd2f7c3..c58f307 100644 --- a/silx/gui/plot3d/test/__init__.py +++ b/silx/gui/plot3d/test/__init__.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2015-2017 European Synchrotron Radiation Facility +# Copyright (c) 2015-2018 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,6 @@ __date__ = "09/11/2017" import logging -import os import unittest from silx.test.utils import test_options @@ -39,7 +38,7 @@ _logger = logging.getLogger(__name__) def suite(): - test_suite = unittest.TestSuite() + testsuite = unittest.TestSuite() if not test_options.WITH_GL_TEST: # Explicitly disabled tests @@ -50,17 +49,21 @@ def suite(): def runTest(self): self.skipTest(test_options.WITH_GL_TEST_REASON) - test_suite.addTest(SkipPlot3DTest()) - return test_suite + testsuite.addTest(SkipPlot3DTest()) + return testsuite # Import here to avoid loading modules if tests are disabled - from ..scene import test as test_scene + from ..scene.test import suite as sceneTestSuite + from ..tools.test import suite as toolsTestSuite from .testGL import suite as testGLSuite from .testScalarFieldView import suite as testScalarFieldViewSuite + from .testSceneWidgetPicking import suite as testSceneWidgetPickingSuite - test_suite = unittest.TestSuite() - test_suite.addTest(testGLSuite()) - test_suite.addTest(test_scene.suite()) - test_suite.addTest(testScalarFieldViewSuite()) - return test_suite + testsuite = unittest.TestSuite() + testsuite.addTest(testGLSuite()) + testsuite.addTest(sceneTestSuite()) + testsuite.addTest(testScalarFieldViewSuite()) + testsuite.addTest(testSceneWidgetPickingSuite()) + testsuite.addTest(toolsTestSuite()) + return testsuite diff --git a/silx/gui/plot3d/test/testGL.py b/silx/gui/plot3d/test/testGL.py index 70f197f..ae167ab 100644 --- a/silx/gui/plot3d/test/testGL.py +++ b/silx/gui/plot3d/test/testGL.py @@ -32,7 +32,7 @@ import logging import unittest from silx.gui._glutils import gl, OpenGLWidget -from silx.gui.test.utils import TestCaseQt +from silx.gui.utils.testutils import TestCaseQt from silx.gui import qt diff --git a/silx/gui/plot3d/test/testScalarFieldView.py b/silx/gui/plot3d/test/testScalarFieldView.py index 43d401f..d9c743b 100644 --- a/silx/gui/plot3d/test/testScalarFieldView.py +++ b/silx/gui/plot3d/test/testScalarFieldView.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2017 European Synchrotron Radiation Facility +# Copyright (c) 2017-2018 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -34,7 +34,7 @@ import unittest import numpy from silx.utils.testutils import ParametricTestCase -from silx.gui.test.utils import TestCaseQt +from silx.gui.utils.testutils import TestCaseQt from silx.gui import qt from silx.gui.plot3d.ScalarFieldView import ScalarFieldView @@ -52,6 +52,13 @@ class TestScalarFieldView(TestCaseQt, ParametricTestCase): self.widget = ScalarFieldView() self.widget.show() + paramTreeWidget = TreeView() + paramTreeWidget.setSfView(self.widget) + + dock = qt.QDockWidget() + dock.setWidget(paramTreeWidget) + self.widget.addDockWidget(qt.Qt.BottomDockWidgetArea, dock) + # Commented as it slows down the tests # self.qWaitForWindowExposed(self.widget) @@ -102,6 +109,24 @@ class TestScalarFieldView(TestCaseQt, ParametricTestCase): self.widget.setData(data, copy=True) self.qapp.processEvents() + def testIsoSliderNormalization(self): + """Test set TreeView with a different isoslider normalization""" + data = self._buildData(size=32) + + self.widget.setData(data) + self.widget.addIsosurface(0.5, (1., 0., 0., 0.5)) + self.widget.addIsosurface(0.7, qt.QColor('green')) + self.qapp.processEvents() + + # Add a second TreeView + paramTreeWidget = TreeView(self.widget) + paramTreeWidget.setIsoLevelSliderNormalization('arcsinh') + paramTreeWidget.setSfView(self.widget) + + dock = qt.QDockWidget() + dock.setWidget(paramTreeWidget) + self.widget.addDockWidget(qt.Qt.BottomDockWidgetArea, dock) + def suite(): test_suite = unittest.TestSuite() diff --git a/silx/gui/plot3d/test/testSceneWidgetPicking.py b/silx/gui/plot3d/test/testSceneWidgetPicking.py new file mode 100644 index 0000000..d0c6467 --- /dev/null +++ b/silx/gui/plot3d/test/testSceneWidgetPicking.py @@ -0,0 +1,267 @@ +# coding: utf-8 +# /*########################################################################## +# +# Copyright (c) 2018 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# ###########################################################################*/ +"""Test SceneWidget picking feature""" + +__authors__ = ["T. Vincent"] +__license__ = "MIT" +__date__ = "03/10/2018" + + +import unittest + +import numpy + +from silx.utils.testutils import ParametricTestCase +from silx.gui.utils.testutils import TestCaseQt +from silx.gui import qt + +from silx.gui.plot3d.SceneWidget import SceneWidget, items + + +class TestSceneWidgetPicking(TestCaseQt, ParametricTestCase): + """Tests SceneWidget picking feature""" + + def setUp(self): + super(TestSceneWidgetPicking, self).setUp() + self.widget = SceneWidget() + self.widget.resize(300, 300) + self.widget.show() + # self.qWaitForWindowExposed(self.widget) + + def tearDown(self): + self.qapp.processEvents() + self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) + self.widget.close() + del self.widget + super(TestSceneWidgetPicking, self).tearDown() + + def _widgetCenter(self): + """Returns widget center""" + size = self.widget.size() + return size.width() // 2, size.height() // 2 + + def testPickImage(self): + """Test picking of ImageData and ImageRgba items""" + imageData = items.ImageData() + imageData.setData(numpy.arange(100).reshape(10, 10)) + + imageRgba = items.ImageRgba() + imageRgba.setData( + numpy.arange(300, dtype=numpy.uint8).reshape(10, 10, 3)) + + for item in (imageData, imageRgba): + with self.subTest(item=item.__class__.__name__): + # Add item + self.widget.clearItems() + self.widget.addItem(item) + self.widget.resetZoom('front') + self.qapp.processEvents() + + # Picking on data (at widget center) + picking = list(self.widget.pickItems(*self._widgetCenter())) + + self.assertEqual(len(picking), 1) + self.assertIs(picking[0].getItem(), item) + self.assertEqual(picking[0].getPositions('ndc').shape, (1, 3)) + data = picking[0].getData() + self.assertEqual(len(data), 1) + self.assertTrue(numpy.array_equal( + data, + item.getData()[picking[0].getIndices()])) + + # Picking outside data + picking = list(self.widget.pickItems(1, 1)) + self.assertEqual(len(picking), 0) + + def testPickScatter(self): + """Test picking of Scatter2D and Scatter3D items""" + data = numpy.arange(100) + + scatter2d = items.Scatter2D() + scatter2d.setData(x=data, y=data, value=data) + + scatter3d = items.Scatter3D() + scatter3d.setData(x=data, y=data, z=data, value=data) + + for item in (scatter2d, scatter3d): + with self.subTest(item=item.__class__.__name__): + # Add item + self.widget.clearItems() + self.widget.addItem(item) + self.widget.resetZoom('front') + self.qapp.processEvents() + + # Picking on data (at widget center) + picking = list(self.widget.pickItems(*self._widgetCenter())) + + self.assertEqual(len(picking), 1) + self.assertIs(picking[0].getItem(), item) + nbPos = len(picking[0].getPositions('ndc')) + data = picking[0].getData() + self.assertEqual(nbPos, len(data)) + self.assertTrue(numpy.array_equal( + data, + item.getValues()[picking[0].getIndices()])) + + # Picking outside data + picking = list(self.widget.pickItems(1, 1)) + self.assertEqual(len(picking), 0) + + def testPickScalarField3D(self): + """Test picking of volume CutPlane and Isosurface items""" + volume = self.widget.add3DScalarField( + numpy.arange(10**3, dtype=numpy.float32).reshape(10, 10, 10)) + self.widget.resetZoom('front') + + cutplane = volume.getCutPlanes()[0] + cutplane.getColormap().setVRange(0, 100) + cutplane.setNormal((0, 0, 1)) + + # Picking on data without anything displayed + cutplane.setVisible(False) + picking = list(self.widget.pickItems(*self._widgetCenter())) + self.assertEqual(len(picking), 0) + + # Picking on data with the cut plane + cutplane.setVisible(True) + picking = list(self.widget.pickItems(*self._widgetCenter())) + + self.assertEqual(len(picking), 1) + self.assertIs(picking[0].getItem(), cutplane) + data = picking[0].getData() + self.assertEqual(len(data), 1) + self.assertEqual(picking[0].getPositions().shape, (1, 3)) + self.assertTrue(numpy.array_equal( + data, + volume.getData(copy=False)[picking[0].getIndices()])) + + # Picking on data with an isosurface + isosurface = volume.addIsosurface(level=500, color=(1., 0., 0., .5)) + picking = list(self.widget.pickItems(*self._widgetCenter())) + self.assertEqual(len(picking), 2) + self.assertIs(picking[0].getItem(), cutplane) + self.assertIs(picking[1].getItem(), isosurface) + self.assertEqual(picking[1].getPositions().shape, (1, 3)) + data = picking[1].getData() + self.assertEqual(len(data), 1) + self.assertTrue(numpy.array_equal( + data, + volume.getData(copy=False)[picking[1].getIndices()])) + + # Picking outside data + picking = list(self.widget.pickItems(1, 1)) + self.assertEqual(len(picking), 0) + + def testPickMesh(self): + """Test picking of Mesh items""" + + triangles = items.Mesh() + triangles.setData( + position=((0, 0, 0), (1, 0, 0), (1, 1, 0), + (0, 0, 0), (1, 1, 0), (0, 1, 0)), + color=(1, 0, 0, 1), + mode='triangles') + triangleStrip = items.Mesh() + triangleStrip.setData( + position=(((1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0))), + color=(0, 1, 0, 1), + mode='triangle_strip') + triangleFan = items.Mesh() + triangleFan.setData( + position=((0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)), + color=(0, 0, 1, 1), + mode='fan') + + for item in (triangles, triangleStrip, triangleFan): + with self.subTest(mode=item.getDrawMode()): + # Add item + self.widget.clearItems() + self.widget.addItem(item) + self.widget.resetZoom('front') + self.qapp.processEvents() + + # Picking on data (at widget center) + picking = list(self.widget.pickItems(*self._widgetCenter())) + + self.assertEqual(len(picking), 1) + self.assertIs(picking[0].getItem(), item) + nbPos = len(picking[0].getPositions()) + data = picking[0].getData() + self.assertEqual(nbPos, len(data)) + self.assertTrue(numpy.array_equal( + data, + item.getPositionData()[picking[0].getIndices()])) + + # Picking outside data + picking = list(self.widget.pickItems(1, 1)) + self.assertEqual(len(picking), 0) + + def testPickCylindricalMesh(self): + """Test picking of Box, Cylinder and Hexagon items""" + + positions = numpy.array(((0., 0., 0.), (1., 1., 0.), (2., 2., 0.))) + box = items.Box() + box.setData(position=positions) + cylinder = items.Cylinder() + cylinder.setData(position=positions) + hexagon = items.Hexagon() + hexagon.setData(position=positions) + + for item in (box, cylinder, hexagon): + with self.subTest(item=item.__class__.__name__): + # Add item + self.widget.clearItems() + self.widget.addItem(item) + self.widget.resetZoom('front') + self.qapp.processEvents() + + # Picking on data (at widget center) + picking = list(self.widget.pickItems(*self._widgetCenter())) + + self.assertEqual(len(picking), 1) + self.assertIs(picking[0].getItem(), item) + nbPos = len(picking[0].getPositions()) + data = picking[0].getData() + print(item.__class__.__name__, [positions[1]], data) + self.assertTrue(numpy.all(numpy.equal(positions[1], data))) + self.assertEqual(nbPos, len(data)) + self.assertTrue(numpy.array_equal( + data, + item.getPosition()[picking[0].getIndices()])) + + # Picking outside data + picking = list(self.widget.pickItems(1, 1)) + self.assertEqual(len(picking), 0) + + +def suite(): + testsuite = unittest.TestSuite() + testsuite.addTest( + unittest.defaultTestLoader.loadTestsFromTestCase( + TestSceneWidgetPicking)) + return testsuite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') -- cgit v1.2.3