/usr/share/doc/openvdb/html/python.html is in libopenvdb-doc 2.1.0-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.6"/>
<title>OpenVDB: Using OpenVDB in Python</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">OpenVDB
 <span id="projectnumber">2.1.0</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.6 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="index.html">OpenVDB</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Using OpenVDB in Python </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>This section describes the OpenVDB Python module and includes Python code snippets and some complete programs that illustrate how to perform common tasks. (An <a href="./python/index.html">API reference</a> is also available, if <a href="http://epydoc.sourceforge.net/">Epydoc</a> is installed.) As of OpenVDB 2.0, the Python module exposes most of the functionality of the C++ <a class="el" href="classopenvdb_1_1v2__1__0_1_1Grid.html">Grid</a> class, including I/O, metadata management, voxel access and iteration, but almost none of the many <a class="el" href="overview.html#secToolUtils">tools</a>. We expect to add support for tools in forthcoming releases.</p>
<p>The Python module supports a fixed set of grid types. If the symbol <code>PY_OPENVDB_WRAP_ALL_GRID_TYPES</code> is defined at compile time, most of the grid types declared in <a class="el" href="openvdb_8h.html">openvdb.h</a> are accessible in Python, otherwise only <b>FloatGrid</b>, <b>BoolGrid</b> and <b>Vec3SGrid</b> are accessible. To add support for grids with other value types or configurations, search for <code>PY_OPENVDB_WRAP_ALL_GRID_TYPES</code> in the module source code, update the code as appropriate and recompile the module. (It is possible that this process will be streamlined in the future with a plugin mechanism.) Note however that adding grid types can significantly increase the time and memory needed to compile the module and can significantly increase the size of the resulting executable. In addition, grids of custom types that are saved to <code>.vdb</code> files or pickled will not be readable by clients using the standard version of the module.</p>
<p>Also note that the <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html">Tree</a> class is not exposed in Python. Much of its functionality is either available through the <a class="el" href="classopenvdb_1_1v2__1__0_1_1Grid.html">Grid</a> or is too low-level to be generally useful in Python. Although trees are not accessible in Python, they can of course be operated on indirectly. Of note are the grid methods <b>copy</b>, which returns a new grid that shares its tree with the original grid, <b>deepCopy</b>, which returns a new grid that owns its own tree, and <b>sharesWith</b>, which reports whether two grids share a tree.</p>
<h1><a class="anchor" id="Contents"></a>
Contents</h1>
<ul>
<li><a class="el" href="python.html#sPyBasics">Getting started</a></li>
<li><a class="el" href="python.html#sPyHandlingMetadata">Handling metadata</a></li>
<li><a class="el" href="python.html#sPyAccessors">Voxel access</a></li>
<li><a class="el" href="python.html#sPyIteration">Iteration</a></li>
<li><a class="el" href="python.html#sPyNumPy">Working with NumPy arrays</a></li>
<li><a class="el" href="python.html#sPyCppAPI">C++ glue routines</a></li>
</ul>
<h1><a class="anchor" id="sPyBasics"></a>
Getting started</h1>
<p>The following example is a complete program that illustrates some of the basic steps to create grids and write them to disk: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> import pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment"># A grid comprises a sparse tree representation of voxel data,</span></div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment"># user-supplied metadata and a voxel space to world space transform,</span></div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="comment"># which defaults to the identity transform.</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="comment"># A FloatGrid stores one single-precision floating point value per voxel.</span></div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment"># Other grid types include BoolGrid and Vec3SGrid. The module-level</span></div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment"># attribute pyopenvdb.GridTypes gives the complete list.</span></div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> cube = vdb.FloatGrid()</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> cube.fill(min=(100, 100, 100), max=(199, 199, 199), value=1.0)</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> </div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="comment"># Name the grid "cube".</span></div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> cube.name = <span class="stringliteral">'cube'</span></div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment"># Populate another FloatGrid with a sparse, narrow-band level set</span></div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="comment"># representation of a sphere with radius 50 voxels, located at</span></div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="comment"># (1.5, 2, 3) in index space.</span></div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> sphere = vdb.createLevelSetSphere(radius=50, center=(1.5, 2, 3))</div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> </div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> <span class="comment"># Associate some metadata with the grid.</span></div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> sphere[<span class="stringliteral">'radius'</span>] = 50.0</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> </div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="comment"># Associate a scaling transform with the grid that sets the voxel size</span></div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="comment"># to 0.5 units in world space.</span></div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> sphere.transform = vdb.createLinearTransform(voxelSize=0.5)</div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> </div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> <span class="comment"># Name the grid "sphere".</span></div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> sphere.name = <span class="stringliteral">'sphere'</span></div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> </div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> <span class="comment"># Write both grids to a VDB file.</span></div>
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> vdb.write(<span class="stringliteral">'mygrids.vdb'</span>, grids=[cube, sphere])</div>
</div><!-- fragment --><p>This example shows how to read grids from files, and some ways to modify grids: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment"># Read a .vdb file and return a list of grids populated with</span></div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment"># their metadata and transforms, but not their trees.</span></div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> filename = <span class="stringliteral">'mygrids.vdb'</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> grids = vdb.readAllGridMetadata(filename)</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> </div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment"># Look for and read in a level-set grid that has certain metadata.</span></div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> sphere = <span class="keywordtype">None</span></div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="keywordflow">for</span> grid <span class="keywordflow">in</span> grids:</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>  <span class="keywordflow">if</span> (grid.gridClass == vdb.GridClass.LEVEL_SET <span class="keywordflow">and</span> <span class="stringliteral">'radius'</span> <span class="keywordflow">in</span> grid</div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span>  <span class="keywordflow">and</span> grid[<span class="stringliteral">'radius'</span>] > 10.0):</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span>  sphere = vdb.read(filename, grid.name)</div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>  <span class="keywordflow">else</span>:</div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>  <span class="keywordflow">print</span> <span class="stringliteral">'skipping grid'</span>, grid.name</div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> </div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="keywordflow">if</span> sphere:</div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>  <span class="comment"># Convert the level set sphere to a narrow-band fog volume, in which</span></div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span>  <span class="comment"># interior voxels have value 1, exterior voxels have value 0, and</span></div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>  <span class="comment"># narrow-band voxels have values varying linearly from 0 to 1.</span></div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> </div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span>  outside = sphere.background</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>  width = 2.0 * outside</div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> </div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span>  <span class="comment"># Visit and update all of the grid's active values, which correspond to</span></div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>  <span class="comment"># voxels in the narrow band.</span></div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span>  <span class="keywordflow">for</span> iter <span class="keywordflow">in</span> sphere.iterOnValues():</div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>  dist = iter.value</div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>  iter.value = (outside - dist) / width</div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> </div>
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span>  <span class="comment"># Visit all of the grid's inactive tile and voxel values and update</span></div>
<div class="line"><a name="l00032"></a><span class="lineno"> 32</span>  <span class="comment"># the values that correspond to the interior region.</span></div>
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span>  <span class="keywordflow">for</span> iter <span class="keywordflow">in</span> sphere.iterOffValues():</div>
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>  <span class="keywordflow">if</span> iter.value < 0.0:</div>
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>  iter.value = 1.0</div>
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span>  iter.active = <span class="keyword">False</span></div>
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> </div>
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>  <span class="comment"># Set exterior voxels to 0.</span></div>
<div class="line"><a name="l00039"></a><span class="lineno"> 39</span>  sphere.background = 0.0</div>
<div class="line"><a name="l00040"></a><span class="lineno"> 40</span> </div>
<div class="line"><a name="l00041"></a><span class="lineno"> 41</span>  sphere.gridClass = vdb.GridClass.FOG_VOLUME</div>
</div><!-- fragment --><h1><a class="anchor" id="sPyHandlingMetadata"></a>
Handling metadata</h1>
<p>Metadata of various types (string, bool, int, float, and 2- and 3-element sequences of ints or floats) can be attached both to individual grids and to files on disk, either by supplying a Python dictionary of (name, value) pairs or, in the case of grids, through a dictionary-like interface.</p>
<p>Add (name, value) metadata pairs to a grid as you would to a dictionary. A new value overwrites an existing value if the name matches an existing name. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> grid = vdb.Vec3SGrid()</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> grid[<span class="stringliteral">'vector'</span>] = <span class="stringliteral">'gradient'</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> >>> grid[<span class="stringliteral">'radius'</span>] = 50.0</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> >>> grid[<span class="stringliteral">'center'</span>] = (10, 15, 10)</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> >>> grid.metadata</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> {<span class="stringliteral">'vector'</span>: <span class="stringliteral">'gradient'</span>, <span class="stringliteral">'radius'</span>: 50.0, <span class="stringliteral">'center'</span>: (10, 15, 10)}</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> </div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> >>> grid[<span class="stringliteral">'radius'</span>]</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> 50.0</div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> >>> <span class="stringliteral">'radius'</span> <span class="keywordflow">in</span> grid, <span class="stringliteral">'misc'</span> <span class="keywordflow">in</span> grid</div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> (<span class="keyword">True</span>, <span class="keyword">False</span>)</div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> </div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="comment"># OK to overwrite an existing value with a value of another type:</span></div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> >>> grid[<span class="stringliteral">'center'</span>] = 0.0</div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> </div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> <span class="comment"># A 4-element sequence is not a supported metadata value type:</span></div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> >>> grid[<span class="stringliteral">'center'</span>] = (0, 0, 0, 0)</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>  File <span class="stringliteral">"<stdin>"</span>, line 1, <span class="keywordflow">in</span> <module></div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> TypeError: metadata value <span class="stringliteral">"(0, 0, 0, 0)"</span> of type tuple <span class="keywordflow">is</span> <span class="keywordflow">not</span> allowed</div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="comment"># Metadata names must be strings:</span></div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> >>> grid[0] = (10.5, 15, 30)</div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>  File <span class="stringliteral">"<stdin>"</span>, line 1, <span class="keywordflow">in</span> <module></div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> TypeError: expected str, found int <span class="keyword">as</span> argument 1 to __setitem__()</div>
</div><!-- fragment --><p> Alternatively, replace all or some of a grid’s metadata by supplying a (name, value) dictionary: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> metadata = {</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> ... <span class="stringliteral">'vector'</span>: <span class="stringliteral">'gradient'</span>,</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> ... <span class="stringliteral">'radius'</span>: 50.0,</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> ... <span class="stringliteral">'center'</span>: (10, 15, 10)</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> ... }</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> </div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment"># Replace all of the grid's metadata.</span></div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> >>> grid.metadata = metadata</div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> </div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> >>> metadata = {</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> ... <span class="stringliteral">'center'</span>: [10.5, 15, 30],</div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> ... <span class="stringliteral">'scale'</span>: 3.14159</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> ... }</div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment"># Overwrite "center" and add "scale":</span></div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> >>> grid.updateMetadata(metadata)</div>
</div><!-- fragment --><p>Iterate over a grid’s metadata as you would over a dictionary: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keywordflow">for</span> key <span class="keywordflow">in</span> grid:</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> ... <span class="keywordflow">print</span> <span class="stringliteral">'%s = %s'</span> % (key, grid[key])</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> ...</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> vector = gradient</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> radius = 50.0</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> scale = 3.14159</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> center = (10.5, 15.0, 30.0)</div>
</div><!-- fragment --><p>Removing metadata is also straightforward: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> del grid[<span class="stringliteral">'vector'</span>]</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> del grid[<span class="stringliteral">'center'</span>]</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> del grid[<span class="stringliteral">'vector'</span>] <span class="comment"># error: already removed</span></div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span>  File <span class="stringliteral">"<stdin>"</span>, line 1, <span class="keywordflow">in</span> <module></div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> KeyError: <span class="stringliteral">'vector'</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> </div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> >>> grid.metadata = {} <span class="comment"># remove all metadata</span></div>
</div><!-- fragment --><p>Some grid metadata is exposed in the form of properties, either because it might be frequently accessed (a grid’s name, for example) or because its allowed values are somehow restricted: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> grid = vdb.createLevelSetSphere(radius=10.0)</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> grid.metadata</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> {<span class="stringliteral">'class'</span>: <span class="stringliteral">'level set'</span>}</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> grid.gridClass = vdb.GridClass.FOG_VOLUME</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> >>> grid.metadata</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> {<span class="stringliteral">'class'</span>: <span class="stringliteral">'fog volume'</span>}</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="comment"># The gridClass property requires a string value:</span></div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> >>> grid.gridClass = 123</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>  File <span class="stringliteral">"<stdin>"</span>, line 1, <span class="keywordflow">in</span> <module></div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> TypeError: expected str, found int <span class="keyword">as</span> argument 1 to <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1io.html#adf56f19f911dd30fd3e8c003269dab21">setGridClass</a>()</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> </div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="comment"># Only certain strings are recognized; see pyopenvdb.GridClass</span></div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment"># for the complete list.</span></div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> >>> grid.gridClass = <span class="stringliteral">'Hello, world.'</span></div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> >>> grid.metadata</div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> {<span class="stringliteral">'class'</span>: <span class="stringliteral">'unknown'</span>}</div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> </div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> >>> grid.metadata = {}</div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> >>> grid.vectorType = vdb.VectorType.COVARIANT</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> >>> grid.metadata</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> {<span class="stringliteral">'vector_type'</span>: <span class="stringliteral">'covariant'</span>}</div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> </div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> >>> grid.name = <span class="stringliteral">'sphere'</span></div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> >>> grid.creator = <span class="stringliteral">'Python'</span></div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> >>> grid.metadata</div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> {<span class="stringliteral">'vector_type'</span>: <span class="stringliteral">'covariant'</span>, <span class="stringliteral">'name'</span>: <span class="stringliteral">'sphere'</span>, <span class="stringliteral">'creator'</span>: <span class="stringliteral">'Python'</span>}</div>
</div><!-- fragment --><p> Setting these properties to <code>None</code> removes the corresponding metadata, but the properties retain default values: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> grid.creator = grid.vectorType = <span class="keywordtype">None</span></div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> grid.metadata</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> {<span class="stringliteral">'name'</span>: <span class="stringliteral">'sphere'</span>}</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> grid.creator, grid.vectorType</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> (<span class="stringliteral">''</span>, <span class="stringliteral">'invariant'</span>)</div>
</div><!-- fragment --><p>Metadata can be associated with a <code>.vdb</code> file at the time the file is written, by supplying a (name, value) dictionary as the optional <code>metadata</code> argument to the <b>write</b> function: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> metadata = {</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> ... <span class="stringliteral">'creator'</span>: <span class="stringliteral">'Python'</span>,</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> ... <span class="stringliteral">'time'</span>: <span class="stringliteral">'11:05:00'</span></div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> ... }</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> vdb.write(<span class="stringliteral">'mygrids.vdb'</span>, grids=grid, metadata=metadata)</div>
</div><!-- fragment --><p> File-level metadata can be retrieved with either the <b>readMetadata</b> function or the <b>readAll</b> function: </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> metadata = vdb.readMetadata(<span class="stringliteral">'mygrids.vdb'</span>)</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> metadata</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> {<span class="stringliteral">'creator'</span>: <span class="stringliteral">'Python'</span>, <span class="stringliteral">'time'</span>: <span class="stringliteral">'11:05:00'</span>}</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> grids, metadata = vdb.readAll(<span class="stringliteral">'mygrids.vdb'</span>)</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> >>> metadata</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> {<span class="stringliteral">'creator'</span>: <span class="stringliteral">'Python'</span>, <span class="stringliteral">'time'</span>: <span class="stringliteral">'11:05:00'</span>}</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> >>> [grid.name <span class="keywordflow">for</span> grid <span class="keywordflow">in</span> grids]</div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> [<span class="stringliteral">'sphere'</span>]</div>
</div><!-- fragment --><h1><a class="anchor" id="sPyAccessors"></a>
Voxel access</h1>
<p>Grids provide read-only and read/write accessors for voxel lookup via <img class="formulaInl" alt="$(i,j,k)$" src="form_51.png"/> index coordinates. Accessors store references to their parent grids, so a grid will not be deleted while it has accessors in use.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment"># Read two grids from a file.</span></div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> >>> grids, metadata = vdb.readAll(<span class="stringliteral">'smoke2.vdb'</span>)</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> [grid.name <span class="keywordflow">for</span> grid <span class="keywordflow">in</span> grids]</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> [<span class="stringliteral">'density'</span>, <span class="stringliteral">'v'</span>]</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> </div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment"># Get read/write accessors to the two grids.</span></div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> >>> dAccessor = grids[0].getAccessor()</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> >>> vAccessor = grids[1].getAccessor()</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> </div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> >>> ijk = (100, 103, 101)</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> </div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> >>> dAccessor.probeValue(ijk)</div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> (0.17614534497261047, <span class="keyword">True</span>)</div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="comment"># Change the value of a voxel.</span></div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> >>> dAccessor.setValueOn(ijk, 0.125)</div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> >>> dAccessor.probeValue(ijk)</div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> (0.125, <span class="keyword">True</span>)</div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> </div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> >>> vAccessor.probeValue(ijk)</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> ((-2.90625, 9.84375, 0.84228515625), <span class="keyword">True</span>)</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="comment"># Change the active state of a voxel.</span></div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> >>> vAccessor.setActiveState(ijk, <span class="keyword">False</span>)</div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> >>> vAccessor.probeValue(ijk)</div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> ((-2.90625, 9.84375, 0.84228515625), <span class="keyword">False</span>)</div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> </div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> <span class="comment"># Get a read-only accessor to one of the grids.</span></div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> >>> dAccessor = grids[0].getConstAccessor()</div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> >>> dAccessor.setActiveState(ijk, <span class="keyword">False</span>)</div>
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span>  File <span class="stringliteral">"<stdin>"</span>, line 1, <span class="keywordflow">in</span> <module></div>
<div class="line"><a name="l00032"></a><span class="lineno"> 32</span> TypeError: accessor <span class="keywordflow">is</span> read-only</div>
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> </div>
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span> <span class="comment"># Delete the accessors once they are no longer needed,</span></div>
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span> <span class="comment"># so that the grids can be garbage-collected.</span></div>
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span> >>> del dAccessor, vAccessor</div>
</div><!-- fragment --><h1><a class="anchor" id="sPyIteration"></a>
Iteration</h1>
<p>Grids provide read-only and read/write iterators over their values. Iteration is over sequences of value objects (<b>BoolGrid.Value</b>s, <b>FloatGrid.Value</b>s, etc.) that expose properties such as the number of voxels spanned by a value (one, for a voxel value, more than one for a tile value), its coordinates and its active state. Value objects returned by read-only iterators are immutable; those returned by read/write iterators permit assignment to their active state and value properties, which modifies the underlying grid. Value objects store references to their parent grids, so a grid will not be deleted while one of its value objects is in use.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> grid = vdb.read(<span class="stringliteral">'smoke2.vdb'</span>, gridname=<span class="stringliteral">'v'</span>)</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> >>> grid.__class__.__name__</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="stringliteral">'Vec3SGrid'</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> </div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment"># Iterate over inactive values and print the coordinates of the first</span></div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment"># five voxel values and the bounding boxes of the first five tile values.</span></div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> >>> voxels = tiles = 0</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> ... N = 5</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> ... <span class="keywordflow">for</span> item <span class="keywordflow">in</span> grid.citerOffValues(): <span class="comment"># read-only iterator</span></div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> ... <span class="keywordflow">if</span> voxels == N <span class="keywordflow">and</span> tiles == N:</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> ... <span class="keywordflow">break</span></div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> ... <span class="keywordflow">if</span> item.count == 1:</div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> ... <span class="keywordflow">if</span> voxels < N:</div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> ... voxels += 1</div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> ... <span class="keywordflow">print</span> <span class="stringliteral">'voxel'</span>, item.min</div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> ... <span class="keywordflow">else</span>:</div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> ... <span class="keywordflow">if</span> tiles < N:</div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> ... tiles += 1</div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> ... <span class="keywordflow">print</span> <span class="stringliteral">'tile'</span>, item.min, item.max</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> ... </div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> tile (0, 0, 0) (7, 7, 7)</div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> tile (0, 0, 8) (7, 7, 15)</div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> tile (0, 0, 16) (7, 7, 23)</div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> tile (0, 0, 24) (7, 7, 31)</div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> tile (0, 0, 32) (7, 7, 39)</div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> voxel (40, 96, 88)</div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> voxel (40, 96, 89)</div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> voxel (40, 96, 90)</div>
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> voxel (40, 96, 91)</div>
<div class="line"><a name="l00032"></a><span class="lineno"> 32</span> voxel (40, 96, 92)</div>
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> </div>
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span> <span class="comment"># Iterate over and normalize all active values.</span></div>
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span> >>> <span class="keyword">from</span> math <span class="keyword">import</span> sqrt</div>
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span> >>> <span class="keywordflow">for</span> item <span class="keywordflow">in</span> grid.iterOnValues(): <span class="comment"># read/write iterator</span></div>
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> ... vector = item.value</div>
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span> ... magnitude = sqrt(sum(x * x <span class="keywordflow">for</span> x <span class="keywordflow">in</span> vector))</div>
<div class="line"><a name="l00039"></a><span class="lineno"> 39</span> ... item.value = [x / magnitude <span class="keywordflow">for</span> x <span class="keywordflow">in</span> vector]</div>
<div class="line"><a name="l00040"></a><span class="lineno"> 40</span> ...</div>
</div><!-- fragment --><p>For some operations, it might be more convenient to use one of the grid methods <b>mapOn</b>, <b>mapOff</b> or <b>mapAll</b>. These methods iterate over a grid’s tiles and voxels (active, inactive or both, respectively) and replace each value <em>x</em> with <em>f</em>(<em>x</em>), where <em>f</em> is a callable object. These methods are not multithreaded. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> <span class="keyword">from</span> math <span class="keyword">import</span> sqrt</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> </div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> >>> grid = vdb.read(<span class="stringliteral">'smoke2.vdb'</span>, gridname=<span class="stringliteral">'v'</span>)</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> >>> <span class="keyword">def </span><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#af5c0227e6c84797a06542df58c2b564d">normalize</a>(vector):</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> ... magnitude = sqrt(sum(x * x <span class="keywordflow">for</span> x <span class="keywordflow">in</span> vector))</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> ... <span class="keywordflow">return</span> [x / magnitude <span class="keywordflow">for</span> x <span class="keywordflow">in</span> vector]</div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> ...</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> >>> grid.mapOn(normalize)</div>
</div><!-- fragment --><p>Similarly, the <b>combine</b> method iterates over corresponding pairs of values (tile and voxel) of two grids <em>A</em> and <em>B</em> of the same type (<b>FloatGrid</b>, <b>Vec3SGrid</b>, etc.), replacing values in <em>A</em> with <em>f</em>(<em>a</em>, <em>b</em>), where <em>f</em> is a callable object. This operation assumes that index coordinates <img class="formulaInl" alt="$(i,j,k)$" src="form_51.png"/> in both grids correspond to the same physical, world space location. Also, the operation always leaves grid <em>B</em> empty. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> density = vdb.read(<span class="stringliteral">'smoke2.vdb'</span>, gridname=<span class="stringliteral">'density'</span>)</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> >>> density.__class__.__name__</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="stringliteral">'FloatGrid'</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> </div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> >>> sphere = vdb.createLevelSetSphere(radius=50.0, center=(100, 300, 100))</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> >>> density.combine(sphere, <span class="keyword">lambda</span> a, b: <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a648c2c2b71ba04512f9ef7393095b39f">min</a>(a, b))</div>
</div><!-- fragment --><p> For now, <b>combine</b> operates only on tile and voxel values, not on their active states or other attributes.</p>
<h1><a class="anchor" id="sPyNumPy"></a>
Working with NumPy arrays</h1>
<p>Large data sets are often handled in Python using <a href="http://www.numpy.org/">NumPy</a>. The OpenVDB Python module can optionally be compiled with NumPy support. With NumPy enabled, the <b>copyFromArray</b> and <b>copyToArray</b> grid methods can be used to exchange data efficiently between scalar-valued grids and three-dimensional NumPy arrays and between vector-valued grids and four-dimensional NumPy arrays. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> <span class="keyword">import</span> pyopenvdb <span class="keyword">as</span> vdb</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> <span class="keyword">import</span> numpy</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> </div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> >>> array = numpy.random.rand(200, 200, 200)</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> >>> array.dtype</div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> dtype(<span class="stringliteral">'float64'</span>)</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> </div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment"># Copy values from a three-dimensional array of doubles</span></div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="comment"># into a grid of floats.</span></div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> >>> grid = vdb.FloatGrid()</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> >>> grid.copyFromArray(array)</div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> >>> grid.activeVoxelCount() == array.size</div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> <span class="keyword">True</span></div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> >>> grid.evalActiveVoxelBoundingBox()</div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> ((0, 0, 0), (199, 199, 199))</div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> </div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="comment"># Copy values from a four-dimensional array of ints</span></div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="comment"># into a grid of float vectors.</span></div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> >>> vecarray = numpy.ndarray((60, 70, 80, 3), int)</div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> >>> vecarray.fill(42)</div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> >>> vecgrid = vdb.Vec3SGrid()</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> >>> vecgrid.copyFromArray(vecarray)</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> >>> vecgrid.activeVoxelCount() == 60 * 70 * 80</div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="keyword">True</span></div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> >>> vecgrid.evalActiveVoxelBoundingBox()</div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> ((0, 0, 0), (59, 69, 79))</div>
</div><!-- fragment --><p>When copying from a NumPy array, values in the array that are equal to the destination grid’s background value (or close to it, if the <code>tolerance</code> argument to <b>copyFromArray</b> is nonzero) are set to the background value and are marked inactive. All other values are marked active. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> grid.clear()</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> grid.copyFromArray(array, tolerance=0.2)</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> <span class="keywordflow">print</span> <span class="stringliteral">'%d%% of copied voxels are active'</span> % (</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> ... round(100.0 * grid.activeVoxelCount() / array.size))</div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> 80% of copied voxels are active</div>
</div><!-- fragment --><p>The optional <code>ijk</code> argument specifies the index coordinates of the voxel in the destination grid into which to start copying values. That is, array index (0, 0, 0) maps to voxel <img class="formulaInl" alt="$(i,j,k)$" src="form_51.png"/>. </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> grid.clear()</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> grid.copyFromArray(array, ijk=(-1, 2, 3))</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> grid.evalActiveVoxelBoundingBox()</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> ((-1, 2, 3), (198, 201, 202))</div>
</div><!-- fragment --><p>The <b>copyToArray</b> method also accepts an <code>ijk</code> argument. It specifies the index coordinates of the voxel to be copied to array index (0, 0, 0). </p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> >>> grid = vdb.createLevelSetSphere(radius=10.0)</div>
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> >>> array = numpy.ndarray((40, 40, 40), int)</div>
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> >>> array.fill(0)</div>
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment"># Copy values from a grid of floats into</span></div>
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="comment"># a three-dimensional array of ints.</span></div>
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> >>> grid.copyToArray(array, ijk=(-15, -20, -35))</div>
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> >>> array[15, 20]</div>
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> array([ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,</div>
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span>  3, 3, 3, 3, 3, 3, 3, 3, 3, 3,</div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>  3, 3, 3, 2, 1, 0, -1, -2, -3, -3,</div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>  -3, -3, -3, -3, -3, -3, -3, -3, -3, -3])</div>
</div><!-- fragment --><p> <b>copyToArray</b> has no <code>tolerance</code> argument, because there is no distinction between active and inactive values in the destination array.</p>
<h1><a class="anchor" id="sPyCppAPI"></a>
C++ glue routines</h1>
<p>Python objects of type <b>FloatGrid</b>, <b>Vec3SGrid</b>, etc. are backed by C structs that “inherit” from <code>PyObject</code>. The OpenVDB Python extension module includes public functions that you can call in your own extension modules to convert between <a class="el" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Grids</a> and <code>PyObject</code>s. See the <a class="el" href="pyopenvdb_8h.html" title="Glue functions for access to pyOpenVDB objects from C++ code. ">pyopenvdb.h</a> reference for a description of these functions and a usage example.</p>
<p>Your extension module might need to link against the OpenVDB extension module in order to access these functions. On UNIX systems, it might also be necessary to specify the <code>RTLD_GLOBAL</code> flag when importing the OpenVDB module, to allow its symbols to be shared across modules. See <b>setdlopenflags</b> in the Python <b>sys</b> module for one way to do this. </p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Feb 7 2014 01:56:46 for OpenVDB by  <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.6
</small></address>
</body>
</html>
|