PyVRML97 2.3.1__tar.gz → 2.3.4b3__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.
- pyvrml97-2.3.4b3/PKG-INFO +65 -0
- pyvrml97-2.3.4b3/PyVRML97.egg-info/PKG-INFO +65 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/PyVRML97.egg-info/SOURCES.txt +6 -1
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/README.rst +5 -0
- pyvrml97-2.3.4b3/pyproject.toml +48 -0
- pyvrml97-2.3.4b3/requirements.txt +5 -0
- pyvrml97-2.3.4b3/test-requirements.txt +4 -0
- pyvrml97-2.3.4b3/tests/test_fieldtypes.py +20 -0
- pyvrml97-2.3.4b3/tests/test_nodepath.py +80 -0
- pyvrml97-2.3.4b3/tests/test_olist.py +43 -0
- pyvrml97-2.3.4b3/tests/test_tostring.py +50 -0
- pyvrml97-2.3.4b3/tests/test_transformmatrix.py +85 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/tox.ini +1 -1
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/__init__.py +1 -1
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/arrays.py +41 -22
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/field.py +189 -146
- pyvrml97-2.3.4b3/vrml/fieldtypes.py +1491 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/node.py +231 -168
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/protofunctions.py +100 -54
- pyvrml97-2.3.4b3/vrml/vrml97/linearise.py +579 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/nodepath.py +1 -1
- pyvrml97-2.3.4b3/vrml/vrml97/parseprocessor.py +452 -0
- PyVRML97-2.3.1/PKG-INFO +0 -27
- PyVRML97-2.3.1/PyVRML97.egg-info/PKG-INFO +0 -27
- PyVRML97-2.3.1/requirements.txt +0 -3
- PyVRML97-2.3.1/setup.py +0 -74
- PyVRML97-2.3.1/test-requirements.txt +0 -2
- PyVRML97-2.3.1/vrml/fieldtypes.py +0 -1052
- PyVRML97-2.3.1/vrml/vrml97/linearise.py +0 -527
- PyVRML97-2.3.1/vrml/vrml97/parseprocessor.py +0 -443
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/MANIFEST.in +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/PyVRML97.egg-info/dependency_links.txt +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/PyVRML97.egg-info/not-zip-safe +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/PyVRML97.egg-info/requires.txt +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/PyVRML97.egg-info/top_level.txt +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/license.txt +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/setup.cfg +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/_bytes.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/cache.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/copier.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/csscolors.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/event.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/nodepath.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/olist.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/protonamespace.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/route.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml200x/__init__.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml200x/parser.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/__init__.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/_transformmatrix.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/_transformmatrix_accel.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/basenamespaces.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/basenodes.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/nodetypes.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/nurbs.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/parser.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/scenegraph.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/script.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/shaders.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/vrml97/transformmatrix.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/weakkeydictfix.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/weaklist.py +0 -0
- {PyVRML97-2.3.1 → pyvrml97-2.3.4b3}/vrml/weaktuple.py +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyVRML97
|
|
3
|
+
Version: 2.3.4b3
|
|
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.4b3
|
|
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,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
|
+
|
|
@@ -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.
|
|
20
|
+
__version__ = "2.3.4b3"
|
|
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
|
|
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(
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def safeCompare(first, second):
|
|
59
67
|
"""Watch out for pointless numpy truth-value checks"""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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(
|
|
84
|
+
def contiguous(a):
|
|
66
85
|
"""Force to a contiguous array"""
|
|
67
|
-
return array(
|
|
86
|
+
return array(a, typeCode(a))
|