├── pyproject.toml ├── .gitignore ├── tests ├── data │ └── sphere.npz ├── test_basic.py └── test_embree.py ├── examples └── sphere │ ├── icosa_sphere_5.npz │ ├── faces.txt │ └── verts.txt ├── .zenodo.json ├── ci ├── embree3.bat └── embree3.bash ├── setup.py ├── .github └── workflows │ └── wheels.yml ├── README.md ├── LICENSE.txt └── embree.pyx /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ['Cython', 'setuptools', 'wheel'] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.egg-info 3 | *.so 4 | *~ 5 | __pycache__ 6 | build 7 | dist -------------------------------------------------------------------------------- /tests/data/sphere.npz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sampotter/python-embree/HEAD/tests/data/sphere.npz -------------------------------------------------------------------------------- /examples/sphere/icosa_sphere_5.npz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sampotter/python-embree/HEAD/examples/sphere/icosa_sphere_5.npz -------------------------------------------------------------------------------- /.zenodo.json: -------------------------------------------------------------------------------- 1 | { 2 | "creators": [ 3 | { 4 | "name": "Samuel F. Potter", 5 | "affiliation": "University of Maryland, College Park, MD, USA" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ci/embree3.bat: -------------------------------------------------------------------------------- 1 | curl -L -o embree.zip https://github.com/embree/embree/releases/download/v3.13.3/embree-3.13.3.x64.vc14.windows.zip 2 | 7z x embree.zip 3 | move embree-3.13.3.x64.vc14.windows embree3 4 | -------------------------------------------------------------------------------- /tests/test_basic.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class BasicTest(unittest.TestCase): 5 | 6 | def test_import(self): 7 | 8 | import embree 9 | 10 | 11 | if __name__ == '__main__': 12 | unittest.main() 13 | -------------------------------------------------------------------------------- /ci/embree3.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -xe 3 | 4 | VERSION="3.13.3" 5 | 6 | rm -rf /tmp/embree.tar.gz 7 | rm -rf ~/embree 8 | 9 | wget -nv https://github.com/embree/embree/releases/download/v${VERSION}/embree-${VERSION}.x86_64.linux.tar.gz -O /tmp/embree.tar.gz 10 | cd /tmp 11 | tar -zxvf embree.tar.gz 12 | rm -f embree.tar.gz 13 | 14 | mv embree-${VERSION}.x86_64.linux ~/embree 15 | 16 | 17 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import find_packages, setup 4 | from setuptools.extension import Extension 5 | from Cython.Build import cythonize 6 | 7 | # the current working directory 8 | cwd = os.path.abspath(os.path.expanduser( 9 | os.path.dirname(__file__))) 10 | 11 | include = ['/opt/local/include', 12 | os.path.expanduser('~/embree/include')] 13 | library = ['/opt/local/lib', 14 | os.path.expanduser('~/embree/lib')] 15 | 16 | if os.name == 'nt': 17 | include = [ 18 | 'c:/Program Files/Intel/Embree3/include', 19 | os.path.join(cwd, 'embree3', 'include')] 20 | library = [ 21 | 'c:/Program Files/Intel/Embree3/lib', 22 | os.path.join(cwd, 'embree3', 'lib')] 23 | 24 | extensions = [ 25 | Extension( 26 | 'embree', 27 | ['embree.pyx'], 28 | libraries=['embree3'], 29 | include_dirs=include, 30 | library_dirs=library 31 | ) 32 | ] 33 | 34 | with open(os.path.join(cwd, 'README.md'), 'r') as f: 35 | long_description = f.read() 36 | with open(os.path.join(cwd, 'embree.pyx'), 'r') as f: 37 | # use eval to get a clean string of version from file 38 | __version__ = eval( 39 | next(line for line in f if 40 | line.startswith('__version__')).split('=')[-1]) 41 | 42 | setup( 43 | name='embree', 44 | version=__version__, 45 | description='Ray queries on triangular meshes.', 46 | long_description=long_description, 47 | long_description_content_type='text/markdown', 48 | install_requires=['numpy'], 49 | packages=find_packages(), 50 | ext_modules=cythonize(extensions), 51 | zip_safe=False 52 | ) 53 | -------------------------------------------------------------------------------- /.github/workflows/wheels.yml: -------------------------------------------------------------------------------- 1 | name: Build Wheels 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build_wheels: 7 | name: Build wheel on ${{ matrix.os }} 8 | runs-on: ${{ matrix.os }} 9 | env: 10 | CIBW_SKIP: pp* *-win32 *musllinux* 11 | CIBW_ARCHS: auto64 12 | CIBW_TEST_REQUIRES: pytest numpy 13 | CIBW_TEST_COMMAND: pytest -v {project}/tests 14 | CIBW_BEFORE_BUILD_LINUX: "yum install -y cmake wget; pip install cython; bash {project}/ci/embree3.bash" 15 | CIBW_REPAIR_WHEEL_COMMAND_LINUX: "LD_LIBRARY_PATH=/root/embree/lib; auditwheel repair -w {dest_dir} {wheel}" 16 | CIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel" 17 | CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair --add-path embree3\\bin; --no-mangle tbb12.dll;embree3.dll -w {dest_dir} {wheel}" 18 | strategy: 19 | matrix: 20 | os: [ubuntu-latest, windows-latest] 21 | steps: 22 | - uses: actions/checkout@v1 23 | - uses: actions/setup-python@v1 24 | name: Install Python 25 | with: 26 | python-version: '3.7' 27 | - name: Install cibuildwheel 28 | run: | 29 | python -m pip install cibuildwheel==2.3.1 30 | - name: Install Embree On Windows 31 | if: matrix.os == 'windows-latest' 32 | run: | 33 | ci/embree3.bat 34 | - name: Build wheels 35 | run: | 36 | python -m cibuildwheel --output-dir wheelhouse 37 | - uses: actions/upload-artifact@v1 38 | with: 39 | name: wheels 40 | path: ./wheelhouse 41 | - name: Upload To PyPi 42 | env: 43 | TWINE_USERNAME: __token__ 44 | TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} 45 | run: | 46 | pip install twine 47 | twine upload ./wheelhouse/* 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![DOI](https://zenodo.org/badge/194721283.svg)](https://zenodo.org/badge/latestdoi/194721283) 2 | [![Build Status](https://app.travis-ci.com/sampotter/python-embree.svg?branch=master)](https://app.travis-ci.com/sampotter/python-embree) 3 | 4 | # python-embree # 5 | 6 | This library is a thin wrapper around Embree 3. 7 | 8 | As much as possible, it tries to emulate the C API usage. The main 9 | point of this is to avoid creating a new API which would obfuscate the 10 | usage of the C API. Ideally, it should be easy to read the Embree 11 | documentation or examples, and translate things straightforwardly to 12 | equivalent Python code. 13 | 14 | A secondary goal is to provide easy interoperability with numpy. 15 | 16 | **NOTE**: *very little of the library is wrapped so far, but this 17 | library is being developed in a way that should make it as easy as 18 | possible to wrap more functionality as necessary. If you find that a 19 | function that you'd like to use isn't wrapped, please create an issue 20 | or feel free to wrap it on your own and submit a pull request.* 21 | 22 | ## Installation 23 | 24 | ### Windows 25 | 26 | If you install Embree using the MSI from Embree's website, the Embree 27 | binaries, headers, and libraries will all be installed to `C:\Program 28 | Files\Intel\Embree3` by default. 29 | 30 | As an example, to compile using MSYS2 from the MinGW 64-bit console, 31 | after `cd`ing to the root directory of this repository, it should be 32 | possible to run: 33 | 34 | ``` 35 | $ python setup.py build_ext -I/c/Program\ Files/Intel/Embree3/include -L /c/Program\ Files/Intel/Embree3/lib 36 | $ python setup.py install 37 | ``` 38 | 39 | to successfully compile and install python-embree. 40 | 41 | ## Tips and tricks 42 | 43 | ### Retain and release 44 | 45 | The underlying Embree library uses reference counting to properly 46 | clean up resources used by the different types it provides 47 | (`RTCDevice`, `RTCScene`, etc.). This means that each type exposes a 48 | pair of "retain" and "release" functions: e.g., `rtcRetainDevice`, and 49 | `rtcReleaseDevice`. How to use these correctly is spelled out in the 50 | [Embree API docs](https://www.embree.org/api.html) and the [many 51 | Embree tutorials](https://www.embree.org/tutorials.html). Please 52 | consult these when using 53 | [python-embree](https://github.com/sampotter/python-embree). The 54 | classes providing a lightweight object-oriented wrapper around 55 | Embree's types *do not call any retain or release functions behind the 56 | scenes: this is the user's responsibility*. 57 | 58 | ### Parallelism 59 | 60 | Using 61 | [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) 62 | for concurrency in Python requires objects that are put into queues to 63 | be serialized using 64 | [pickle](https://docs.python.org/3/library/pickle.html). Unfortunately, 65 | it is not currently possible to serialize the Embree data structures 66 | (see the Embree repository's issues 67 | [#137](https://github.com/embree/embree/issues/137) and 68 | [#238](https://github.com/embree/embree/issues/238)), and there do not 69 | appear to be plans to support this feature. The rationale for not 70 | supporting this feature is that building the Embree BVH from scratch 71 | is usually faster than reading the equivalent amount of data from 72 | disk. 73 | 74 | This means that you will not be able to use any of the extensions 75 | classes exported by 76 | [embree.pyx](https://github.com/sampotter/python-embree/blob/master/embree.pyx) 77 | (such as `embree.Device`, `embree.Scene`, etc.) with multiprocessing 78 | *directly*. To get around this problem, a simple fix is to wrap a bit 79 | of Embree functionality in a Python class with its own `__reduce__` 80 | method. For an example, see the implementation of `TrimeshShapeModel` 81 | [here](https://github.com/sampotter/python-flux/blob/master/flux/shape.py). 82 | -------------------------------------------------------------------------------- /tests/test_embree.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import embree 4 | import numpy as np 5 | import unittest 6 | 7 | 8 | cwd = os.path.expanduser( 9 | os.path.abspath(os.path.dirname(__file__))) 10 | 11 | 12 | np.seterr('raise') 13 | 14 | 15 | class TestIntersect1M(unittest.TestCase): 16 | def setUp(self): 17 | 18 | with open(os.path.join(cwd, 'data', 'sphere.npz'), 'rb') as f: 19 | npz = np.load(f) 20 | verts, faces = npz['V'], npz['F'] 21 | 22 | self.verts = verts.astype(np.float32) 23 | self.num_verts = verts.shape[0] 24 | 25 | self.faces = faces.astype(np.uint32) 26 | self.num_faces = faces.shape[0] 27 | 28 | self.centroids = self.verts[self.faces].mean(1) 29 | 30 | self.device = embree.Device() 31 | self.scene = self.device.make_scene() 32 | self.geometry = self.device.make_geometry(embree.GeometryType.Triangle) 33 | 34 | vertex_buffer = self.geometry.set_new_buffer( 35 | embree.BufferType.Vertex, # buf_type 36 | 0, # slot 37 | embree.Format.Float3, # fmt 38 | 3 * np.dtype('float32').itemsize, # byte_stride 39 | self.num_verts) # item_count 40 | vertex_buffer[:] = self.verts[:] 41 | 42 | index_buffer = self.geometry.set_new_buffer( 43 | embree.BufferType.Index, # buf_type 44 | 0, # slot 45 | embree.Format.Uint3, # fmt 46 | 3 * np.dtype('uint32').itemsize, # byte_stride, 47 | self.num_faces) # item count 48 | index_buffer[:] = self.faces[:] 49 | 50 | self.geometry.commit() 51 | self.scene.attach_geometry(self.geometry) 52 | self.geometry.release() 53 | self.scene.commit() 54 | 55 | def test_ray_shot_from_sphere_center(self): 56 | rayhit = embree.RayHit1M(self.num_faces) 57 | rayhit.org[:] = 0 58 | rayhit.dir[:] = np.divide( 59 | self.centroids, 60 | np.sqrt(np.sum(self.centroids**2, axis=1)).reshape(-1, 1) 61 | ) 62 | rayhit.tnear[:] = 0 63 | rayhit.tfar[:] = np.inf 64 | rayhit.flags[:] = 0 65 | rayhit.geom_id[:] = embree.INVALID_GEOMETRY_ID 66 | 67 | context = embree.IntersectContext() 68 | self.scene.intersect1M(context, rayhit) 69 | 70 | self.assertTrue((rayhit.geom_id != embree.INVALID_GEOMETRY_ID).all()) 71 | self.assertTrue((rayhit.prim_id == np.arange(self.num_faces)).all()) 72 | 73 | def test_rays_shot_between_sphere_facets(self): 74 | N = self.num_faces 75 | 76 | rayhit = embree.RayHit1M(N**2) 77 | 78 | for i in range(N): 79 | rayhit.org[N * i:N * (i + 1)] = self.centroids[i] 80 | 81 | for i in range(N): 82 | D = self.centroids - self.centroids[i] 83 | dist = np.sqrt(np.sum(D**2, axis=1)) 84 | dist[dist == 0] = np.inf 85 | D /= dist.reshape(-1, 1) 86 | rayhit.dir[N * i:N * (i + 1)] = D 87 | 88 | rayhit.tnear[:] = 0.01 89 | rayhit.tfar[:] = np.inf 90 | rayhit.flags[:] = 0 91 | rayhit.geom_id[:] = embree.INVALID_GEOMETRY_ID 92 | 93 | context = embree.IntersectContext() 94 | self.scene.intersect1M(context, rayhit) 95 | 96 | for i in range(N): 97 | geom_id = rayhit.geom_id[N * i:N * (i + 1)] 98 | self.assertTrue(geom_id[i] == embree.INVALID_GEOMETRY_ID) 99 | J = np.setdiff1d(np.arange(N), [i]) 100 | self.assertTrue((geom_id[J] != embree.INVALID_GEOMETRY_ID).all()) 101 | 102 | for i in range(N): 103 | prim_id = rayhit.prim_id[N * i:N * (i + 1)] 104 | J = np.setdiff1d(np.arange(N), [i]) 105 | self.assertTrue((prim_id[J] == np.arange(N)[J]).all()) 106 | 107 | 108 | if __name__ == '__main__': 109 | unittest.main() 110 | -------------------------------------------------------------------------------- /examples/sphere/faces.txt: -------------------------------------------------------------------------------- 1 | 0 30 21 2 | 30 31 102 3 | 31 32 103 4 | 32 11 89 5 | 30 102 21 6 | 31 103 102 7 | 32 89 103 8 | 21 102 22 9 | 102 103 104 10 | 103 89 88 11 | 102 104 22 12 | 103 88 104 13 | 22 104 23 14 | 104 88 87 15 | 104 87 23 16 | 23 87 5 17 | 0 21 54 18 | 21 22 105 19 | 22 23 106 20 | 23 5 71 21 | 21 105 54 22 | 22 106 105 23 | 23 71 106 24 | 54 105 55 25 | 105 106 107 26 | 106 71 70 27 | 105 107 55 28 | 106 70 107 29 | 55 107 56 30 | 107 70 69 31 | 107 69 56 32 | 56 69 1 33 | 0 54 57 34 | 54 55 108 35 | 55 56 109 36 | 56 1 93 37 | 54 108 57 38 | 55 109 108 39 | 56 93 109 40 | 57 108 58 41 | 108 109 110 42 | 109 93 94 43 | 108 110 58 44 | 109 94 110 45 | 58 110 59 46 | 110 94 95 47 | 110 95 59 48 | 59 95 7 49 | 0 57 66 50 | 57 58 111 51 | 58 59 112 52 | 59 7 33 53 | 57 111 66 54 | 58 112 111 55 | 59 33 112 56 | 66 111 67 57 | 111 112 113 58 | 112 33 34 59 | 111 113 67 60 | 112 34 113 61 | 67 113 68 62 | 113 34 35 63 | 113 35 68 64 | 68 35 10 65 | 0 66 30 66 | 66 67 114 67 | 67 68 115 68 | 68 10 63 69 | 66 114 30 70 | 67 115 114 71 | 68 63 115 72 | 30 114 31 73 | 114 115 116 74 | 115 63 64 75 | 114 116 31 76 | 115 64 116 77 | 31 116 32 78 | 116 64 65 79 | 116 65 32 80 | 32 65 11 81 | 1 69 27 82 | 69 70 117 83 | 70 71 118 84 | 71 5 48 85 | 69 117 27 86 | 70 118 117 87 | 71 48 118 88 | 27 117 28 89 | 117 118 119 90 | 118 48 49 91 | 117 119 28 92 | 118 49 119 93 | 28 119 29 94 | 119 49 50 95 | 119 50 29 96 | 29 50 9 97 | 5 87 41 98 | 87 88 120 99 | 88 89 121 100 | 89 11 53 101 | 87 120 41 102 | 88 121 120 103 | 89 53 121 104 | 41 120 40 105 | 120 121 122 106 | 121 53 52 107 | 120 122 40 108 | 121 52 122 109 | 40 122 39 110 | 122 52 51 111 | 122 51 39 112 | 39 51 4 113 | 11 65 26 114 | 65 64 123 115 | 64 63 124 116 | 63 10 74 117 | 65 123 26 118 | 64 124 123 119 | 63 74 124 120 | 26 123 25 121 | 123 124 125 122 | 124 74 73 123 | 123 125 25 124 | 124 73 125 125 | 25 125 24 126 | 125 73 72 127 | 125 72 24 128 | 24 72 2 129 | 10 35 83 130 | 35 34 126 131 | 34 33 127 132 | 33 7 80 133 | 35 126 83 134 | 34 127 126 135 | 33 80 127 136 | 83 126 82 137 | 126 127 128 138 | 127 80 79 139 | 126 128 82 140 | 127 79 128 141 | 82 128 81 142 | 128 79 78 143 | 128 78 81 144 | 81 78 6 145 | 7 95 99 146 | 95 94 129 147 | 94 93 130 148 | 93 1 75 149 | 95 129 99 150 | 94 130 129 151 | 93 75 130 152 | 99 129 100 153 | 129 130 131 154 | 130 75 76 155 | 129 131 100 156 | 130 76 131 157 | 100 131 101 158 | 131 76 77 159 | 131 77 101 160 | 101 77 8 161 | 3 42 12 162 | 42 43 132 163 | 43 44 133 164 | 44 9 17 165 | 42 132 12 166 | 43 133 132 167 | 44 17 133 168 | 12 132 13 169 | 132 133 134 170 | 133 17 16 171 | 132 134 13 172 | 133 16 134 173 | 13 134 14 174 | 134 16 15 175 | 134 15 14 176 | 14 15 4 177 | 3 12 92 178 | 12 13 135 179 | 13 14 136 180 | 14 4 62 181 | 12 135 92 182 | 13 136 135 183 | 14 62 136 184 | 92 135 91 185 | 135 136 137 186 | 136 62 61 187 | 135 137 91 188 | 136 61 137 189 | 91 137 90 190 | 137 61 60 191 | 137 60 90 192 | 90 60 2 193 | 3 92 45 194 | 92 91 138 195 | 91 90 139 196 | 90 2 96 197 | 92 138 45 198 | 91 139 138 199 | 90 96 139 200 | 45 138 46 201 | 138 139 140 202 | 139 96 97 203 | 138 140 46 204 | 139 97 140 205 | 46 140 47 206 | 140 97 98 207 | 140 98 47 208 | 47 98 6 209 | 3 45 84 210 | 45 46 141 211 | 46 47 142 212 | 47 6 36 213 | 45 141 84 214 | 46 142 141 215 | 47 36 142 216 | 84 141 85 217 | 141 142 143 218 | 142 36 37 219 | 141 143 85 220 | 142 37 143 221 | 85 143 86 222 | 143 37 38 223 | 143 38 86 224 | 86 38 8 225 | 3 84 42 226 | 84 85 144 227 | 85 86 145 228 | 86 8 18 229 | 84 144 42 230 | 85 145 144 231 | 86 18 145 232 | 42 144 43 233 | 144 145 146 234 | 145 18 19 235 | 144 146 43 236 | 145 19 146 237 | 43 146 44 238 | 146 19 20 239 | 146 20 44 240 | 44 20 9 241 | 4 15 39 242 | 15 16 147 243 | 16 17 148 244 | 17 9 50 245 | 15 147 39 246 | 16 148 147 247 | 17 50 148 248 | 39 147 40 249 | 147 148 149 250 | 148 50 49 251 | 147 149 40 252 | 148 49 149 253 | 40 149 41 254 | 149 49 48 255 | 149 48 41 256 | 41 48 5 257 | 2 60 24 258 | 60 61 150 259 | 61 62 151 260 | 62 4 51 261 | 60 150 24 262 | 61 151 150 263 | 62 51 151 264 | 24 150 25 265 | 150 151 152 266 | 151 51 52 267 | 150 152 25 268 | 151 52 152 269 | 25 152 26 270 | 152 52 53 271 | 152 53 26 272 | 26 53 11 273 | 6 98 81 274 | 98 97 153 275 | 97 96 154 276 | 96 2 72 277 | 98 153 81 278 | 97 154 153 279 | 96 72 154 280 | 81 153 82 281 | 153 154 155 282 | 154 72 73 283 | 153 155 82 284 | 154 73 155 285 | 82 155 83 286 | 155 73 74 287 | 155 74 83 288 | 83 74 10 289 | 8 38 101 290 | 38 37 156 291 | 37 36 157 292 | 36 6 78 293 | 38 156 101 294 | 37 157 156 295 | 36 78 157 296 | 101 156 100 297 | 156 157 158 298 | 157 78 79 299 | 156 158 100 300 | 157 79 158 301 | 100 158 99 302 | 158 79 80 303 | 158 80 99 304 | 99 80 7 305 | 9 20 29 306 | 20 19 159 307 | 19 18 160 308 | 18 8 77 309 | 20 159 29 310 | 19 160 159 311 | 18 77 160 312 | 29 159 28 313 | 159 160 161 314 | 160 77 76 315 | 159 161 28 316 | 160 76 161 317 | 28 161 27 318 | 161 76 75 319 | 161 75 27 320 | 27 75 1 321 | -------------------------------------------------------------------------------- /examples/sphere/verts.txt: -------------------------------------------------------------------------------- 1 | -0.5257311121191336 0.85065080835204 0 2 | 0.5257311121191336 0.85065080835204 0 3 | -0.5257311121191336 -0.85065080835204 0 4 | 0.5257311121191336 -0.85065080835204 0 5 | 0 -0.5257311121191336 0.85065080835204 6 | 0 0.5257311121191336 0.85065080835204 7 | 0 -0.5257311121191336 -0.85065080835204 8 | 0 0.5257311121191336 -0.85065080835204 9 | 0.85065080835204 0 -0.5257311121191336 10 | 0.85065080835204 0 0.5257311121191336 11 | -0.85065080835204 0 -0.5257311121191336 12 | -0.85065080835204 0 0.5257311121191336 13 | 0.4428627132664893 -0.8641878268373419 0.2388556408050596 14 | 0.3090169943749474 -0.8090169943749475 0.5 15 | 0.1476209044221631 -0.6817183540715489 0.7165669224151787 16 | 0.2388556408050596 -0.4428627132664893 0.8641878268373419 17 | 0.5 -0.3090169943749474 0.8090169943749475 18 | 0.7165669224151787 -0.1476209044221631 0.6817183540715489 19 | 0.9554225632202383 0 -0.2952418088443262 20 | 1 0 0 21 | 0.9554225632202383 0 0.2952418088443262 22 | -0.4428627132664893 0.8641878268373419 0.2388556408050596 23 | -0.3090169943749474 0.8090169943749475 0.5 24 | -0.1476209044221631 0.6817183540715489 0.7165669224151787 25 | -0.6817183540715489 -0.7165669224151787 0.1476209044221631 26 | -0.8090169943749475 -0.5 0.3090169943749474 27 | -0.8641878268373419 -0.2388556408050596 0.4428627132664893 28 | 0.6817183540715489 0.7165669224151787 0.1476209044221631 29 | 0.8090169943749475 0.5 0.3090169943749474 30 | 0.8641878268373419 0.2388556408050596 0.4428627132664893 31 | -0.6817183540715489 0.7165669224151787 0.1476209044221631 32 | -0.8090169943749475 0.5 0.3090169943749474 33 | -0.8641878268373419 0.2388556408050596 0.4428627132664893 34 | -0.2388556408050596 0.4428627132664893 -0.8641878268373419 35 | -0.5 0.3090169943749474 -0.8090169943749475 36 | -0.7165669224151787 0.1476209044221631 -0.6817183540715489 37 | 0.2388556408050596 -0.4428627132664893 -0.8641878268373419 38 | 0.5 -0.3090169943749474 -0.8090169943749475 39 | 0.7165669224151787 -0.1476209044221631 -0.6817183540715489 40 | 0 -0.2952418088443262 0.9554225632202383 41 | 0 0 1 42 | 0 0.2952418088443262 0.9554225632202383 43 | 0.6817183540715489 -0.7165669224151787 0.1476209044221631 44 | 0.8090169943749475 -0.5 0.3090169943749474 45 | 0.8641878268373419 -0.2388556408050596 0.4428627132664893 46 | 0.4428627132664893 -0.8641878268373419 -0.2388556408050596 47 | 0.3090169943749474 -0.8090169943749475 -0.5 48 | 0.1476209044221631 -0.6817183540715489 -0.7165669224151787 49 | 0.2388556408050596 0.4428627132664893 0.8641878268373419 50 | 0.5 0.3090169943749474 0.8090169943749475 51 | 0.7165669224151787 0.1476209044221631 0.6817183540715489 52 | -0.2388556408050596 -0.4428627132664893 0.8641878268373419 53 | -0.5 -0.3090169943749474 0.8090169943749475 54 | -0.7165669224151787 -0.1476209044221631 0.6817183540715489 55 | -0.2952418088443262 0.9554225632202383 0 56 | 0 1 0 57 | 0.2952418088443262 0.9554225632202383 0 58 | -0.4428627132664893 0.8641878268373419 -0.2388556408050596 59 | -0.3090169943749474 0.8090169943749475 -0.5 60 | -0.1476209044221631 0.6817183540715489 -0.7165669224151787 61 | -0.4428627132664893 -0.8641878268373419 0.2388556408050596 62 | -0.3090169943749474 -0.8090169943749475 0.5 63 | -0.1476209044221631 -0.6817183540715489 0.7165669224151787 64 | -0.9554225632202383 0 -0.2952418088443262 65 | -1 0 0 66 | -0.9554225632202383 0 0.2952418088443262 67 | -0.6817183540715489 0.7165669224151787 -0.1476209044221631 68 | -0.8090169943749475 0.5 -0.3090169943749474 69 | -0.8641878268373419 0.2388556408050596 -0.4428627132664893 70 | 0.4428627132664893 0.8641878268373419 0.2388556408050596 71 | 0.3090169943749474 0.8090169943749475 0.5 72 | 0.1476209044221631 0.6817183540715489 0.7165669224151787 73 | -0.6817183540715489 -0.7165669224151787 -0.1476209044221631 74 | -0.8090169943749475 -0.5 -0.3090169943749474 75 | -0.8641878268373419 -0.2388556408050596 -0.4428627132664893 76 | 0.6817183540715489 0.7165669224151787 -0.1476209044221631 77 | 0.8090169943749475 0.5 -0.3090169943749474 78 | 0.8641878268373419 0.2388556408050596 -0.4428627132664893 79 | 0 -0.2952418088443262 -0.9554225632202383 80 | 0 0 -1 81 | 0 0.2952418088443262 -0.9554225632202383 82 | -0.2388556408050596 -0.4428627132664893 -0.8641878268373419 83 | -0.5 -0.3090169943749474 -0.8090169943749475 84 | -0.7165669224151787 -0.1476209044221631 -0.6817183540715489 85 | 0.6817183540715489 -0.7165669224151787 -0.1476209044221631 86 | 0.8090169943749475 -0.5 -0.3090169943749474 87 | 0.8641878268373419 -0.2388556408050596 -0.4428627132664893 88 | -0.2388556408050596 0.4428627132664893 0.8641878268373419 89 | -0.5 0.3090169943749474 0.8090169943749475 90 | -0.7165669224151787 0.1476209044221631 0.6817183540715489 91 | -0.2952418088443262 -0.9554225632202383 0 92 | 0 -1 0 93 | 0.2952418088443262 -0.9554225632202383 0 94 | 0.4428627132664893 0.8641878268373419 -0.2388556408050596 95 | 0.3090169943749474 0.8090169943749475 -0.5 96 | 0.1476209044221631 0.6817183540715489 -0.7165669224151787 97 | -0.4428627132664893 -0.8641878268373419 -0.2388556408050596 98 | -0.3090169943749474 -0.8090169943749475 -0.5 99 | -0.1476209044221631 -0.6817183540715489 -0.7165669224151787 100 | 0.2388556408050596 0.4428627132664893 -0.8641878268373419 101 | 0.5 0.3090169943749474 -0.8090169943749475 102 | 0.7165669224151787 0.1476209044221631 -0.6817183540715489 103 | -0.5877852522924731 0.6881909602355868 0.4253254041760199 104 | -0.6881909602355868 0.4253254041760199 0.5877852522924731 105 | -0.4253254041760199 0.5877852522924731 0.6881909602355868 106 | -0.1624598481164531 0.9510565162951535 0.2628655560595668 107 | 0 0.8506508083520399 0.5257311121191336 108 | 0.1624598481164531 0.9510565162951535 0.2628655560595668 109 | -0.1624598481164531 0.9510565162951535 -0.2628655560595668 110 | 0.1624598481164531 0.9510565162951535 -0.2628655560595668 111 | 0 0.8506508083520399 -0.5257311121191336 112 | -0.5877852522924731 0.6881909602355868 -0.4253254041760199 113 | -0.4253254041760199 0.5877852522924731 -0.6881909602355868 114 | -0.6881909602355868 0.4253254041760199 -0.5877852522924731 115 | -0.8506508083520399 0.5257311121191336 0 116 | -0.9510565162951535 0.2628655560595668 -0.1624598481164531 117 | -0.9510565162951535 0.2628655560595668 0.1624598481164531 118 | 0.5877852522924731 0.6881909602355868 0.4253254041760199 119 | 0.4253254041760199 0.5877852522924731 0.6881909602355868 120 | 0.6881909602355868 0.4253254041760199 0.5877852522924731 121 | -0.2628655560595668 0.1624598481164531 0.9510565162951535 122 | -0.5257311121191336 0 0.8506508083520399 123 | -0.2628655560595668 -0.1624598481164531 0.9510565162951535 124 | -0.9510565162951535 -0.2628655560595668 0.1624598481164531 125 | -0.9510565162951535 -0.2628655560595668 -0.1624598481164531 126 | -0.8506508083520399 -0.5257311121191336 0 127 | -0.5257311121191336 0 -0.8506508083520399 128 | -0.2628655560595668 0.1624598481164531 -0.9510565162951535 129 | -0.2628655560595668 -0.1624598481164531 -0.9510565162951535 130 | 0.4253254041760199 0.5877852522924731 -0.6881909602355868 131 | 0.5877852522924731 0.6881909602355868 -0.4253254041760199 132 | 0.6881909602355868 0.4253254041760199 -0.5877852522924731 133 | 0.5877852522924731 -0.6881909602355868 0.4253254041760199 134 | 0.6881909602355868 -0.4253254041760199 0.5877852522924731 135 | 0.4253254041760199 -0.5877852522924731 0.6881909602355868 136 | 0.1624598481164531 -0.9510565162951535 0.2628655560595668 137 | 0 -0.8506508083520399 0.5257311121191336 138 | -0.1624598481164531 -0.9510565162951535 0.2628655560595668 139 | 0.1624598481164531 -0.9510565162951535 -0.2628655560595668 140 | -0.1624598481164531 -0.9510565162951535 -0.2628655560595668 141 | 0 -0.8506508083520399 -0.5257311121191336 142 | 0.5877852522924731 -0.6881909602355868 -0.4253254041760199 143 | 0.4253254041760199 -0.5877852522924731 -0.6881909602355868 144 | 0.6881909602355868 -0.4253254041760199 -0.5877852522924731 145 | 0.8506508083520399 -0.5257311121191336 0 146 | 0.9510565162951535 -0.2628655560595668 -0.1624598481164531 147 | 0.9510565162951535 -0.2628655560595668 0.1624598481164531 148 | 0.2628655560595668 -0.1624598481164531 0.9510565162951535 149 | 0.5257311121191336 0 0.8506508083520399 150 | 0.2628655560595668 0.1624598481164531 0.9510565162951535 151 | -0.5877852522924731 -0.6881909602355868 0.4253254041760199 152 | -0.4253254041760199 -0.5877852522924731 0.6881909602355868 153 | -0.6881909602355868 -0.4253254041760199 0.5877852522924731 154 | -0.4253254041760199 -0.5877852522924731 -0.6881909602355868 155 | -0.5877852522924731 -0.6881909602355868 -0.4253254041760199 156 | -0.6881909602355868 -0.4253254041760199 -0.5877852522924731 157 | 0.5257311121191336 0 -0.8506508083520399 158 | 0.2628655560595668 -0.1624598481164531 -0.9510565162951535 159 | 0.2628655560595668 0.1624598481164531 -0.9510565162951535 160 | 0.9510565162951535 0.2628655560595668 0.1624598481164531 161 | 0.9510565162951535 0.2628655560595668 -0.1624598481164531 162 | 0.8506508083520399 0.5257311121191336 0 163 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2019 Samuel F. Potter 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /embree.pyx: -------------------------------------------------------------------------------- 1 | # cython: embedsignature=True 2 | # cython: language_level=3 3 | 4 | import errno 5 | import numpy as np 6 | 7 | from enum import Enum 8 | 9 | from libc.stdio cimport printf 10 | from libc.stdlib cimport free 11 | 12 | __version__ = '0.0.3' 13 | 14 | # In this section, we define an aligned memory allocation function, 15 | # "aligned_alloc". This should be used throughout this .pyx file to 16 | # ensure that memory allocated for use by Embree is 16-byte 17 | # aligned. This must be done differently on each major platform. 18 | # 19 | # TODO: update the Windows and Darwin implementations of aligned_alloc 20 | # to ensure that they have the same "exception interface" as the Linux 21 | # version of aligned_alloc. 22 | IF UNAME_SYSNAME == "Windows": 23 | cdef extern from "": 24 | cdef void *_aligned_malloc(size_t size, size_t alignment) 25 | cdef void _aligned_free(void *memblock) 26 | cdef void *aligned_alloc(size_t size, size_t alignment): 27 | return _aligned_malloc(size, alignment) 28 | # memory obtained from _aligned_malloc() 29 | # must be freed with _aligned_free() 30 | # while posix_memalign() just uses regular free() 31 | cdef void aligned_free(void *memblock): 32 | _aligned_free(memblock) 33 | ELIF UNAME_SYSNAME == "Darwin": 34 | # malloc is 16-byte mem aligned by default on Darwin 35 | from libc.stdlib cimport malloc 36 | cdef void *aligned_alloc(size_t size, size_t alignment): 37 | return malloc(size) 38 | cdef void aligned_free(void *memblock): 39 | free(memblock) 40 | ELSE: 41 | from posix.stdlib cimport posix_memalign 42 | cdef void *aligned_alloc(size_t size, size_t alignment): 43 | cdef void *ptr = NULL 44 | cdef int code = posix_memalign(&ptr, alignment, size) 45 | if code == errno.EINVAL: 46 | raise Exception( 47 | 'posix_memalign: bad alignment (size = %, alignment = %)' % ( 48 | size, alignment)) 49 | elif code == errno.ENOMEM: 50 | raise Exception('posix_memalign: insufficient memory to allocate') 51 | elif code != 0: 52 | raise Exception('posix_memalign: unknown error code') 53 | return ptr 54 | cdef void aligned_free(void *memblock): 55 | free(memblock) 56 | 57 | DEF RTC_MAX_INSTANCE_LEVEL_COUNT = 1 58 | 59 | cdef extern from "embree3/rtcore.h": 60 | 61 | cdef struct RTCBufferTy: 62 | pass 63 | ctypedef RTCBufferTy* RTCBuffer 64 | 65 | cdef struct RTCDeviceTy: 66 | pass 67 | ctypedef RTCDeviceTy* RTCDevice 68 | 69 | cdef struct RTCGeometryTy: 70 | pass 71 | ctypedef RTCGeometryTy* RTCGeometry 72 | 73 | cdef struct RTCSceneTy: 74 | pass 75 | ctypedef RTCSceneTy* RTCScene 76 | 77 | cdef enum RTCBufferType: 78 | RTC_BUFFER_TYPE_INDEX = 0 79 | RTC_BUFFER_TYPE_VERTEX = 1 80 | RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE = 2 81 | RTC_BUFFER_TYPE_NORMAL = 3 82 | RTC_BUFFER_TYPE_TANGENT = 4 83 | RTC_BUFFER_TYPE_NORMAL_DERIVATIVE = 5 84 | RTC_BUFFER_TYPE_GRID = 8 85 | RTC_BUFFER_TYPE_FACE = 16 86 | RTC_BUFFER_TYPE_LEVEL = 17 87 | RTC_BUFFER_TYPE_EDGE_CREASE_INDEX = 18 88 | RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT = 19 89 | RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX = 20 90 | RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT = 21 91 | RTC_BUFFER_TYPE_HOLE = 22 92 | RTC_BUFFER_TYPE_FLAGS = 32 93 | 94 | cdef enum RTCError: 95 | RTC_ERROR_NONE = 0 96 | RTC_ERROR_UNKNOWN = 1 97 | RTC_ERROR_INVALID_ARGUMENT = 2 98 | RTC_ERROR_INVALID_OPERATION = 3 99 | RTC_ERROR_OUT_OF_MEMORY = 4 100 | RTC_ERROR_UNSUPPORTED_CPU = 5 101 | RTC_ERROR_CANCELLED = 6 102 | 103 | cdef enum RTCFormat: 104 | RTC_FORMAT_UNDEFINED = 0 105 | RTC_FORMAT_UCHAR = 0x1001 106 | RTC_FORMAT_UCHAR2 = 0x1002 107 | RTC_FORMAT_UCHAR3 = 0x1003 108 | RTC_FORMAT_UCHAR4 = 0x1004 109 | RTC_FORMAT_CHAR = 0x2001 110 | RTC_FORMAT_CHAR2 = 0x2002 111 | RTC_FORMAT_CHAR3 = 0x2003 112 | RTC_FORMAT_CHAR4 = 0x2004 113 | RTC_FORMAT_USHORT = 0x3001 114 | RTC_FORMAT_USHORT2 = 0x3002 115 | RTC_FORMAT_USHORT3 = 0x3003 116 | RTC_FORMAT_USHORT4 = 0x3004 117 | RTC_FORMAT_SHORT = 0x4001 118 | RTC_FORMAT_SHORT2 = 0x4002 119 | RTC_FORMAT_SHORT3 = 0x4003 120 | RTC_FORMAT_SHORT4 = 0x4004 121 | RTC_FORMAT_UINT = 0x5001 122 | RTC_FORMAT_UINT2 = 0x5002 123 | RTC_FORMAT_UINT3 = 0x5003 124 | RTC_FORMAT_UINT4 = 0x5004 125 | RTC_FORMAT_INT = 0x6001 126 | RTC_FORMAT_INT2 = 0x6002 127 | RTC_FORMAT_INT3 = 0x6003 128 | RTC_FORMAT_INT4 = 0x6004 129 | RTC_FORMAT_ULLONG = 0x7001 130 | RTC_FORMAT_ULLONG2 = 0x7002 131 | RTC_FORMAT_ULLONG3 = 0x7003 132 | RTC_FORMAT_ULLONG4 = 0x7004 133 | RTC_FORMAT_LLONG = 0x8001 134 | RTC_FORMAT_LLONG2 = 0x8002 135 | RTC_FORMAT_LLONG3 = 0x8003 136 | RTC_FORMAT_LLONG4 = 0x8004 137 | RTC_FORMAT_FLOAT = 0x9001 138 | RTC_FORMAT_FLOAT2 = 0x9002 139 | RTC_FORMAT_FLOAT3 = 0x9003 140 | RTC_FORMAT_FLOAT4 = 0x9004 141 | RTC_FORMAT_FLOAT5 = 0x9005 142 | RTC_FORMAT_FLOAT6 = 0x9006 143 | RTC_FORMAT_FLOAT7 = 0x9007 144 | RTC_FORMAT_FLOAT8 = 0x9008 145 | RTC_FORMAT_FLOAT9 = 0x9009 146 | RTC_FORMAT_FLOAT10 = 0x9010 147 | RTC_FORMAT_FLOAT11 = 0x9011 148 | RTC_FORMAT_FLOAT12 = 0x9012 149 | RTC_FORMAT_FLOAT13 = 0x9013 150 | RTC_FORMAT_FLOAT14 = 0x9014 151 | RTC_FORMAT_FLOAT15 = 0x9015 152 | RTC_FORMAT_FLOAT16 = 0x9016 153 | RTC_FORMAT_FLOAT2X2_ROW_MAJOR = 0x9122 154 | RTC_FORMAT_FLOAT2X3_ROW_MAJOR = 0x9123 155 | RTC_FORMAT_FLOAT2X4_ROW_MAJOR = 0x9124 156 | RTC_FORMAT_FLOAT3X2_ROW_MAJOR = 0x9132 157 | RTC_FORMAT_FLOAT3X3_ROW_MAJOR = 0x9133 158 | RTC_FORMAT_FLOAT3X4_ROW_MAJOR = 0x9134 159 | RTC_FORMAT_FLOAT4X2_ROW_MAJOR = 0x9142 160 | RTC_FORMAT_FLOAT4X3_ROW_MAJOR = 0x9143 161 | RTC_FORMAT_FLOAT4X4_ROW_MAJOR = 0x9144 162 | RTC_FORMAT_FLOAT2X2_COLUMN_MAJOR = 0x9222 163 | RTC_FORMAT_FLOAT2X3_COLUMN_MAJOR = 0x9223 164 | RTC_FORMAT_FLOAT2X4_COLUMN_MAJOR = 0x9224 165 | RTC_FORMAT_FLOAT3X2_COLUMN_MAJOR = 0x9232 166 | RTC_FORMAT_FLOAT3X3_COLUMN_MAJOR = 0x9233 167 | RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR = 0x9234 168 | RTC_FORMAT_FLOAT4X2_COLUMN_MAJOR = 0x9242 169 | RTC_FORMAT_FLOAT4X3_COLUMN_MAJOR = 0x9243 170 | RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR = 0x9244 171 | RTC_FORMAT_GRID = 0xA00 172 | 173 | cdef enum RTCGeometryType: 174 | RTC_GEOMETRY_TYPE_TRIANGLE = 0 175 | RTC_GEOMETRY_TYPE_QUAD = 1 176 | RTC_GEOMETRY_TYPE_GRID = 2 177 | RTC_GEOMETRY_TYPE_SUBDIVISION = 8 178 | RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE = 17 179 | RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE = 24 180 | RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE = 25 181 | RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE = 26 182 | RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE = 32 183 | RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE = 33 184 | RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE = 34 185 | RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE = 40 186 | RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE = 41 187 | RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE = 42 188 | RTC_GEOMETRY_TYPE_SPHERE_POINT = 50 189 | RTC_GEOMETRY_TYPE_DISC_POINT = 51 190 | RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT = 52 191 | RTC_GEOMETRY_TYPE_USER = 120 192 | RTC_GEOMETRY_TYPE_INSTANCE = 121 193 | 194 | cdef enum RTCBuildQuality: 195 | RTC_BUILD_QUALITY_LOW = 0, 196 | RTC_BUILD_QUALITY_MEDIUM = 1, 197 | RTC_BUILD_QUALITY_HIGH = 2, 198 | RTC_BUILD_QUALITY_REFIT = 3 199 | 200 | cdef enum RTCSceneFlags: 201 | RTC_SCENE_FLAG_NONE = 0, 202 | RTC_SCENE_FLAG_DYNAMIC = (1 << 0) 203 | RTC_SCENE_FLAG_COMPACT = (1 << 1) 204 | RTC_SCENE_FLAG_ROBUST = (1 << 2) 205 | RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION = (1 << 3) 206 | 207 | cdef enum RTCIntersectContextFlags: 208 | RTC_INTERSECT_CONTEXT_FLAG_NONE = 0, 209 | RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT = (0 << 0) 210 | RTC_INTERSECT_CONTEXT_FLAG_COHERENT = (1 << 0) 211 | 212 | cdef struct RTCRay: 213 | float org_x 214 | float org_y 215 | float org_z 216 | float tnear 217 | float dir_x 218 | float dir_y 219 | float dir_z 220 | float time 221 | float tfar 222 | unsigned mask 223 | unsigned id 224 | unsigned flags 225 | 226 | cdef struct RTCHit: 227 | float Ng_x 228 | float Ng_y 229 | float Ng_z 230 | float u 231 | float v 232 | unsigned primID 233 | unsigned geomID 234 | unsigned instID[RTC_MAX_INSTANCE_LEVEL_COUNT] 235 | 236 | cdef struct RTCRayHit: 237 | RTCRay ray 238 | RTCHit hit 239 | 240 | cdef struct RTCRayNp: 241 | float *org_x 242 | float *org_y 243 | float *org_z 244 | float *tnear 245 | float *dir_x 246 | float *dir_y 247 | float *dir_z 248 | float *time 249 | float *tfar 250 | unsigned int *mask 251 | unsigned int *id 252 | unsigned int *flags 253 | 254 | cdef struct RTCHitNp: 255 | float *Ng_x 256 | float *Ng_y 257 | float *Ng_z 258 | float *u 259 | float *v 260 | unsigned int *primID 261 | unsigned int *geomID 262 | unsigned int *instID[RTC_MAX_INSTANCE_LEVEL_COUNT] 263 | 264 | cdef struct RTCRayHitNp: 265 | RTCRayNp ray 266 | RTCHitNp hit 267 | 268 | cdef struct RTCRayN: 269 | pass 270 | 271 | cdef struct RTCHitN: 272 | pass 273 | 274 | cdef struct RTCFilterFunctionNArguments: 275 | int* valid 276 | void* geometryUserPtr 277 | const RTCIntersectContext* context 278 | RTCRayN* ray 279 | RTCHitN* hit 280 | unsigned int N 281 | 282 | ctypedef void(*RTCFilterFunctionN)(const RTCFilterFunctionNArguments*) 283 | 284 | cdef struct RTCIntersectContext: 285 | RTCIntersectContextFlags flags 286 | RTCFilterFunctionN filter 287 | unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT] 288 | 289 | RTCBuffer rtcNewBuffer(RTCDevice, size_t) 290 | RTCBuffer rtcNewSharedBuffer(RTCDevice, void*, size_t) 291 | void* rtcGetBufferData(RTCBuffer) 292 | void rtcRetainBuffer(RTCBuffer) 293 | void rtcReleaseBuffer(RTCBuffer) 294 | 295 | RTCDevice rtcNewDevice(const char*) 296 | void rtcRetainDevice(RTCDevice) 297 | void rtcReleaseDevice(RTCDevice) 298 | RTCError rtcGetDeviceError(RTCDevice) 299 | 300 | ctypedef void (*RTCErrorFunction)(void*, RTCError, const char*) 301 | void rtcSetDeviceErrorFunction(RTCDevice, RTCErrorFunction, void*) 302 | 303 | RTCGeometry rtcNewGeometry(RTCDevice, RTCGeometryType) 304 | void rtcRetainGeometry(RTCGeometry) 305 | void rtcReleaseGeometry(RTCGeometry) 306 | void rtcCommitGeometry(RTCGeometry) 307 | void rtcUpdateGeometryBuffer(RTCGeometry, RTCBufferType, unsigned) 308 | void rtcSetGeometryBuildQuality(RTCGeometry, RTCBuildQuality) 309 | void rtcSetGeometryBuffer(RTCGeometry, RTCBufferType, unsigned, 310 | RTCFormat, RTCBuffer, size_t, size_t, size_t) 311 | void rtcSetSharedGeometryBuffer(RTCGeometry, RTCBufferType, unsigned, 312 | RTCFormat, void*, size_t, size_t, size_t) 313 | void* rtcSetNewGeometryBuffer(RTCGeometry, RTCBufferType, unsigned, 314 | RTCFormat, size_t, size_t) 315 | void* rtcGetGeometryBufferData(RTCGeometry, RTCBufferType, unsigned) 316 | 317 | void rtcInitIntersectContext(RTCIntersectContext*) 318 | 319 | RTCScene rtcNewScene(RTCDevice) 320 | void rtcRetainScene(RTCScene) 321 | void rtcReleaseScene(RTCScene) 322 | unsigned rtcAttachGeometry(RTCScene, RTCGeometry) 323 | void rtcDetachGeometry(RTCScene, unsigned) 324 | void rtcCommitScene(RTCScene) 325 | void rtcSetSceneBuildQuality(RTCScene, RTCBuildQuality) 326 | void rtcSetSceneFlags(RTCScene, RTCSceneFlags) 327 | 328 | void rtcIntersect1(RTCScene, RTCIntersectContext*, RTCRayHit*) 329 | void rtcIntersect1M(RTCScene, RTCIntersectContext*, RTCRayHit*, 330 | unsigned, size_t) 331 | void rtcOccluded1(RTCScene, RTCIntersectContext*, RTCRay*) 332 | void rtcOccluded1M(RTCScene, RTCIntersectContext*, RTCRay*, unsigned, 333 | size_t) 334 | 335 | void rtcIntersectNp(RTCScene, RTCIntersectContext*, RTCRayHitNp*, unsigned) 336 | 337 | 338 | INVALID_GEOMETRY_ID = -1 339 | 340 | class BufferType(Enum): 341 | Index = 0 342 | Vertex = 1 343 | VertexAttribute = 2 344 | Normal = 3 345 | Tangent = 4 346 | NormalDerivative = 5 347 | Grid = 8 348 | Face = 16 349 | Level = 17 350 | EdgeCreaseIndex = 18 351 | EdgeCreaseWeight = 19 352 | VertexCreaseIndex = 20 353 | VertexCreaseWeight = 21 354 | Hole = 22 355 | Flags = 32 356 | 357 | class Error(Enum): 358 | Success = 0 359 | Unknown = 1 360 | InvalidArgument = 2 361 | InvalidOperation = 3 362 | OutOfMemory = 4 363 | UnsupportedCpu = 5 364 | Cancelled = 6 365 | 366 | class Format(Enum): 367 | Undefined = 0 368 | Uchar = 0x1001 369 | Uchar2 = 0x1002 370 | Uchar3 = 0x1003 371 | Uchar4 = 0x1004 372 | Char = 0x2001 373 | Char2 = 0x2002 374 | Char3 = 0x2003 375 | Char4 = 0x2004 376 | Ushort = 0x3001 377 | Ushort2 = 0x3002 378 | Ushort3 = 0x3003 379 | Ushort4 = 0x3004 380 | Short = 0x4001 381 | Short2 = 0x4002 382 | Short3 = 0x4003 383 | Short4 = 0x4004 384 | Uint = 0x5001 385 | Uint2 = 0x5002 386 | Uint3 = 0x5003 387 | Uint4 = 0x5004 388 | Int = 0x6001 389 | Int2 = 0x6002 390 | Int3 = 0x6003 391 | Int4 = 0x6004 392 | Ullong = 0x7001 393 | Ullong2 = 0x7002 394 | Ullong3 = 0x7003 395 | Ullong4 = 0x7004 396 | Llong = 0x8001 397 | Llong2 = 0x8002 398 | Llong3 = 0x8003 399 | Llong4 = 0x8004 400 | Float = 0x9001 401 | Float2 = 0x9002 402 | Float3 = 0x9003 403 | Float4 = 0x9004 404 | Float5 = 0x9005 405 | Float6 = 0x9006 406 | Float7 = 0x9007 407 | Float8 = 0x9008 408 | Float9 = 0x9009 409 | Float10 = 0x9010 410 | Float11 = 0x9011 411 | Float12 = 0x9012 412 | Float13 = 0x9013 413 | Float14 = 0x9014 414 | Float15 = 0x9015 415 | Float16 = 0x9016 416 | Float2x2RowMajor = 0x9122 417 | Float2x3RowMajor = 0x9123 418 | Float2x4RowMajor = 0x9124 419 | Float3x2RowMajor = 0x9132 420 | Float3x3RowMajor = 0x9133 421 | Float3x4RowMajor = 0x9134 422 | Float4x2RowMajor = 0x9142 423 | Float4x3RowMajor = 0x9143 424 | Float4x4RowMajor = 0x9144 425 | Float2x2ColumnMajor = 0x9222 426 | Float2x3ColumnMajor = 0x9223 427 | Float2x4ColumnMajor = 0x9224 428 | Float3x2ColumnMajor = 0x9232 429 | Float3x3ColumnMajor = 0x9233 430 | Float3x4ColumnMajor = 0x9234 431 | Float4x2ColumnMajor = 0x9242 432 | Float4x3ColumnMajor = 0x9243 433 | Float4x4ColumnMajor = 0x9244 434 | Grid = 0xA00 435 | 436 | def as_dtype(self): 437 | return { 438 | Format.Uint3: np.uint32, 439 | Format.Uint4: np.uint32, 440 | Format.Int: np.int32, 441 | Format.Float: np.single, 442 | Format.Float3: np.single, 443 | Format.Float4: np.single 444 | }[self] 445 | 446 | @property 447 | def dtype(self): 448 | return self.as_dtype() 449 | 450 | def get_nelts(self): 451 | return { 452 | Format.Uint3: 3, 453 | Format.Uint4: 4, 454 | Format.Float3: 3, 455 | Format.Float4: 4 456 | }[self] 457 | 458 | @property 459 | def nelts(self): 460 | return self.get_nelts() 461 | 462 | class GeometryType(Enum): 463 | Triangle = 0 464 | Quad = 1 465 | Grid = 2 466 | Subdivision = 8 467 | FlatLinearCurve = 17 468 | RoundBezierCurve = 24 469 | FlatBezierCurve = 25 470 | NormalOrientedBezierCurve = 26 471 | RoundBsplineCurve = 32 472 | FlatBsplineCurve = 33 473 | NormalOrientedBsplineCurve = 34 474 | RoundHermiteCurve = 40 475 | FlatHermiteCurve = 41 476 | NormalOrientedHermiteCurve = 42 477 | SpherePoint = 50 478 | DiscPoint = 51 479 | OrientedDiscPoint = 52 480 | User = 120 481 | Instance = 121 482 | 483 | class BuildQuality(Enum): 484 | Low = 0 485 | Medium = 1 486 | High = 2 487 | Refit = 3 488 | 489 | class SceneFlags(Enum): 490 | None_ = 0 491 | Dynamic = (1 << 0) 492 | Compact = (1 << 1) 493 | Robust = (1 << 2) 494 | ContextFilterFunction = (1 << 3) 495 | 496 | class IntersectContextFlags(Enum): 497 | NONE = 0, 498 | INCOHERENT = (0 << 0) 499 | COHERENT = (1 << 0) 500 | 501 | cdef typed_mv_from_ptr(void* ptr, fmt, size_t item_count): 502 | cdef float[:] float_mv 503 | cdef unsigned[:] uint_mv 504 | cdef int[:] int_mv 505 | if fmt in {Format.Uint3, Format.Uint4}: 506 | uint_mv = ptr 507 | return uint_mv 508 | elif fmt in {Format.Int}: 509 | int_mv = ptr 510 | return int_mv 511 | elif fmt in {Format.Float, Format.Float3, Format.Float4}: 512 | float_mv = ptr 513 | return float_mv 514 | 515 | cdef array_from_ptr(void* ptr, fmt, item_count): 516 | mv = typed_mv_from_ptr(ptr, fmt, item_count) 517 | arr = np.asarray(mv, dtype=fmt.dtype) 518 | if fmt.nelts > 1: 519 | arr = arr.reshape(item_count, fmt.nelts) 520 | return arr 521 | 522 | cdef class Buffer: 523 | cdef: 524 | RTCBuffer _buffer 525 | Device device 526 | 527 | def __cinit__(self, Device device, size_t byte_size): 528 | self._buffer = rtcNewBuffer(device._device, byte_size) 529 | 530 | def retain(self): 531 | rtcRetainBuffer(self._buffer) 532 | 533 | def release(self): 534 | rtcReleaseBuffer(self._buffer) 535 | 536 | cdef void simple_error_function(void* userPtr, RTCError code, const char* str) noexcept: 537 | print('%s: %s' % (Error(code), str)) 538 | 539 | cdef class Device: 540 | cdef: 541 | RTCDevice _device 542 | 543 | def __cinit__(self): 544 | self._device = rtcNewDevice(NULL) 545 | 546 | # TODO: hardcode an error function until we decide on a nice 547 | # way of exposing error functions to the library user 548 | rtcSetDeviceErrorFunction(self._device, simple_error_function, NULL); 549 | 550 | def retain(self): 551 | rtcRetainDevice(self._device) 552 | 553 | def release(self): 554 | rtcReleaseDevice(self._device) 555 | 556 | def get_error(self): 557 | return Error(rtcGetDeviceError(self._device)) 558 | 559 | def make_buffer(self, byte_size): 560 | return Buffer(self, byte_size) 561 | 562 | def make_geometry(self, geometry_type): 563 | return Geometry(self, geometry_type) 564 | 565 | def make_scene(self): 566 | return Scene(self) 567 | 568 | cdef class Geometry: 569 | cdef: 570 | RTCGeometry _geometry 571 | Device device 572 | 573 | def __cinit__(self, Device device, geometry_type): 574 | self._geometry = rtcNewGeometry(device._device, geometry_type.value) 575 | self.device = device 576 | 577 | def retain(self): 578 | rtcRetainGeometry(self._geometry) 579 | 580 | def release(self): 581 | rtcReleaseGeometry(self._geometry) 582 | 583 | def set_build_quality(self, build_quality): 584 | rtcSetGeometryBuildQuality(self._geometry, build_quality.value) 585 | 586 | def commit(self): 587 | rtcCommitGeometry(self._geometry) 588 | 589 | def set_new_buffer(self, buf_type, unsigned slot, fmt, 590 | size_t byte_stride, size_t item_count): 591 | if byte_stride % 4 != 0: 592 | raise Exception('byte_stride must be aligned to 4 bytes') 593 | cdef void* ptr = rtcSetNewGeometryBuffer( 594 | self._geometry, buf_type.value, slot, fmt.value, byte_stride, 595 | item_count) 596 | return array_from_ptr(ptr, fmt, item_count) 597 | 598 | def get_buffer(self, buf_type, unsigned slot, fmt, size_t item_count): 599 | cdef void* ptr = rtcGetGeometryBufferData( 600 | self._geometry, buf_type.value, slot) 601 | return array_from_ptr(ptr, fmt, item_count) 602 | 603 | def update_buffer(self, buf_type, unsigned slot): 604 | rtcUpdateGeometryBuffer(self._geometry, buf_type.value, slot) 605 | 606 | 607 | cdef class Ray: 608 | cdef: 609 | RTCRay _ray 610 | 611 | @property 612 | def org(self): 613 | return np.asarray( &self._ray.org_x) 614 | 615 | @org.setter 616 | def org(self, org): 617 | self._ray.org_x = org[0] 618 | self._ray.org_y = org[1] 619 | self._ray.org_z = org[2] 620 | 621 | @property 622 | def tnear(self): 623 | return self._ray.tnear 624 | 625 | @tnear.setter 626 | def tnear(self, float tnear): 627 | self._ray.tnear = tnear 628 | 629 | @property 630 | def dir(self): 631 | return np.asarray( &self._ray.dir_x) 632 | 633 | @dir.setter 634 | def dir(self, dir): 635 | self._ray.dir_x = dir[0] 636 | self._ray.dir_y = dir[1] 637 | self._ray.dir_z = dir[2] 638 | 639 | @property 640 | def time(self): 641 | return self._ray.time 642 | 643 | @time.setter 644 | def time(self, float time): 645 | self._ray.time = time 646 | 647 | @property 648 | def tfar(self): 649 | return self._ray.tfar 650 | 651 | @tfar.setter 652 | def tfar(self, float tfar): 653 | self._ray.tfar = tfar 654 | 655 | @property 656 | def mask(self): 657 | return self._ray.mask 658 | 659 | @mask.setter 660 | def mask(self, unsigned mask): 661 | self._ray.mask = mask 662 | 663 | @property 664 | def id(self): 665 | return self._ray.id 666 | 667 | @id.setter 668 | def id(self, unsigned id): 669 | self._ray.id = id 670 | 671 | @property 672 | def flags(self): 673 | return self._ray.flags 674 | 675 | @flags.setter 676 | def flags(self, unsigned flags): 677 | self._ray.flags = flags 678 | 679 | def __repr__(self): 680 | return 'Ray(dir = %s, org = %s, tfar = %s, tnear = %s)' % ( 681 | self.dir, self.org, self.tfar, self.tnear 682 | ) 683 | 684 | cdef class Hit: 685 | cdef: 686 | RTCHit _hit 687 | 688 | def __cinit__(self): 689 | self._hit.primID = INVALID_GEOMETRY_ID 690 | self._hit.geomID = INVALID_GEOMETRY_ID 691 | 692 | @property 693 | def normal(self): 694 | return (self._hit.Ng_x, self._hit.Ng_y, self._hit.Ng_z) 695 | 696 | @property 697 | def uv(self): 698 | return (self._hit.u, self._hit.v) 699 | 700 | @property 701 | def prim_id(self): 702 | return self._hit.primID 703 | 704 | @property 705 | def geom_id(self): 706 | return self._hit.geomID 707 | 708 | @property 709 | def inst_id(self): 710 | return self._hit.instID[0] 711 | 712 | def __repr__(self): 713 | return 'Hit(geom_id = %d, inst_id = %d, normal = %s, prim_id = %d, uv = %s)' % ( 714 | self.geom_id, self.inst_id, self.normal, self.prim_id, self.uv 715 | ) 716 | 717 | cdef class RayHit: 718 | cdef: 719 | RTCRayHit _rayhit 720 | 721 | @property 722 | def org(self): 723 | return np.asarray( &self._rayhit.ray.org_x) 724 | 725 | @org.setter 726 | def org(self, org): 727 | self._rayhit.ray.org_x = org[0] 728 | self._rayhit.ray.org_y = org[1] 729 | self._rayhit.ray.org_z = org[2] 730 | 731 | @property 732 | def dir(self): 733 | return np.asarray( &self._rayhit.ray.dir_x) 734 | 735 | @dir.setter 736 | def dir(self, dir): 737 | self._rayhit.ray.dir_x = dir[0] 738 | self._rayhit.ray.dir_y = dir[1] 739 | self._rayhit.ray.dir_z = dir[2] 740 | 741 | @property 742 | def tnear(self): 743 | return self._rayhit.ray.tnear 744 | 745 | @tnear.setter 746 | def tnear(self, tnear): 747 | self._rayhit.ray.tnear = tnear 748 | 749 | @property 750 | def tfar(self): 751 | return self._rayhit.ray.tfar 752 | 753 | @tfar.setter 754 | def tfar(self, tfar): 755 | self._rayhit.ray.tfar = tfar 756 | 757 | @property 758 | def normal(self): 759 | return np.asarray( &self._rayhit.hit.Ng_x) 760 | 761 | @property 762 | def uv(self): 763 | return np.asarray( &self._rayhit.hit.u) 764 | 765 | @property 766 | def prim_id(self): 767 | return self._rayhit.hit.primID 768 | 769 | @prim_id.setter 770 | def prim_id(self, prim_id): 771 | self._rayhit.hit.primID = prim_id 772 | 773 | @property 774 | def geom_id(self): 775 | return self._rayhit.hit.geomID 776 | 777 | @geom_id.setter 778 | def geom_id(self, geom_id): 779 | self._rayhit.hit.geomID = geom_id 780 | 781 | @property 782 | def inst_id(self): 783 | return np.asarray( 784 | self._rayhit.hit.instID) 785 | 786 | def __repr__(self): 787 | return ( 788 | 'RayHit(dir = %s, org = %s, tfar = %s, tnear = %s, ' + \ 789 | 'geom_id = %d, inst_id = %d, normal = %s, prim_id = %d, uv = %s)' 790 | ) % ( 791 | self.dir, self.org, self.tfar, self.tnear, 792 | self.geom_id, self.inst_id, self.normal, self.prim_id, self.uv 793 | ) 794 | 795 | cdef class Ray1M: 796 | cdef: 797 | RTCRay *_ray 798 | unsigned _M 799 | 800 | def __cinit__(self, unsigned M): 801 | cdef size_t size = M*sizeof(RTCRay) 802 | self._ray = aligned_alloc(size, 0x10) 803 | if self._ray == NULL: 804 | raise Exception('failed to allocate %d bytes' % (size,)) 805 | self._M = M 806 | 807 | def __dealloc__(self): 808 | aligned_free(self._ray) 809 | 810 | @property 811 | def size(self): 812 | return self._M 813 | 814 | def toarray(self): 815 | return np.asarray( self._ray) 816 | 817 | @property 818 | def org(self): 819 | cdef float[:, :] mv = &self._ray[0].org_x 820 | mv.strides[0] = sizeof(RTCRay) 821 | return np.asarray(mv) 822 | 823 | @property 824 | def tnear(self): 825 | cdef float[:] mv = &self._ray[0].tnear 826 | mv.strides[0] = sizeof(RTCRay) 827 | return np.asarray(mv) 828 | 829 | @property 830 | def dir(self): 831 | cdef float[:, :] mv = &self._ray[0].dir_x 832 | mv.strides[0] = sizeof(RTCRay) 833 | return np.asarray(mv) 834 | 835 | @property 836 | def time(self): 837 | cdef float[:] mv = &self._ray[0].time 838 | mv.strides[0] = sizeof(RTCRay) 839 | return np.asarray(mv) 840 | 841 | @property 842 | def tfar(self): 843 | cdef float[:] mv = &self._ray[0].tfar 844 | mv.strides[0] = sizeof(RTCRay) 845 | return np.asarray(mv) 846 | 847 | @property 848 | def mask(self): 849 | cdef unsigned[:] mv = &self._ray[0].mask 850 | mv.strides[0] = sizeof(RTCRay) 851 | return np.asarray(mv) 852 | 853 | @property 854 | def id(self): 855 | cdef unsigned[:] mv = &self._ray[0].id 856 | mv.strides[0] = sizeof(RTCRay) 857 | return np.asarray(mv) 858 | 859 | @property 860 | def flags(self): 861 | cdef unsigned[:] mv = &self._ray[0].flags 862 | mv.strides[0] = sizeof(RTCRay) 863 | return np.asarray(mv) 864 | 865 | cdef class RayHit1M: 866 | cdef: 867 | RTCRayHit *_rayhit 868 | unsigned _M 869 | 870 | def __cinit__(self, unsigned M): 871 | cdef size_t size = M*sizeof(RTCRayHit) 872 | self._rayhit = aligned_alloc(size, 0x10) 873 | if self._rayhit == NULL: 874 | raise Exception('failed to allocate %d bytes' % (size,)) 875 | self._M = M 876 | 877 | def __dealloc__(self): 878 | aligned_free(self._rayhit) 879 | 880 | @property 881 | def size(self): 882 | return self._M 883 | 884 | def toarray(self): 885 | return np.asarray( self._rayhit) 886 | 887 | @property 888 | def org(self): 889 | cdef float[:, :] mv = &self._rayhit[0].ray.org_x 890 | mv.strides[0] = sizeof(RTCRayHit) 891 | return np.asarray(mv) 892 | 893 | @property 894 | def tnear(self): 895 | cdef float[:] mv = &self._rayhit[0].ray.tnear 896 | mv.strides[0] = sizeof(RTCRayHit) 897 | return np.asarray(mv) 898 | 899 | @property 900 | def dir(self): 901 | cdef float[:, :] mv = &self._rayhit[0].ray.dir_x 902 | mv.strides[0] = sizeof(RTCRayHit) 903 | return np.asarray(mv) 904 | 905 | @property 906 | def time(self): 907 | cdef float[:] mv = &self._rayhit[0].ray.time 908 | mv.strides[0] = sizeof(RTCRayHit) 909 | return np.asarray(mv) 910 | 911 | @property 912 | def tfar(self): 913 | cdef float[:] mv = &self._rayhit[0].ray.tfar 914 | mv.strides[0] = sizeof(RTCRayHit) 915 | return np.asarray(mv) 916 | 917 | @property 918 | def mask(self): 919 | cdef unsigned[:] mv = &self._rayhit[0].ray.mask 920 | mv.strides[0] = sizeof(RTCRayHit) 921 | return np.asarray(mv) 922 | 923 | @property 924 | def id(self): 925 | cdef unsigned[:] mv = &self._rayhit[0].ray.id 926 | mv.strides[0] = sizeof(RTCRayHit) 927 | return np.asarray(mv) 928 | 929 | @property 930 | def flags(self): 931 | cdef unsigned[:] mv = &self._rayhit[0].ray.flags 932 | mv.strides[0] = sizeof(RTCRayHit) 933 | return np.asarray(mv) 934 | 935 | @property 936 | def normal(self): 937 | cdef float[:, :] mv = &self._rayhit[0].hit.Ng_x 938 | mv.strides[0] = sizeof(RTCRayHit) 939 | return np.asarray(mv) 940 | 941 | @property 942 | def uv(self): 943 | cdef float[:, :] mv = &self._rayhit[0].hit.u 944 | mv.strides[0] = sizeof(RTCRayHit) 945 | return np.asarray(mv) 946 | 947 | @property 948 | def prim_id(self): 949 | cdef unsigned[:] mv = &self._rayhit[0].hit.primID 950 | mv.strides[0] = sizeof(RTCRayHit) 951 | return np.asarray(mv) 952 | 953 | @property 954 | def geom_id(self): 955 | cdef unsigned[:] mv = &self._rayhit[0].hit.geomID 956 | mv.strides[0] = sizeof(RTCRayHit) 957 | return np.asarray(mv) 958 | 959 | @property 960 | def inst_id(self): 961 | cdef unsigned[:, :] mv = \ 962 | \ 963 | &self._rayhit[0].hit.instID[0] 964 | mv.strides[0] = sizeof(RTCRayHit) 965 | return np.asarray(mv) 966 | 967 | cdef class RayHitNp: 968 | cdef: 969 | RTCRayHitNp _rayhit 970 | unsigned N 971 | 972 | def __cinit__(self, unsigned N): 973 | cdef RTCRayNp *ray = &self._rayhit.ray 974 | ray.org_x = aligned_alloc(N*sizeof(float), 0x10) 975 | ray.org_y = aligned_alloc(N*sizeof(float), 0x10) 976 | ray.org_z = aligned_alloc(N*sizeof(float), 0x10) 977 | ray.tnear = aligned_alloc(N*sizeof(float), 0x10) 978 | ray.dir_x = aligned_alloc(N*sizeof(float), 0x10) 979 | ray.dir_y = aligned_alloc(N*sizeof(float), 0x10) 980 | ray.dir_z = aligned_alloc(N*sizeof(float), 0x10) 981 | ray.time = aligned_alloc(N*sizeof(float), 0x10) 982 | ray.tfar = aligned_alloc(N*sizeof(float), 0x10) 983 | ray.mask = aligned_alloc(N*sizeof(unsigned), 0x10) 984 | ray.id = aligned_alloc(N*sizeof(unsigned), 0x10) 985 | ray.flags = aligned_alloc(N*sizeof(unsigned), 0x10) 986 | 987 | cdef RTCHitNp *hit = &self._rayhit.hit 988 | hit.Ng_x = aligned_alloc(N*sizeof(float), 0x10) 989 | hit.Ng_y = aligned_alloc(N*sizeof(float), 0x10) 990 | hit.Ng_z = aligned_alloc(N*sizeof(float), 0x10) 991 | hit.u = aligned_alloc(N*sizeof(float), 0x10) 992 | hit.v = aligned_alloc(N*sizeof(float), 0x10) 993 | hit.primID = aligned_alloc(N*sizeof(unsigned), 0x10) 994 | hit.geomID = aligned_alloc(N*sizeof(unsigned), 0x10) 995 | for i in range(RTC_MAX_INSTANCE_LEVEL_COUNT): 996 | hit.instID[i] = aligned_alloc(N*sizeof(unsigned), 0x10) 997 | 998 | def __dealloc__(self): 999 | aligned_free(self._rayhit.ray.org_x) 1000 | aligned_free(self._rayhit.ray.org_y) 1001 | aligned_free(self._rayhit.ray.org_z) 1002 | aligned_free(self._rayhit.ray.tnear) 1003 | aligned_free(self._rayhit.ray.dir_x) 1004 | aligned_free(self._rayhit.ray.dir_y) 1005 | aligned_free(self._rayhit.ray.dir_z) 1006 | aligned_free(self._rayhit.ray.time) 1007 | aligned_free(self._rayhit.ray.tfar) 1008 | aligned_free(self._rayhit.ray.mask) 1009 | aligned_free(self._rayhit.ray.id) 1010 | aligned_free(self._rayhit.ray.flags) 1011 | aligned_free(self._rayhit.hit.Ng_x) 1012 | aligned_free(self._rayhit.hit.Ng_y) 1013 | aligned_free(self._rayhit.hit.Ng_z) 1014 | aligned_free(self._rayhit.hit.u) 1015 | aligned_free(self._rayhit.hit.v) 1016 | aligned_free(self._rayhit.hit.primID) 1017 | aligned_free(self._rayhit.hit.geomID) 1018 | for i in range(RTC_MAX_INSTANCE_LEVEL_COUNT): 1019 | aligned_free(self._rayhit.hit.instID[i]) 1020 | 1021 | @property 1022 | def size(self): 1023 | return self._N 1024 | 1025 | @property 1026 | def org_x(self): 1027 | return np.asarray(self._rayhit.ray.org_x) 1028 | 1029 | @property 1030 | def org_y(self): 1031 | np.asarray(self._rayhit.ray.org_y) 1032 | 1033 | @property 1034 | def org_z(self): 1035 | np.asarray(self._rayhit.ray.org_z) 1036 | 1037 | @property 1038 | def tnear(self): 1039 | np.asarray(self._rayhit.ray.tnear) 1040 | 1041 | @property 1042 | def dir_x(self): 1043 | np.asarray(self._rayhit.ray.dir_x) 1044 | 1045 | @property 1046 | def dir_y(self): 1047 | np.asarray(self._rayhit.ray.dir_y) 1048 | 1049 | @property 1050 | def dir_z(self): 1051 | np.asarray(self._rayhit.ray.dir_z) 1052 | 1053 | @property 1054 | def mask(self): 1055 | np.asarray(self._rayhit.ray.mask) 1056 | 1057 | @property 1058 | def flags(self): 1059 | np.asarray(self._rayhit.ray.flags) 1060 | 1061 | @property 1062 | def time(self): 1063 | np.asarray(self._rayhit.ray.time) 1064 | 1065 | @property 1066 | def tfar(self): 1067 | np.asarray(self._rayhit.ray.tfar) 1068 | 1069 | @property 1070 | def Ng_x(self): 1071 | np.asarray(self._rayhit.hit.Ng_x) 1072 | 1073 | @property 1074 | def Ng_y(self): 1075 | np.asarray(self._rayhit.hit.Ng_y) 1076 | 1077 | @property 1078 | def Ng_z(self): 1079 | np.asarray(self._rayhit.hit.Ng_z) 1080 | 1081 | @property 1082 | def u(self): 1083 | np.asarray(self._rayhit.hit.u) 1084 | 1085 | @property 1086 | def v(self): 1087 | np.asarray(self._rayhit.hit.v) 1088 | 1089 | @property 1090 | def primID(self): 1091 | np.asarray(self._rayhit.hit.primID) 1092 | 1093 | @property 1094 | def geomID(self): 1095 | np.asarray(self._rayhit.hit.geomID) 1096 | 1097 | @property 1098 | def instID(self): 1099 | return tuple( 1100 | self._rayhit.hit.instID[i] 1101 | for i in range(RTC_MAX_INSTANCE_LEVEL_COUNT) 1102 | ) 1103 | 1104 | cdef class IntersectContext: 1105 | cdef: 1106 | RTCIntersectContext _context 1107 | 1108 | def __cinit__(self): 1109 | rtcInitIntersectContext(&self._context) 1110 | 1111 | @property 1112 | def flags(self): 1113 | return IntersectContextFlags(self._context.flags) 1114 | 1115 | @flags.setter 1116 | def flags(self, flags): 1117 | if not isinstance(flags, IntersectContextFlags): 1118 | raise ValueError('flags should be instance of IntersectContextFlags') 1119 | self._context.flags = flags.value 1120 | 1121 | cdef class Scene: 1122 | cdef: 1123 | RTCScene _scene 1124 | Device _device 1125 | 1126 | def __cinit__(self, Device device): 1127 | self._scene = rtcNewScene(device._device) 1128 | self._device = device 1129 | 1130 | def retain(self): 1131 | rtcRetainScene(self._scene) 1132 | 1133 | def release(self): 1134 | rtcReleaseScene(self._scene) 1135 | 1136 | def attach_geometry(self, Geometry geometry): 1137 | return rtcAttachGeometry(self._scene, geometry._geometry) 1138 | 1139 | def detach_geometry(self, geom_id): 1140 | rtcDetachGeometry(self._scene, geom_id) 1141 | 1142 | def set_build_quality(self, build_quality): 1143 | rtcSetSceneBuildQuality(self._scene, build_quality.value) 1144 | 1145 | def commit(self): 1146 | rtcCommitScene(self._scene) 1147 | 1148 | def set_flags(self, flags): 1149 | if isinstance(flags, SceneFlags): 1150 | flags = flags.value 1151 | rtcSetSceneFlags(self._scene, flags) 1152 | 1153 | def intersect1(self, IntersectContext context, RayHit rayhit): 1154 | rtcIntersect1(self._scene, &context._context, &rayhit._rayhit) 1155 | 1156 | def intersect1M(self, IntersectContext context, RayHit1M rayhit): 1157 | rtcIntersect1M(self._scene, &context._context, rayhit._rayhit, 1158 | rayhit._M, sizeof(RTCRayHit)) 1159 | 1160 | def intersectNp(self, IntersectContext context, RayHitNp rayhit): 1161 | rtcIntersectNp(self._scene, &context._context, &rayhit._rayhit, 1162 | rayhit._N) 1163 | 1164 | def occluded1(self, IntersectContext context, Ray ray): 1165 | rtcOccluded1(self._scene, &context._context, &ray._ray) 1166 | 1167 | def occluded1M(self, IntersectContext context, Ray1M ray): 1168 | rtcOccluded1M(self._scene, &context._context, ray._ray, ray._M, 1169 | sizeof(RTCRay)) 1170 | --------------------------------------------------------------------------------