PyVRML97 2.3.1__tar.gz → 2.3.4b1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. pyvrml97-2.3.4b1/PKG-INFO +65 -0
  2. pyvrml97-2.3.4b1/PyVRML97.egg-info/PKG-INFO +65 -0
  3. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/PyVRML97.egg-info/SOURCES.txt +6 -1
  4. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/README.rst +5 -0
  5. pyvrml97-2.3.4b1/pyproject.toml +48 -0
  6. pyvrml97-2.3.4b1/requirements.txt +5 -0
  7. pyvrml97-2.3.4b1/test-requirements.txt +4 -0
  8. pyvrml97-2.3.4b1/tests/test_fieldtypes.py +20 -0
  9. pyvrml97-2.3.4b1/tests/test_nodepath.py +80 -0
  10. pyvrml97-2.3.4b1/tests/test_olist.py +43 -0
  11. pyvrml97-2.3.4b1/tests/test_tostring.py +50 -0
  12. pyvrml97-2.3.4b1/tests/test_transformmatrix.py +85 -0
  13. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/tox.ini +1 -1
  14. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/__init__.py +1 -1
  15. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/arrays.py +41 -22
  16. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/field.py +189 -146
  17. pyvrml97-2.3.4b1/vrml/fieldtypes.py +1491 -0
  18. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/node.py +231 -168
  19. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/protofunctions.py +100 -54
  20. pyvrml97-2.3.4b1/vrml/vrml97/linearise.py +579 -0
  21. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/nodepath.py +1 -1
  22. pyvrml97-2.3.4b1/vrml/vrml97/parseprocessor.py +452 -0
  23. PyVRML97-2.3.1/PKG-INFO +0 -27
  24. PyVRML97-2.3.1/PyVRML97.egg-info/PKG-INFO +0 -27
  25. PyVRML97-2.3.1/requirements.txt +0 -3
  26. PyVRML97-2.3.1/setup.py +0 -74
  27. PyVRML97-2.3.1/test-requirements.txt +0 -2
  28. PyVRML97-2.3.1/vrml/fieldtypes.py +0 -1052
  29. PyVRML97-2.3.1/vrml/vrml97/linearise.py +0 -527
  30. PyVRML97-2.3.1/vrml/vrml97/parseprocessor.py +0 -443
  31. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/MANIFEST.in +0 -0
  32. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/PyVRML97.egg-info/dependency_links.txt +0 -0
  33. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/PyVRML97.egg-info/not-zip-safe +0 -0
  34. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/PyVRML97.egg-info/requires.txt +0 -0
  35. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/PyVRML97.egg-info/top_level.txt +0 -0
  36. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/license.txt +0 -0
  37. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/setup.cfg +0 -0
  38. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/_bytes.py +0 -0
  39. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/cache.py +0 -0
  40. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/copier.py +0 -0
  41. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/csscolors.py +0 -0
  42. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/event.py +0 -0
  43. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/nodepath.py +0 -0
  44. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/olist.py +0 -0
  45. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/protonamespace.py +0 -0
  46. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/route.py +0 -0
  47. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml200x/__init__.py +0 -0
  48. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml200x/parser.py +0 -0
  49. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/__init__.py +0 -0
  50. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/_transformmatrix.py +0 -0
  51. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/_transformmatrix_accel.py +0 -0
  52. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/basenamespaces.py +0 -0
  53. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/basenodes.py +0 -0
  54. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/nodetypes.py +0 -0
  55. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/nurbs.py +0 -0
  56. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/parser.py +0 -0
  57. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/scenegraph.py +0 -0
  58. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/script.py +0 -0
  59. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/shaders.py +0 -0
  60. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/vrml97/transformmatrix.py +0 -0
  61. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/weakkeydictfix.py +0 -0
  62. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/weaklist.py +0 -0
  63. {PyVRML97-2.3.1 → pyvrml97-2.3.4b1}/vrml/weaktuple.py +0 -0
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyVRML97
3
+ Version: 2.3.4b1
4
+ Summary: VRML97 Scenegraph model for Python
5
+ Author-email: "Mike C. Fletcher" <mcfletch@vrplumber.com>
6
+ License: BSD-style, see license.txt for details
7
+ Project-URL: Homepage, http://pyopengl.sourceforge.net/context/
8
+ Keywords: VRML,VRML97,scenegraph
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: C
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
14
+ Classifier: Intended Audience :: Developers
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/x-rst
17
+ Requires-Dist: numpy
18
+ Requires-Dist: PyDispatcher
19
+ Requires-Dist: simpleparse
20
+
21
+ PyVRML97 Scenegraph Model
22
+ ==========================
23
+
24
+ PyVRML97 is the scenegraph model from `OpenGLContext`_ but can be used separately
25
+ in VRML97 processing tools. It relies on `SimpleParse`_, `PyDispatcher`_ and `Numpy`_
26
+ to provide the basic modelling functionality.
27
+
28
+ Properties (fields) in PyVRML97 follow the "Observer" pattern, and PyVRML97
29
+ provides a cache mechanism that allows you to do cache invalidation when
30
+ setting properties (fields). OpenGLContext uses that extensively to
31
+ optimize the rendering process.
32
+
33
+ .. _`OpenGLContext`: https://pypi.python.org/pypi/OpenGLContext
34
+ .. _`SimpleParse`: https://pypi.python.org/pypi/SimpleParse
35
+ .. _`PyDispatcher`: https://pypi.python.org/pypi/PyDispatcher
36
+ .. _`Numpy`: https://pypi.python.org/pypi/numpy
37
+
38
+ Installation
39
+ -------------
40
+
41
+ It isn't common to directly install PyVRML97 itself (normally you want to
42
+ install it as part of installing OpenGLContext), but should you wish to, you
43
+ can install via::
44
+
45
+ $ pip install PyVRML97 PyVRML97_accelerate
46
+
47
+ The PyVRML97_accelerate module requires that you have a working compiler
48
+ (or, if you are on Windows, prebuilt wheels likely are available).
49
+
50
+ .. image:: https://ci.appveyor.com/api/projects/status/MikeCFletcher/pyvrml97/branch/master
51
+ :target: https://ci.appveyor.com/project/MikeCFletcher/pyvrml97
52
+ :alt: Appveyor Build
53
+
54
+ .. image:: https://img.shields.io/pypi/v/pyvrml97.svg
55
+ :target: https://pypi.python.org/pypi/pyvrml97
56
+ :alt: Latest PyPI Version
57
+
58
+ .. image:: https://img.shields.io/pypi/dm/pyvrml97.svg
59
+ :target: https://pypi.python.org/pypi/pyvrml97
60
+ :alt: Monthly download counter
61
+
62
+ Build/Release Process
63
+ ----------------------
64
+
65
+ * Push an annotated tag with `version` prefix (github workflow `build_and_publish.yml`)
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyVRML97
3
+ Version: 2.3.4b1
4
+ Summary: VRML97 Scenegraph model for Python
5
+ Author-email: "Mike C. Fletcher" <mcfletch@vrplumber.com>
6
+ License: BSD-style, see license.txt for details
7
+ Project-URL: Homepage, http://pyopengl.sourceforge.net/context/
8
+ Keywords: VRML,VRML97,scenegraph
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: C
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
14
+ Classifier: Intended Audience :: Developers
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/x-rst
17
+ Requires-Dist: numpy
18
+ Requires-Dist: PyDispatcher
19
+ Requires-Dist: simpleparse
20
+
21
+ PyVRML97 Scenegraph Model
22
+ ==========================
23
+
24
+ PyVRML97 is the scenegraph model from `OpenGLContext`_ but can be used separately
25
+ in VRML97 processing tools. It relies on `SimpleParse`_, `PyDispatcher`_ and `Numpy`_
26
+ to provide the basic modelling functionality.
27
+
28
+ Properties (fields) in PyVRML97 follow the "Observer" pattern, and PyVRML97
29
+ provides a cache mechanism that allows you to do cache invalidation when
30
+ setting properties (fields). OpenGLContext uses that extensively to
31
+ optimize the rendering process.
32
+
33
+ .. _`OpenGLContext`: https://pypi.python.org/pypi/OpenGLContext
34
+ .. _`SimpleParse`: https://pypi.python.org/pypi/SimpleParse
35
+ .. _`PyDispatcher`: https://pypi.python.org/pypi/PyDispatcher
36
+ .. _`Numpy`: https://pypi.python.org/pypi/numpy
37
+
38
+ Installation
39
+ -------------
40
+
41
+ It isn't common to directly install PyVRML97 itself (normally you want to
42
+ install it as part of installing OpenGLContext), but should you wish to, you
43
+ can install via::
44
+
45
+ $ pip install PyVRML97 PyVRML97_accelerate
46
+
47
+ The PyVRML97_accelerate module requires that you have a working compiler
48
+ (or, if you are on Windows, prebuilt wheels likely are available).
49
+
50
+ .. image:: https://ci.appveyor.com/api/projects/status/MikeCFletcher/pyvrml97/branch/master
51
+ :target: https://ci.appveyor.com/project/MikeCFletcher/pyvrml97
52
+ :alt: Appveyor Build
53
+
54
+ .. image:: https://img.shields.io/pypi/v/pyvrml97.svg
55
+ :target: https://pypi.python.org/pypi/pyvrml97
56
+ :alt: Latest PyPI Version
57
+
58
+ .. image:: https://img.shields.io/pypi/dm/pyvrml97.svg
59
+ :target: https://pypi.python.org/pypi/pyvrml97
60
+ :alt: Monthly download counter
61
+
62
+ Build/Release Process
63
+ ----------------------
64
+
65
+ * Push an annotated tag with `version` prefix (github workflow `build_and_publish.yml`)
@@ -1,8 +1,8 @@
1
1
  MANIFEST.in
2
2
  README.rst
3
3
  license.txt
4
+ pyproject.toml
4
5
  requirements.txt
5
- setup.py
6
6
  test-requirements.txt
7
7
  tox.ini
8
8
  PyVRML97.egg-info/PKG-INFO
@@ -11,6 +11,11 @@ PyVRML97.egg-info/dependency_links.txt
11
11
  PyVRML97.egg-info/not-zip-safe
12
12
  PyVRML97.egg-info/requires.txt
13
13
  PyVRML97.egg-info/top_level.txt
14
+ tests/test_fieldtypes.py
15
+ tests/test_nodepath.py
16
+ tests/test_olist.py
17
+ tests/test_tostring.py
18
+ tests/test_transformmatrix.py
14
19
  vrml/__init__.py
15
20
  vrml/_bytes.py
16
21
  vrml/arrays.py
@@ -38,3 +38,8 @@ The PyVRML97_accelerate module requires that you have a working compiler
38
38
  .. image:: https://img.shields.io/pypi/dm/pyvrml97.svg
39
39
  :target: https://pypi.python.org/pypi/pyvrml97
40
40
  :alt: Monthly download counter
41
+
42
+ Build/Release Process
43
+ ----------------------
44
+
45
+ * Push an annotated tag with `version` prefix (github workflow `build_and_publish.yml`)
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ # PyVRML97 (the root package) is pure Python - no C extensions - so it needs
3
+ # nothing but setuptools to build. Cython/numpy build-deps live only in
4
+ # accelerate/pyproject.toml, where the extensions actually are. setuptools>=61
5
+ # is required to read the PEP 621 [project] table below.
6
+ requires = ["setuptools>=61.0"]
7
+ build-backend = "setuptools.build_meta"
8
+
9
+ [project]
10
+ name = "PyVRML97"
11
+ dynamic = ["version"]
12
+ description = "VRML97 Scenegraph model for Python"
13
+ requires-python = ">=3.9"
14
+ readme = "README.rst"
15
+ license = { text = "BSD-style, see license.txt for details" }
16
+ authors = [
17
+ { name = "Mike C. Fletcher", email = "mcfletch@vrplumber.com" },
18
+ ]
19
+ dependencies = [
20
+ "numpy",
21
+ "PyDispatcher",
22
+ "simpleparse",
23
+ ]
24
+ keywords = [
25
+ "VRML",
26
+ "VRML97",
27
+ "scenegraph",
28
+ ]
29
+ classifiers = [
30
+ "License :: OSI Approved :: BSD License",
31
+ "Programming Language :: Python",
32
+ "Programming Language :: C",
33
+ "Topic :: Software Development :: Libraries :: Python Modules",
34
+ "Topic :: Multimedia :: Graphics :: 3D Rendering",
35
+ "Intended Audience :: Developers",
36
+ ]
37
+
38
+ [project.urls]
39
+ Homepage = "http://pyopengl.sourceforge.net/context/"
40
+
41
+ [tool.setuptools]
42
+ zip-safe = false
43
+
44
+ [tool.setuptools.packages.find]
45
+ include = ["vrml*"]
46
+
47
+ [tool.setuptools.dynamic]
48
+ version = { attr = "vrml.__version__" }
@@ -0,0 +1,5 @@
1
+ --prefer-binary
2
+ simpleparse
3
+ numpy >= 2.0.1; python_version >= '3.10'
4
+ numpy; python_version < '3.10'
5
+ PyDispatcher
@@ -0,0 +1,4 @@
1
+ -r ./requirements.txt
2
+ pytest
3
+ # pip crashing due to missing dataclasses, sigh
4
+ dataclasses; python_version < '3.7'
@@ -0,0 +1,20 @@
1
+ import unittest,sys
2
+ from vrml import fieldtypes
3
+ from vrml.arrays import allclose,dot,array
4
+ try:
5
+ xrange
6
+ except NameError:
7
+ xrange = range
8
+
9
+ class TestFieldTypes( unittest.TestCase ):
10
+ def test_mfvec3f(self):
11
+ should_work = [
12
+ zip([1,2,3],[2,3,4],[5,6,7]),
13
+ map(int,[1,2,3]),
14
+ xrange(3),
15
+ ]
16
+ field = fieldtypes.MFVec3f(name="moo")
17
+ for value in should_work:
18
+ result = field.coerce(value),value
19
+
20
+
@@ -0,0 +1,80 @@
1
+ import unittest
2
+ from vrml.vrml97 import nodepath
3
+ from vrml.vrml97.basenodes import Transform
4
+ from vrml.arrays import allclose, array, pi,dot
5
+
6
+ class TestNodePath( unittest.TestCase ):
7
+ def setUp( self ):
8
+ self.empty = nodepath.NodePath()
9
+ self.first_child = self.empty + [ Transform( translation=(1,0,0), DEF='first', ) ]
10
+ self.second_child = self.first_child + [ Transform( translation=(1,0,0), DEF='second') ]
11
+ self.third_child = self.second_child + [ Transform( translation=(3,0,0), scale=(2,1,2), rotation=(0,1,0,pi/2), DEF='third',)]
12
+ self.fourth_child = self.third_child + [ Transform( DEF='fourth',) ]
13
+ def test_empty_matrix( self ):
14
+ m = self.empty.transformMatrix()
15
+ assert allclose(
16
+ m,
17
+ array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],'f')
18
+ ), m
19
+ def test_second_child( self ):
20
+ m = self.second_child.transformMatrix()
21
+ assert allclose(
22
+ m,
23
+ array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[2,0,0,1]],'f')
24
+ ), m
25
+ def test_change_translation( self ):
26
+ self.first_child[-1].translation = (-1,0,0)
27
+ m2 = self.second_child.transformMatrix()
28
+ assert allclose(
29
+ m2,
30
+ array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],'f')
31
+ ), m2
32
+ def test_change_rotation( self ):
33
+ self.first_child[-1].rotation = (0,1,0,3.14)
34
+ m = self.second_child.transformMatrix( translate=False, scale=False)
35
+ self.first_child[-1].rotation = (0,1,0,0.0)
36
+ m2 = self.second_child.transformMatrix( translate=False, scale=False)
37
+ assert not allclose( m,m2 ), (m,m2)
38
+
39
+ def test_iterchildren( self ):
40
+ l = list( self.first_child.iterchildren())
41
+ assert l == [ self.second_child ]
42
+ def test_iterdescendents( self ):
43
+ l = list( self.empty.iterdescendents())
44
+ assert l == [ self.first_child, self.second_child ]
45
+
46
+ def test_forward_back( self ):
47
+ for child in (self.second_child,self.third_child,self.fourth_child):
48
+ matrix = child.transformMatrix( )
49
+ inverse = child.transformMatrix( inverse=True )
50
+ test = array( [10,20,30,1], 'f')
51
+ projected = dot( matrix, test )
52
+ back = dot( inverse, projected )
53
+ assert allclose( test, back ), (test,back, child[-1], matrix, inverse)
54
+ def test_complex_transform( self ):
55
+ test = array( [0,0,10,1], 'f' )
56
+ matrix = self.fourth_child.transformMatrix( )
57
+ #inverse = self.fourth_child.transformMatrix( inverse=True )
58
+ projected = dot( test, matrix )
59
+ # projecting out of the screen, then rotated
60
+ # counter-clockwise 90deg (to go right), then scaled up 2x (to 20)
61
+ # then translated 5 to the right...
62
+ target = array([25,0,0,1],'f')
63
+ assert allclose( projected, target, atol=0.0001), projected
64
+
65
+ def test_nest_simple( self ):
66
+ path = self.empty + [
67
+ Transform( translation=(0,0,1), DEF='translate', ),
68
+ Transform( scale=(1,1,.5),DEF='scale'),
69
+ ]
70
+ matrix = path.transformMatrix()
71
+ projected = dot( array([0,0,10,1],'f'), matrix )
72
+ assert allclose( projected, array([0,0,6,1]),atol=.0001), projected
73
+
74
+ def test_rotation_array( self ):
75
+ path = self.empty + [
76
+ Transform( rotation = (0,1,0,pi/2 )),
77
+ ]
78
+ matrix = path.transformMatrix()
79
+ projected = dot( array([ 0,0,1,1],'f'),matrix )
80
+ assert allclose( projected, array([1,0,0,1],'f'),atol=.0001), projected
@@ -0,0 +1,43 @@
1
+ import unittest
2
+ from vrml import olist
3
+ from pydispatch.dispatcher import connect
4
+
5
+ class TestOList( unittest.TestCase ):
6
+ def setUp( self ):
7
+ self.out = []
8
+ self.olist = olist.OList()
9
+ connect( self.on_new, sender=self.olist )
10
+ def on_new( self, signal, value ):
11
+ self.out.append( (signal,value) )
12
+ def test_append( self ):
13
+ self.olist.append( 'this' )
14
+ assert self.out == [('new','this')], self.out
15
+ def test_setitem( self ):
16
+ self.olist[:] = [ 'those','them','their' ]
17
+ del self.out[:]
18
+ self.olist[1] = 'that'
19
+ assert self.out == [('del','them'),('new','that')], self.out
20
+ def test_pop( self ):
21
+ self.olist[:] = [ 'those','them','that' ]
22
+ del self.out[:]
23
+ popped = self.olist.pop( )
24
+ assert popped == 'that', popped
25
+ assert self.out == [('del','that')]
26
+ def test_insert( self ):
27
+ self.olist.insert( 0, 'those' )
28
+ assert self.out == [('new','those')]
29
+ def test_remove( self ):
30
+ self.olist[:] = [ 'those','them','their' ]
31
+ del self.out[:]
32
+ self.olist.remove( 'those' )
33
+ assert self.out == [('del','those')]
34
+ def test_delslice( self ):
35
+ self.olist[:] = [ 'those','them','their' ]
36
+ del self.out[:]
37
+ del self.olist[1:2]
38
+ assert self.out == [('del','them')], self.out
39
+ def test_setslice( self ):
40
+ self.olist[:] = [ 'those','them','their','thou' ]
41
+ del self.out[:]
42
+ self.olist[1:3] = ['them','those','that','them']
43
+ assert self.out == [('new','those'),('new','that'),('del','their')], self.out
@@ -0,0 +1,50 @@
1
+ import unittest, os
2
+ from vrml.vrml97.parser import buildParser
3
+ from vrml.vrml97.basenodes import Transform
4
+ from vrml.vrml97.shaders import (
5
+ ShaderGeometry,
6
+ Shader,
7
+ ShaderAttribute,
8
+ GLSLObject,
9
+ FloatUniform, # not functional, but ok
10
+ )
11
+ from vrml.vrml97.scenegraph import SceneGraph
12
+ import numpy as np
13
+
14
+ HERE = os.path.dirname(os.path.abspath(__file__))
15
+
16
+ # to prevent issues if more than one file uses a .wrl or if they somehow use recursive inlines
17
+ ALREADY_PROCESSED = []
18
+
19
+ VRMLPARSER = buildParser()
20
+
21
+ depth = 0
22
+
23
+
24
+ class TestToString(unittest.TestCase):
25
+
26
+ def parsed_content(self, source):
27
+ parser = buildParser()
28
+ result = parser.parse(source)
29
+ success, result, parsed = result
30
+ if not success:
31
+ raise RuntimeError("Did not finish parse")
32
+ if parsed < len(source):
33
+ raise RuntimeError("Partial parse %d/%d characters" % (parsed, len(source)))
34
+ scene = result[1]
35
+ assert isinstance(scene, SceneGraph), scene
36
+ return scene
37
+
38
+ def test_to_string_simple(self):
39
+ source = open(os.path.join(HERE, 'fixtures', 'proto_is_simple.wrl')).read()
40
+ scene = self.parsed_content(source)
41
+ assert len(scene.children) == 1, scene.children
42
+ content = scene.toString()
43
+ assert 'PROTO' in content, content
44
+ assert 'X {' in content, content # TODO: relies on default formatting...
45
+
46
+ def test_to_string_spec_file(self):
47
+ source = open(os.path.join(HERE, 'fixtures', 'exampleD.2.wrl')).read()
48
+ scene = self.parsed_content(source)
49
+ content = scene.toString()
50
+ assert 'Material' in content, content
@@ -0,0 +1,85 @@
1
+ import unittest,sys
2
+ from vrml.arrays import pi,array
3
+ from vrml.vrml97 import transformmatrix
4
+ from vrml.arrays import allclose,dot
5
+ DEGTORAD = transformmatrix.DEGTORAD
6
+ try:
7
+ from vrml.vrml97 import _transformmatrix_accel
8
+ except ImportError:
9
+ _transformmatrix_accel = None
10
+ from vrml.vrml97 import _transformmatrix
11
+
12
+ class TestTransformMatrix( unittest.TestCase ):
13
+ def test_calculations( self ):
14
+ for (matrix,point, expected, name) in self._create_test_matrix(
15
+ transformmatrix.transMatrix,
16
+ transformmatrix.rotMatrix,
17
+ transformmatrix.scaleMatrix,
18
+ ):
19
+ try:
20
+ result = dot( point,matrix)
21
+ except TypeError as err:
22
+ sys.stderr.write("""\nF (TypeError):\n\tpoint=%(point)s\n\t%(matrix)s\n"""%(locals()))
23
+ else:
24
+ assert allclose( result, expected, 0, 0.000001 ),(name,matrix,point,expected,result)
25
+
26
+ def _create_test_matrix( self, transMatrix,rotMatrix,scaleMatrix ):
27
+ return [
28
+ (transMatrix( (1,0,0) )[0], (0, 0,0,1), (1,0,0,1), "Simple translation"),
29
+ (transMatrix( (-1,-1,-1) )[0], (1, 1,1,1), (0,0,0,1), "Simple translation"),
30
+ (transMatrix( (0,0,1) )[0], (0, 0,0,1), (0,0,1,1), "Simple translation"),
31
+ (rotMatrix( (0,1,0,pi) )[0], (1, 0,0,1), (-1,0,0,1), "Simple rotation"),
32
+ (rotMatrix( (0,1,0,pi/2) )[0], (1, 0,0,1), (0,0,-1,1), "Simple rotation"),
33
+ (rotMatrix( (0,0,1,pi/2) )[0], (1, 0,0,1), (0,1,0,1), "Simple rotation"),
34
+ (rotMatrix( (0,0,1,-(pi/2)) )[0], (1, 0,0,1), (0,-1,0,1), "Simple rotation"),
35
+ (rotMatrix( (0,0,-1,-(pi/2)) )[0], (1, 0,0,1), (0,1,0,1), "Simple rotation"),
36
+ (rotMatrix( (0,0,-2,-(pi/2)) )[0], (1, 0,0,1), (0,1,0,1), "Simple rotation (w/normalize)"),
37
+ (rotMatrix( (1,0,0,-(pi/2)) )[0], (1, 0,0,1), (1,0,0,1), "Simple rotation"),
38
+ (rotMatrix( (0,0,1,pi/2) )[0], (0,1,0,1), (-1,0,0,1), "Simple rotation"),
39
+ (rotMatrix( (1,0,0,pi/2) )[0], (0,0,1,1), (0,-1,0,1), "Simple rotation"),
40
+ (scaleMatrix( (1,1,2) )[0], (1, 1,1,1), (1,1,2,1), "Simple scale"),
41
+ (scaleMatrix( (-1,1,2) )[0], (1, 1,1,1), (-1,1,2,1), "Simple scale"),
42
+ (scaleMatrix( (-1,0,2) )[0], (1, 1,1,1), (-1,0,2,1), "Simple scale"),
43
+ (scaleMatrix( (-1,0,0) )[0], (1, 1,1,1), (-1,0,0,1), "Simple scale"),
44
+ (scaleMatrix( (0,0,0) )[0], (1, 1,1,1), (0,0,0,1), "Simple scale"),
45
+ (rotMatrix([ 0.,0.,1., -0.515])[0], (1,0,0,1), (0.87029272,-0.49253485,0.,1.), "Make sure rotation uses float check for abs value" ),
46
+ ]
47
+
48
+ def test_perspectiveMatrix( self ):
49
+ """Test that perspective matrix calculation matches expected values"""
50
+ result = transformmatrix.perspectiveMatrix(
51
+ 59.999999999999993*DEGTORAD, 1.0, 0.29999999999999999, 50000
52
+ )
53
+ inverse = transformmatrix.perspectiveMatrix(
54
+ 59.999999999999993*DEGTORAD, 1.0, 0.29999999999999999, 50000, inverse=True,
55
+ )
56
+
57
+ expected = array([
58
+ [ 1.73205081, 0., 0., 0., ],
59
+ [ 0., 1.73205081, 0., 0., ],
60
+ [ 0., 0., -1.000012, -1., ],
61
+ [ 0., 0., -0.6000036, 0., ],],'f')
62
+ assert allclose(result,expected), result
63
+
64
+ test = array([ 20,8,5,1.0 ],'f')
65
+ projected = dot( result, test )
66
+ print(projected)
67
+ unprojected = dot( inverse, projected )
68
+ assert allclose( unprojected, test ), (unprojected, test)
69
+
70
+ if _transformmatrix_accel:
71
+ def test_cross_check( self ):
72
+ first = self._create_test_matrix(
73
+ _transformmatrix_accel.transMatrix,
74
+ _transformmatrix_accel.rotMatrix,
75
+ _transformmatrix_accel.scaleMatrix,
76
+ )
77
+ second = self._create_test_matrix(
78
+ _transformmatrix.transMatrix,
79
+ _transformmatrix.rotMatrix,
80
+ _transformmatrix.scaleMatrix,
81
+ )
82
+ for (firstmatrix,_,_,_),(secondmatrix,point, _, name) in zip(first,second):
83
+ assert allclose(firstmatrix,secondmatrix, atol=0.000001), (firstmatrix,secondmatrix,name)
84
+
85
+
@@ -1,5 +1,5 @@
1
1
  [tox]
2
- envlist=py{27,36,37}-accel{0,1}
2
+ envlist=py{312,311,310,38}-accel{0,1}
3
3
  skip_missing_interpreters=True
4
4
  [testenv]
5
5
  usedevelop=True
@@ -17,6 +17,6 @@ standard. For instance, the vrml.vrml97.basenodes
17
17
  file contains the "prototypes" for most of the
18
18
  built-in nodes in the official specification.
19
19
  """
20
- __version__ = "2.3.1"
20
+ __version__ = "2.3.4b1"
21
21
  __author__ = "Michael Colin Fletcher"
22
22
  __license__ = "BSD-style, see license.txt for details"
@@ -3,27 +3,30 @@
3
3
  Chooses numpy if available because when it's installed
4
4
  Numeric tends to be a bit flaky...
5
5
  """
6
+
6
7
  from numpy import *
8
+
7
9
  try:
8
- # TODO: don't import this here, as it's not
9
- # actually *used* in pyvrml97, it's just used
10
+ # TODO: don't import this here, as it's not
11
+ # actually *used* in pyvrml97, it's just used
10
12
  # in OpenGLContext...
11
13
  from vrml_accelerate import frustcullaccel
12
14
  except ImportError as err:
13
15
  frustcullaccel = None
14
16
  # why did this get taken out? Is divide now safe?
15
- amin = amin
17
+ amin = amin
16
18
  amax = amax
17
- divide_safe = divide
19
+ divide_safe = divide
18
20
  # Now deal with differing numpy APIs...
19
- a = array([1,2,3],'i')
20
- ArrayType = ndarray # alias removed in later versions
21
- # Take's API changed from Numeric, we've updated to
21
+ a = array([1, 2, 3], 'i')
22
+ ArrayType = ndarray # alias removed in later versions
23
+ # Take's API changed from Numeric, we've updated to
22
24
  # always provide axis now...
23
- if hasattr( a, '__array_typestr__' ):
24
- def typeCode( a ):
25
+ if hasattr(a, '__array_typestr__'):
26
+
27
+ def typeCode(a):
25
28
  """Retrieve the typecode for the given array
26
-
29
+
27
30
  Depending on whether you access the classic or new API
28
31
  you have different access methods, so we have to use
29
32
  the typecode() method if __array_typestr__ isn't there.
@@ -32,10 +35,12 @@ if hasattr( a, '__array_typestr__' ):
32
35
  return a.__array_typestr__
33
36
  except AttributeError:
34
37
  return a.typecode()
38
+
35
39
  else:
36
- def typeCode( a ):
40
+
41
+ def typeCode(a):
37
42
  """Retrieve the typecode for the given array
38
-
43
+
39
44
  Depending on whether you access the classic or new API
40
45
  you have different access methods, so we have to use
41
46
  the typecode() method if .dtype.char isn't there.
@@ -44,24 +49,38 @@ else:
44
49
  return a.dtype.char
45
50
  except AttributeError:
46
51
  return a.typecode()
52
+
53
+
47
54
  del a
48
55
  implementation_name = 'numpy'
49
56
  try:
50
- # PyVRML97 is from before numpy printed errors, we explicitly do not care
57
+ # PyVRML97 is from before numpy printed errors, we explicitly do not care
51
58
  # about the divide-by-zero, which commonly happens in mesh data processing
52
- # TODO: likely should rework the mesh processing to check manually and remove
59
+ # TODO: likely should rework the mesh processing to check manually and remove
53
60
  # this sledge-hammer approach
54
61
  seterr(all='ignore')
55
62
  except Exception as err:
56
63
  pass
57
-
58
- def safeCompare( first, second ):
64
+
65
+
66
+ def safeCompare(first, second):
59
67
  """Watch out for pointless numpy truth-value checks"""
60
- try:
61
- return bool(first == second )
62
- except ValueError:
63
- return bool( any( first == second ) )
68
+ if first is None:
69
+ if second is None:
70
+ return True
71
+ else:
72
+ return False
73
+ elif second is None:
74
+ return False
75
+ if isinstance(first, (int, float, str)):
76
+ return first == second
77
+ if isinstance(first, ArrayType) and isinstance(second, ArrayType):
78
+ return bool(any(first == second))
79
+ elif type(first) != type(second):
80
+ return False
81
+ return bool(first == second)
82
+
64
83
 
65
- def contiguous( a ):
84
+ def contiguous(a):
66
85
  """Force to a contiguous array"""
67
- return array( a, typeCode(a) )
86
+ return array(a, typeCode(a))