/usr/share/doc/openvdb/html/codeExamples.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 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | <!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: OpenVDB Cookbook</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><li class="navelem"><a class="el" href="faq.html">Frequently Asked Questions</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">OpenVDB Cookbook </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>This section provides code snippets and some complete programs that illustrate how to use OpenVDB and how to perform common tasks.</p>
<h1><a class="anchor" id="Contents"></a>
Contents</h1>
<ul>
<li><a class="el" href="codeExamples.html#sHelloWorld">"Hello, World" for OpenVDB</a><ul>
<li><a class="el" href="codeExamples.html#sCompilingHelloWorld">Compiling</a></li>
</ul>
</li>
<li><a class="el" href="codeExamples.html#sAllocatingGrids">Creating and writing a grid</a></li>
<li><a class="el" href="codeExamples.html#sPopulatingGrids">Populating a grid with values</a></li>
<li><a class="el" href="codeExamples.html#sModifyingGrids">Reading and modifying a grid</a></li>
<li><a class="el" href="codeExamples.html#sStreamIO">Stream I/O</a></li>
<li><a class="el" href="codeExamples.html#sHandlingMetadata">Handling metadata</a><ul>
<li><a class="el" href="codeExamples.html#sAddingMetadata">Adding metadata</a></li>
<li><a class="el" href="codeExamples.html#sGettingMetadata">Retrieving metadata</a></li>
<li><a class="el" href="codeExamples.html#sRemovingMetadata">Removing metadata</a></li>
</ul>
</li>
<li><a class="el" href="codeExamples.html#sIteration">Iteration</a><ul>
<li><a class="el" href="codeExamples.html#sNodeIterator">Node Iterator</a></li>
<li><a class="el" href="codeExamples.html#sLeafIterator">Leaf Node Iterator</a></li>
<li><a class="el" href="codeExamples.html#sValueIterator">Value Iterator</a></li>
</ul>
</li>
<li><a class="el" href="codeExamples.html#sXformTools">Transforming grids</a><ul>
<li><a class="el" href="codeExamples.html#sResamplingTools">Geometric transformation</a></li>
<li><a class="el" href="codeExamples.html#sValueXformTools">Value transformation</a></li>
</ul>
</li>
<li><a class="el" href="codeExamples.html#sCombiningGrids">Combining grids</a><ul>
<li><a class="el" href="codeExamples.html#sCsgTools">Level set CSG operations</a></li>
<li><a class="el" href="codeExamples.html#sCompTools">Compositing operations</a></li>
<li><a class="el" href="codeExamples.html#sCombineTools">Generic combination</a></li>
</ul>
</li>
<li><a class="el" href="codeExamples.html#sGenericProg">Generic programming</a><ul>
<li><a class="el" href="codeExamples.html#sTypedGridMethods">Calling Grid methods</a></li>
</ul>
</li>
</ul>
<h1><a class="anchor" id="sHelloWorld"></a>
"Hello, World" for OpenVDB</h1>
<p>This is a very simple example showing how to create a grid and access its voxels. OpenVDB supports both random access to voxels by coordinates and sequential access by means of iterators. This example illustrates both types of access: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <iostream></span></div>
<div class="line"></div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Initialize the OpenVDB library. This must be called at least</span></div>
<div class="line"> <span class="comment">// once per program and may safely be called multiple times.</span></div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a68e8673fb73be5d09f0cbc957b6a1293">openvdb::initialize</a>();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Create an empty floating-point grid with background value 0. </span></div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> grid = <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#afed9748b2280ee9155aa1033cc583bc7">openvdb::FloatGrid::create</a>();</div>
<div class="line"></div>
<div class="line"> std::cout << <span class="stringliteral">"Testing random access:"</span> << std::endl;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Get an accessor for coordinate-based access to voxels.</span></div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html">openvdb::FloatGrid::Accessor</a> accessor = grid->getAccessor();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Define a coordinate with large signed indices.</span></div>
<div class="line"> openvdb::Coord xyz(1000, -200000000, 30000000);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Set the voxel value at (1000, -200000000, 30000000) to 1.</span></div>
<div class="line"> accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#a83302a39df403b0b10ffcadac5856916">setValue</a>(xyz, 1.0);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Verify that the voxel value at (1000, -200000000, 30000000) is 1.</span></div>
<div class="line"> std::cout << <span class="stringliteral">"Grid"</span> << xyz << <span class="stringliteral">" = "</span> << accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#aa0cec1da633233009e933bb56b1ec345">getValue</a>(xyz) << std::endl;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Reset the coordinates to those of a different voxel.</span></div>
<div class="line"> xyz.reset(1000, 200000000, -30000000);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Verify that the voxel value at (1000, 200000000, -30000000) is</span></div>
<div class="line"> <span class="comment">// the background value, 0.</span></div>
<div class="line"> std::cout << <span class="stringliteral">"Grid"</span> << xyz << <span class="stringliteral">" = "</span> << accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#aa0cec1da633233009e933bb56b1ec345">getValue</a>(xyz) << std::endl;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Set the voxel value at (1000, 200000000, -30000000) to 2.</span></div>
<div class="line"> accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#a83302a39df403b0b10ffcadac5856916">setValue</a>(xyz, 2.0);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Set the voxels at the two extremes of the available coordinate space.</span></div>
<div class="line"> <span class="comment">// For 32-bit signed coordinates these are (-2147483648, -2147483648, -2147483648)</span></div>
<div class="line"> <span class="comment">// and (2147483647, 2147483647, 2147483647).</span></div>
<div class="line"> accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#a83302a39df403b0b10ffcadac5856916">setValue</a>(<a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a648c2c2b71ba04512f9ef7393095b39f">openvdb::Coord::min</a>(), 3.0f);</div>
<div class="line"> accessor.<a class="code" href="classopenvdb_1_1v2__1__0_1_1tree_1_1ValueAccessor.html#a83302a39df403b0b10ffcadac5856916">setValue</a>(<a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a567891aeefe25ecb9b1729190c60e3d4">openvdb::Coord::max</a>(), 4.0f);</div>
<div class="line"></div>
<div class="line"> std::cout << <span class="stringliteral">"Testing sequential access:"</span> << std::endl;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Print all active ("on") voxels by means of an iterator.</span></div>
<div class="line"> <span class="keywordflow">for</span> (<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#af73f7039c425b2517eb1772881d83ad4">openvdb::FloatGrid::ValueOnCIter</a> iter = grid->cbeginValueOn(); iter; ++iter) {</div>
<div class="line"> std::cout << <span class="stringliteral">"Grid"</span> << iter.getCoord() << <span class="stringliteral">" = "</span> << *iter << std::endl;</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><p> Output: </p>
<div class="fragment"><div class="line">Testing random access:</div>
<div class="line">Grid[1000, -200000000, 30000000] = 1</div>
<div class="line">Grid[1000, 200000000, -30000000] = 0</div>
<div class="line">Testing sequential access:</div>
<div class="line">Grid[-2147483648, -2147483648, -2147483648] = 3</div>
<div class="line">Grid[1000, -200000000, 30000000] = 1</div>
<div class="line">Grid[1000, 200000000, -30000000] = 2</div>
<div class="line">Grid[2147483647, 2147483647, 2147483647] = 4</div>
</div><!-- fragment --><h2><a class="anchor" id="sCompilingHelloWorld"></a>
Compiling</h2>
<p>See the <code>Makefile</code> and <code>INSTALL</code> file included in this distribution for details on how to build and install the OpenVDB library. By default, installation is into the directory tree rooted at <code>/tmp/OpenVDB/</code>, but this can be changed either by editing the value of the <code>INSTALL_DIR</code> variable in the makefile or by setting the desired value from the command line, as in the following example: </p>
<div class="fragment"><div class="line">make install INSTALL_DIR=/usr/local</div>
</div><!-- fragment --><p> Once OpenVDB has been installed, the simplest way to compile a program like the “Hello, World” example above is to examine the commands that are used to build the <code>vdb_print</code> tool: </p>
<div class="fragment"><div class="line">rm vdb_print</div>
<div class="line">make verbose=yes vdb_print</div>
</div><!-- fragment --><p> and then replace “<code>-o vdb_print</code>” with, for example, “<code>-o helloworld</code>” and “<code>cmd/openvdb_print/main.cc</code>” with “<code>helloworld.cc</code>”.</p>
<h1><a class="anchor" id="sAllocatingGrids"></a>
Creating and writing a grid</h1>
<p>This example is a complete program that illustrates some of the basic steps to create grids and write them to disk. (See <a class="el" href="codeExamples.html#sPopulatingGrids">Populating a grid with values</a>, below, for the implementation of the <code>makeSphere()</code> function.) </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a68e8673fb73be5d09f0cbc957b6a1293">openvdb::initialize</a>();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Create a shared pointer to a newly-allocated grid of a built-in type:</span></div>
<div class="line"> <span class="comment">// in this case, a FloatGrid, which stores one single-precision floating point</span></div>
<div class="line"> <span class="comment">// value per voxel. Other built-in grid types include BoolGrid, DoubleGrid,</span></div>
<div class="line"> <span class="comment">// Int32Grid and Vec3SGrid (see openvdb.h for the complete list).</span></div>
<div class="line"> <span class="comment">// The grid comprises a sparse tree representation of voxel data,</span></div>
<div class="line"> <span class="comment">// user-supplied metadata and a voxel space to world space transform,</span></div>
<div class="line"> <span class="comment">// which defaults to the identity transform.</span></div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> grid =</div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#afed9748b2280ee9155aa1033cc583bc7">openvdb::FloatGrid::create</a>(<span class="comment">/*background value=*/</span>2.0);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Populate the grid with a sparse, narrow-band level set representation</span></div>
<div class="line"> <span class="comment">// of a sphere with radius 50 voxels, located at (1.5, 2, 3) in index space.</span></div>
<div class="line"> makeSphere(*grid, <span class="comment">/*radius=*/</span>50.0, <span class="comment">/*center=*/</span><a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html">openvdb::Vec3f</a>(1.5, 2, 3));</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Associate some metadata with the grid.</span></div>
<div class="line"> grid->insertMeta(<span class="stringliteral">"radius"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::FloatMetadata</a>(50.0));</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Associate a scaling transform with the grid that sets the voxel size</span></div>
<div class="line"> <span class="comment">// to 0.5 units in world space.</span></div>
<div class="line"> grid->setTransform(</div>
<div class="line"> openvdb::math::Transform::createLinearTransform(<span class="comment">/*voxel size=*/</span>0.5));</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Identify the grid as a level set.</span></div>
<div class="line"> grid->setGridClass(<a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a511a7f5bd868162ec06bcc20b98e160eac12b83a53c9998ec7823ba0ac9c1521d">openvdb::GRID_LEVEL_SET</a>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Name the grid "LevelSetSphere".</span></div>
<div class="line"> grid->setName(<span class="stringliteral">"LevelSetSphere"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Create a VDB file object.</span></div>
<div class="line"> openvdb::io::File file(<span class="stringliteral">"mygrids.vdb"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Add the grid pointer to a container.</span></div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aa7853474b8fa140799c730775f891aca">openvdb::GridPtrVec</a> grids;</div>
<div class="line"> grids.push_back(grid);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Write out the contents of the container.</span></div>
<div class="line"> file.write(grids);</div>
<div class="line"> file.close();</div>
<div class="line">}</div>
</div><!-- fragment --><p>The OpenVDB library includes optimized routines for many common tasks. For example, most of the steps given above are encapsulated in the function <a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#a3a2625fb8ecc82eeb5f5e9b0a32eea6f">tools::createLevelSetSphere()</a>, so that the above can be written simply as follows:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/LevelSetSphere.h></span></div>
<div class="line"></div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a68e8673fb73be5d09f0cbc957b6a1293">openvdb::initialize</a>();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Create a FloatGrid and populate it with a narrow-band</span></div>
<div class="line"> <span class="comment">// signed distance field of a sphere.</span></div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> grid =</div>
<div class="line"> openvdb::tools::createLevelSetSphere<openvdb::FloatGrid>(</div>
<div class="line"> <span class="comment">/*radius=*/</span>50.0, <span class="comment">/*center=*/</span><a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aad16c11fc989660440b62fc2853a8f9a">openvdb::Vec3f</a>(1.5, 2, 3),</div>
<div class="line"> <span class="comment">/*voxel size=*/</span>0.5, <span class="comment">/*width=*/</span>4.0);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Associate some metadata with the grid.</span></div>
<div class="line"> grid->insertMeta(<span class="stringliteral">"radius"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::FloatMetadata</a>(50.0));</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Name the grid "LevelSetSphere".</span></div>
<div class="line"> grid->setName(<span class="stringliteral">"LevelSetSphere"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Create a VDB file object.</span></div>
<div class="line"> openvdb::io::File file(<span class="stringliteral">"mygrids.vdb"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Add the grid pointer to a container.</span></div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aa7853474b8fa140799c730775f891aca">openvdb::GridPtrVec</a> grids;</div>
<div class="line"> grids.push_back(grid);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Write out the contents of the container.</span></div>
<div class="line"> file.write(grids);</div>
<div class="line"> file.close();</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="sPopulatingGrids"></a>
Populating a grid with values</h1>
<p>The following code is templated so as to operate on grids containing values of any scalar type, provided that the value type supports negation and comparison. Note that this algorithm is only meant as an example and should never be used in production; use the much more efficient routines in <a class="el" href="LevelSetSphere_8h.html" title="Generate a narrow-band level set of sphere. ">tools/LevelSetSphere.h</a> instead.</p>
<p>See <a class="el" href="codeExamples.html#sGenericProg">Generic programming</a> for more on processing grids of arbitrary type. <a class="anchor" id="makeSphereCode"></a></p>
<div class="fragment"><div class="line"><span class="comment">// Populate the given grid with a narrow-band level set representation of a sphere.</span></div>
<div class="line"><span class="comment">// The width of the narrow band is determined by the grid's background value.</span></div>
<div class="line"><span class="comment">// (Example code only; use tools::createSphereSDF() in production.)</span></div>
<div class="line"><span class="keyword">template</span><<span class="keyword">class</span> Gr<span class="keywordtype">id</span>Type></div>
<div class="line"><span class="keywordtype">void</span></div>
<div class="line">makeSphere(GridType& grid, <span class="keywordtype">float</span> radius, <span class="keyword">const</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html">openvdb::Vec3f</a>& c)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> GridType::ValueType ValueT;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Distance value for the constant region exterior to the narrow band</span></div>
<div class="line"> <span class="keyword">const</span> ValueT outside = grid.background();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Distance value for the constant region interior to the narrow band</span></div>
<div class="line"> <span class="comment">// (by convention, the signed distance is negative in the interior of</span></div>
<div class="line"> <span class="comment">// a level set)</span></div>
<div class="line"> <span class="keyword">const</span> ValueT inside = -outside;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Use the background value as the width in voxels of the narrow band.</span></div>
<div class="line"> <span class="comment">// (The narrow band is centered on the surface of the sphere, which</span></div>
<div class="line"> <span class="comment">// has distance 0.)</span></div>
<div class="line"> <span class="keywordtype">int</span> padding = int(<a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#aa1a8e9526bbb3d32caa2d52cbd4d29d0">openvdb::math::RoundUp</a>(<a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a39db44d7bbe88980d47cc4476f374265">openvdb::math::Abs</a>(outside)));</div>
<div class="line"> <span class="comment">// The bounding box of the narrow band is 2*dim voxels on a side.</span></div>
<div class="line"> <span class="keywordtype">int</span> dim = int(radius + padding);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Get a voxel accessor.</span></div>
<div class="line"> <span class="keyword">typename</span> GridType::Accessor accessor = grid.getAccessor();</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Compute the signed distance from the surface of the sphere of each</span></div>
<div class="line"> <span class="comment">// voxel within the bounding box and insert the value into the grid</span></div>
<div class="line"> <span class="comment">// if it is smaller in magnitude than the background value.</span></div>
<div class="line"> openvdb::Coord ijk;</div>
<div class="line"> <span class="keywordtype">int</span> &i = ijk[0], &j = ijk[1], &k = ijk[2];</div>
<div class="line"> <span class="keywordflow">for</span> (i = c[0] - dim; i < c[0] + dim; ++i) {</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">float</span> x2 = <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a0058077e35dc30591c9262c08f3c76d3">openvdb::math::Pow2</a>(i - c[0]);</div>
<div class="line"> <span class="keywordflow">for</span> (j = c[1] - dim; j < c[1] + dim; ++j) {</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">float</span> x2y2 = <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a0058077e35dc30591c9262c08f3c76d3">openvdb::math::Pow2</a>(j - c[1]) + x2;</div>
<div class="line"> <span class="keywordflow">for</span> (k = c[2] - dim; k < c[2] + dim; ++k) {</div>
<div class="line"></div>
<div class="line"> <span class="comment">// The distance from the sphere surface in voxels</span></div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">float</span> dist = <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a176851096165ca9aaffc2c18c9e03bd6">openvdb::math::Sqrt</a>(x2y2</div>
<div class="line"> + <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a0058077e35dc30591c9262c08f3c76d3">openvdb::math::Pow2</a>(k - c[2])) - radius;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Convert the floating-point distance to the grid's value type.</span></div>
<div class="line"> ValueT val = ValueT(dist);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Only insert distances that are smaller in magnitude than</span></div>
<div class="line"> <span class="comment">// the background value.</span></div>
<div class="line"> <span class="keywordflow">if</span> (val < inside || outside < val) <span class="keywordflow">continue</span>;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Set the distance for voxel (i,j,k).</span></div>
<div class="line"> accessor.setValue(ijk, val);</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Propagate the outside/inside sign information from the narrow band</span></div>
<div class="line"> <span class="comment">// throughout the grid.</span></div>
<div class="line"> grid.signedFloodFill();</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="sModifyingGrids"></a>
Reading and modifying a grid</h1>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a68e8673fb73be5d09f0cbc957b6a1293">openvdb::initialize</a>();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Create a VDB file object.</span></div>
<div class="line">openvdb::io::File file(<span class="stringliteral">"mygrids.vdb"</span>);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Open the file. This reads the file header, but not any grids.</span></div>
<div class="line">file.open();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Loop over all grids in the file and retrieve a shared pointer</span></div>
<div class="line"><span class="comment">// to the one named "LevelSetSphere". (This can also be done</span></div>
<div class="line"><span class="comment">// more simply by calling file.readGrid("LevelSetSphere").)</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1GridBase.html#ae5f073a322a4a562054f0b2506f48111">openvdb::GridBase::Ptr</a> baseGrid;</div>
<div class="line"><span class="keywordflow">for</span> (openvdb::io::File::NameIterator nameIter = file.beginName();</div>
<div class="line"> nameIter != file.endName(); ++nameIter)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Read in only the grid we are interested in.</span></div>
<div class="line"> <span class="keywordflow">if</span> (nameIter.gridName() == <span class="stringliteral">"LevelSetSphere"</span>) {</div>
<div class="line"> baseGrid = file.readGrid(nameIter.gridName());</div>
<div class="line"> } <span class="keywordflow">else</span> {</div>
<div class="line"> std::cout << <span class="stringliteral">"skipping grid "</span> << nameIter.gridName() << std::endl;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line">file.close();</div>
<div class="line"></div>
<div class="line"><span class="comment">// From the example above, "LevelSetSphere" is known to be a FloatGrid,</span></div>
<div class="line"><span class="comment">// so cast the generic grid pointer to a FloatGrid pointer.</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> grid = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Convert the level set sphere to a narrow-band fog volume, in which</span></div>
<div class="line"><span class="comment">// interior voxels have value 1, exterior voxels have value 0, and</span></div>
<div class="line"><span class="comment">// narrow-band voxels have values varying linearly from 0 to 1.</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">float</span> outside = grid->background();</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">float</span> width = 2.0 * outside;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Visit and update all of the grid's active values, which correspond to</span></div>
<div class="line"><span class="comment">// voxels on the narrow band.</span></div>
<div class="line"><span class="keywordflow">for</span> (<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#a489aa6fa35d5ee2842072babf80c7f0c">openvdb::FloatGrid::ValueOnIter</a> iter = grid->beginValueOn(); iter; ++iter) {</div>
<div class="line"> <span class="keywordtype">float</span> dist = iter.getValue();</div>
<div class="line"> iter.setValue((outside - dist) / width);</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Visit all of the grid's inactive tile and voxel values and update the values</span></div>
<div class="line"><span class="comment">// that correspond to the interior region.</span></div>
<div class="line"><span class="keywordflow">for</span> (<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aa3bfddcea0ca11dc312deb2d9b008111">openvdb::FloatGrid::ValueOffIter</a> iter = grid->beginValueOff(); iter; ++iter) {</div>
<div class="line"> <span class="keywordflow">if</span> (iter.getValue() < 0.0) {</div>
<div class="line"> iter.setValue(1.0);</div>
<div class="line"> iter.setValueOff();</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Set exterior voxels to 0.</span></div>
<div class="line">grid->setBackground(0.0);</div>
</div><!-- fragment --><h1><a class="anchor" id="sStreamIO"></a>
Stream I/O</h1>
<p>The <a class="el" href="classopenvdb_1_1v2__1__0_1_1io_1_1Stream.html">io::Stream</a> class allows grids to be written to and read from streams that do not support random access, with the restriction that all grids must be written or read at once. (With <a class="el" href="classopenvdb_1_1v2__1__0_1_1io_1_1File.html">io::File</a>, grids can be read individually by name, provided that they were originally written with <code>io::File</code>, rather than streamed to a file.)</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/io/Stream.h></span></div>
<div class="line"></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a68e8673fb73be5d09f0cbc957b6a1293">openvdb::initialize</a>();</div>
<div class="line"></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aab1ee9f1c00e75f96098bbad7a368bbc">openvdb::GridPtrVecPtr</a> grids(<span class="keyword">new</span> <a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aa7853474b8fa140799c730775f891aca">GridPtrVec</a>);</div>
<div class="line">grids->push_back(...);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Stream the grids to a string.</span></div>
<div class="line">std::ostringstream ostr(std::ios_base::binary);</div>
<div class="line">openvdb::io::Stream(ostr).write(*grids);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Stream the grids to a file.</span></div>
<div class="line">std::ofstream ofile(<span class="stringliteral">"mygrids.vdb"</span>, std::ios_base::binary);</div>
<div class="line">openvdb::io::Stream(ofile).write(*grids);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Stream in grids from a string.</span></div>
<div class="line"><span class="comment">// Note that io::Stream::getGrids() returns a shared pointer</span></div>
<div class="line"><span class="comment">// to an openvdb::GridPtrVec.</span></div>
<div class="line">std::istringstream istr(ostr.str(), std::ios_base::binary);</div>
<div class="line">openvdb::io::Stream strm(istr);</div>
<div class="line">grids = strm.getGrids();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Stream in grids from a file.</span></div>
<div class="line">std::ifstream ifile(<span class="stringliteral">"mygrids.vdb"</span>, std::ios_base::binary);</div>
<div class="line">grids = openvdb::io::Stream(ifile).getGrids();</div>
</div><!-- fragment --><h1><a class="anchor" id="sHandlingMetadata"></a>
Handling metadata</h1>
<p>Metadata of various types (string, floating point, integer, etc.—see <a class="el" href="metadata_2Metadata_8h.html">metadata/Metadata.h</a> for more) can be attached both to individual <code>Grid</code>s and to files on disk. The examples that follow refer to <code>Grid</code>s, but the usage is the same for the <a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html">MetaMap</a> that can optionally be supplied to a <a class="el" href="classopenvdb_1_1v2__1__0_1_1io_1_1File.html#a916750caa82c74d8ffdf5586392ecf18">file</a> or <a class="el" href="classopenvdb_1_1v2__1__0_1_1io_1_1Stream.html#a916750caa82c74d8ffdf5586392ecf18">stream</a> for writing.</p>
<h2><a class="anchor" id="sAddingMetadata"></a>
Adding metadata</h2>
<p>The <a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#a312ab36a22cbbc5a04fe512da74b8fd4">Grid::insertMeta()</a> method either adds a new (<em>name</em>, <em>value</em>) pair if the name is unique, or overwrites the existing value if the name matches an existing one. An existing value cannot be overwritten with a new value of a different type; the old metadata must be removed first. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::Vec3SGrid::Ptr</a> grid = <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#afed9748b2280ee9155aa1033cc583bc7">openvdb::Vec3SGrid::create</a>();</div>
<div class="line"></div>
<div class="line">grid->insertMeta(<span class="stringliteral">"vector type"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::StringMetadata</a>(<span class="stringliteral">"covariant (gradient)"</span>));</div>
<div class="line">grid->insertMeta(<span class="stringliteral">"radius"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::FloatMetadata</a>(50.0));</div>
<div class="line">grid->insertMeta(<span class="stringliteral">"center"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::Vec3SMetadata</a>(openvdb::Vec3S(10, 15, 10)));</div>
<div class="line"></div>
<div class="line"><span class="comment">// OK, overwrites existing value:</span></div>
<div class="line">grid->insertMeta(<span class="stringliteral">"center"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::Vec3SMetadata</a>(openvdb::Vec3S(10.5, 15, 30)));</div>
<div class="line"></div>
<div class="line"><span class="comment">// Error (throws openvdb::TypeError), can't overwrite a value of type Vec3S</span></div>
<div class="line"><span class="comment">// with a value of type float:</span></div>
<div class="line">grid->insertMeta(<span class="stringliteral">"center"</span>, <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::FloatMetadata</a>(0.0));</div>
</div><!-- fragment --><h2><a class="anchor" id="sGettingMetadata"></a>
Retrieving metadata</h2>
<p>Call <a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#a4ce926e6a516133e7d92ec5e86d4fbf5">Grid::metaValue()</a> to retrieve the value of metadata of a known type. For example, </p>
<div class="fragment"><div class="line">std::string s = grid->metaValue<std::string>(<span class="stringliteral">"vector type"</span>);</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">float</span> r = grid->metaValue<<span class="keywordtype">float</span>>(<span class="stringliteral">"radius"</span>);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Error (throws openvdb::TypeError), can't read a value of type Vec3S as a float:</span></div>
<div class="line"><span class="keywordtype">float</span> center = grid->metaValue<<span class="keywordtype">float</span>>(<span class="stringliteral">"center"</span>);</div>
</div><!-- fragment --><p><a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#aaffd4267064b4952be89781e5d077568">Grid::beginMeta()</a> and <a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#aaffd4267064b4952be89781e5d077568">Grid::beginMeta()</a> return STL <code>std::map</code> iterators over all of the metadata associated with a grid: </p>
<div class="fragment"><div class="line"><span class="keywordflow">for</span> (<a class="code" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#a1591b2f992798e6203a78ae2de3d09dd">openvdb::MetaMap::MetaIterator</a> iter = grid->beginMeta();</div>
<div class="line"> iter != grid->endMeta(); ++iter)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">const</span> std::string& name = iter->first;</div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Metadata.html#a95ed14273597421f00f70344b5df704e">openvdb::Metadata::Ptr</a> value = iter->second;</div>
<div class="line"> std::string valueAsString = value->str();</div>
<div class="line"> std::cout << name << <span class="stringliteral">" = "</span> << valueAsString << std::endl;</div>
<div class="line">}</div>
</div><!-- fragment --><p>If the type of the metadata is not known, use the <a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#a68d753337de4f85f9fa5cde7b916c102">index operator</a> to retrieve a shared pointer to a generic <a class="el" href="classopenvdb_1_1v2__1__0_1_1Metadata.html">Metadata</a> object, then query its type: </p>
<div class="fragment"><div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Metadata.html#a95ed14273597421f00f70344b5df704e">openvdb::Metadata::Ptr</a> metadata = grid[<span class="stringliteral">"center"</span>];</div>
<div class="line"></div>
<div class="line"><span class="comment">// See typenameAsString<T>() in Types.h for a list of strings that can be</span></div>
<div class="line"><span class="comment">// returned by the typeName() method.</span></div>
<div class="line">std::cout << metadata->typeName() << std::endl; <span class="comment">// prints "vec3s"</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// One way to process metadata of arbitrary types:</span></div>
<div class="line"><span class="keywordflow">if</span> (metadata->typeName() == <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#acf959bd7e94562323ed426e09721a789">openvdb::StringMetadata::staticTypeName</a>()) {</div>
<div class="line"> std::string s = <span class="keyword">static_cast<</span><a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::StringMetadata</a>&<span class="keyword">></span>(*metadata).<a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#ab49416ba38b750a3ac3a320185f5224f">value</a>();</div>
<div class="line">} <span class="keywordflow">else</span> <span class="keywordflow">if</span> (metadata->typeName() == <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#acf959bd7e94562323ed426e09721a789">openvdb::FloatMetadata::staticTypeName</a>()) {</div>
<div class="line"> <span class="keywordtype">float</span> f = <span class="keyword">static_cast<</span><a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::FloatMetadata</a>&<span class="keyword">></span>(*metadata).<a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#ab49416ba38b750a3ac3a320185f5224f">value</a>();</div>
<div class="line">} <span class="keywordflow">else</span> <span class="keywordflow">if</span> (metadata->typeName() == <a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#acf959bd7e94562323ed426e09721a789">openvdb::Vec3SMetadata::staticTypeName</a>()) {</div>
<div class="line"> openvdb::Vec3S v = <span class="keyword">static_cast<</span><a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html">openvdb::Vec3SMetadata</a>&<span class="keyword">></span>(*metadata).<a class="code" href="classopenvdb_1_1v2__1__0_1_1TypedMetadata.html#ab49416ba38b750a3ac3a320185f5224f">value</a>();</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="sRemovingMetadata"></a>
Removing metadata</h2>
<p><a class="el" href="classopenvdb_1_1v2__1__0_1_1MetaMap.html#a2138f847598edec8b5f1c91557abd6ba">Grid::removeMeta()</a> removes metadata by name. If the given name is not found, the call has no effect. </p>
<div class="fragment"><div class="line">grid->removeMeta(<span class="stringliteral">"vector type"</span>);</div>
<div class="line">grid->removeMeta(<span class="stringliteral">"center"</span>);</div>
<div class="line">grid->removeMeta(<span class="stringliteral">"vector type"</span>); <span class="comment">// OK (no effect)</span></div>
</div><!-- fragment --><h1><a class="anchor" id="sIteration"></a>
Iteration</h1>
<h2><a class="anchor" id="sNodeIterator"></a>
Node Iterator</h2>
<p>A <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#ac34433f7d2e2eb2d95fddef8e0b1d523">Tree::NodeIter</a> visits each node in a tree exactly once. In the following example, the tree is known to have a depth of 4; see the <a class="el" href="overview.html#treeNodeIterRef">Overview</a> for a discussion of why node iteration can be complicated when the tree depth is not known. There are techniques (beyond the scope of this Cookbook) for operating on trees of arbitrary depth. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="keyword">typedef</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a> GridType;</div>
<div class="line"><span class="keyword">typedef</span> GridType::TreeType TreeType;</div>
<div class="line"><span class="keyword">typedef</span> TreeType::RootNodeType RootType; <span class="comment">// level 3 RootNode</span></div>
<div class="line">assert(RootType::LEVEL == 3);</div>
<div class="line"><span class="keyword">typedef</span> RootType::ChildNodeType Int1Type; <span class="comment">// level 2 InternalNode</span></div>
<div class="line"><span class="keyword">typedef</span> Int1Type::ChildNodeType Int2Type; <span class="comment">// level 1 InternalNode</span></div>
<div class="line"><span class="keyword">typedef</span> TreeType::LeafNodeType LeafType; <span class="comment">// level 0 LeafNode</span></div>
<div class="line"></div>
<div class="line">GridType::Ptr grid = ...;</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">for</span> (TreeType::NodeIter iter = grid->tree().beginNode(); iter; ++iter) {</div>
<div class="line"> <span class="keywordflow">switch</span> (iter.getDepth()) {</div>
<div class="line"> <span class="keywordflow">case</span> 0: { RootType* node = NULL; iter.getNode(node); <span class="keywordflow">if</span> (node) ...; <span class="keywordflow">break</span>; }</div>
<div class="line"> <span class="keywordflow">case</span> 1: { Int1Type* node = NULL; iter.getNode(node); <span class="keywordflow">if</span> (node) ...; <span class="keywordflow">break</span>; }</div>
<div class="line"> <span class="keywordflow">case</span> 2: { Int2Type* node = NULL; iter.getNode(node); <span class="keywordflow">if</span> (node) ...; <span class="keywordflow">break</span>; }</div>
<div class="line"> <span class="keywordflow">case</span> 3: { LeafType* node = NULL; iter.getNode(node); <span class="keywordflow">if</span> (node) ...; <span class="keywordflow">break</span>; }</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="sLeafIterator"></a>
Leaf Node Iterator</h2>
<p>A <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#abd661fdeff6388ca9d64ee76b5dcbf8a">Tree::LeafIter</a> visits each leaf node in a tree exactly once. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="keyword">typedef</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a> GridType;</div>
<div class="line"><span class="keyword">typedef</span> GridType::TreeType TreeType;</div>
<div class="line"></div>
<div class="line">GridType::Ptr grid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Iterate over references to const LeafNodes.</span></div>
<div class="line"><span class="keywordflow">for</span> (TreeType::LeafCIter iter = grid->tree().cbeginLeaf(); iter; ++iter) {</div>
<div class="line"> <span class="keyword">const</span> TreeType::LeafNodeType& leaf = *iter;</div>
<div class="line"> ...</div>
<div class="line">}</div>
<div class="line"><span class="comment">// Iterate over references to non-const LeafNodes.</span></div>
<div class="line"><span class="keywordflow">for</span> (TreeType::LeafIter iter = grid->tree().beginLeaf(); iter; ++iter) {</div>
<div class="line"> TreeType::LeafNodeType& leaf = *iter;</div>
<div class="line"> ...</div>
<div class="line">}</div>
<div class="line"><span class="comment">// Iterate over pointers to const LeafNodes.</span></div>
<div class="line"><span class="keywordflow">for</span> (TreeType::LeafCIter iter = grid->tree().cbeginLeaf(); iter; ++iter) {</div>
<div class="line"> <span class="keyword">const</span> TreeType::LeafNodeType* leaf = iter.getLeaf();</div>
<div class="line"> ...</div>
<div class="line">}</div>
<div class="line"><span class="comment">// Iterate over pointers to non-const LeafNodes.</span></div>
<div class="line"><span class="keywordflow">for</span> (TreeType::LeafIter iter = grid->tree().beginLeaf(); iter; ++iter) {</div>
<div class="line"> TreeType::LeafNodeType* leaf = iter.getLeaf();</div>
<div class="line"> ...</div>
<div class="line">}</div>
</div><!-- fragment --><p> See the <a class="el" href="overview.html#treeLeafIterRef">Overview</a> for more on leaf node iterators.</p>
<h2><a class="anchor" id="sValueIterator"></a>
Value Iterator</h2>
<p>A <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a3679e9e0ab166205346c3aee0f853108">Tree::ValueIter</a> visits each <a class="el" href="overview.html#subsecValues">value</a> (both tile and voxel) in a tree exactly once. Iteration can be unrestricted or can be restricted to only active values or only inactive values. Note that tree-level value iterators (unlike the node iterators described above) can be accessed either through a grid's tree or directly through the grid itself, as in the following example: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="keyword">typedef</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3SGrid</a> GridType;</div>
<div class="line"><span class="keyword">typedef</span> GridType::TreeType TreeType;</div>
<div class="line"></div>
<div class="line">GridType::Ptr grid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Iterate over all active values but don't allow them to be changed.</span></div>
<div class="line"><span class="keywordflow">for</span> (GridType::ValueOnCIter iter = grid->cbeginValueOn(); iter.test(); ++iter) {</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html">openvdb::Vec3f</a>& value = *iter;</div>
<div class="line"></div>
<div class="line"> <span class="comment">// Print the coordinates of all voxels whose vector value has</span></div>
<div class="line"> <span class="comment">// a length greater than 10, and print the bounding box coordinates</span></div>
<div class="line"> <span class="comment">// of all tiles whose vector value length is greater than 10.</span></div>
<div class="line"> <span class="keywordflow">if</span> (value.<a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html#ac391672014f7b4faed37018787333e4b">length</a>() > 10.0) {</div>
<div class="line"> <span class="keywordflow">if</span> (iter.isVoxelValue()) {</div>
<div class="line"> std::cout << iter.getCoord() << std::endl;</div>
<div class="line"> } <span class="keywordflow">else</span> {</div>
<div class="line"> openvdb::CoordBBox bbox;</div>
<div class="line"> iter.getBoundingBox(bbox);</div>
<div class="line"> std::cout << bbox << std::endl;</div>
<div class="line"> }</div>
<div class="line"> } </div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Iterate over and normalize all inactive values.</span></div>
<div class="line"><span class="keywordflow">for</span> (GridType::ValueOffIter iter = grid->beginValueOff(); iter.test(); ++iter) {</div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html">openvdb::Vec3f</a> value = *iter;</div>
<div class="line"> value.<a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Vec3.html#ae37fa555d3e29bc5ee4b0c813f86f18d">normalize</a>();</div>
<div class="line"> iter.setValue(value);</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Normalize the (inactive) background value as well.</span></div>
<div class="line">grid->setBackground(grid->background().unit());</div>
</div><!-- fragment --><p> See the <a class="el" href="overview.html#treeValueIterRef">Overview</a> for more on value iterators.</p>
<h1><a class="anchor" id="sXformTools"></a>
Transforming grids</h1>
<h2><a class="anchor" id="sResamplingTools"></a>
Geometric transformation</h2>
<p>A <a class="el" href="classopenvdb_1_1v2__1__0_1_1tools_1_1GridTransformer.html">GridTransformer</a> applies a geometric transformation to an input grid using one of several sampling schemes, and stores the result in an output grid. The operation is multithreaded by default, though threading can be disabled by calling <a class="el" href="classopenvdb_1_1v2__1__0_1_1tools_1_1GridResampler.html#ac3fa2c9a94b6643ed5244fca102e11a8">setThreaded(false)</a>. A <code>GridTransformer</code> object can be reused to apply the same transformation to multiple input grids, optionally using different sampling schemes. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/GridTransformer.h></span></div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a></div>
<div class="line"> sourceGrid = ...</div>
<div class="line"> targetGrid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Get the source and target grids' index space to world space transforms.</span></div>
<div class="line"><span class="keyword">const</span> openvdb::math::Transform</div>
<div class="line"> &sourceXform = sourceGrid->transform(),</div>
<div class="line"> &targetXform = targetGrid->transform();</div>
<div class="line"><span class="comment">// Compute a source grid to target grid transform.</span></div>
<div class="line"><span class="comment">// (For this example, we assume that both grids' transforms are linear,</span></div>
<div class="line"><span class="comment">// so that they can be represented as 4 x 4 matrices.)</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Mat4.html">openvdb::Mat4R</a> xform =</div>
<div class="line"> sourceXform.baseMap()->getAffineMap()->getMat4() *</div>
<div class="line"> targetXform.baseMap()->getAffineMap()->getMat4().<a class="code" href="classopenvdb_1_1v2__1__0_1_1math_1_1Mat4.html#a26a6d7acc07d370764b895b848f846e0">inverse</a>();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Create the transformer.</span></div>
<div class="line">openvdb::tools::GridTransformer transformer(xform);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Resample using nearest-neighbor interpolation.</span></div>
<div class="line">transformer.transformGrid<openvdb::tools::PointSampler, <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a>>(</div>
<div class="line"> sourceGrid, *targetGrid);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Resample using trilinear interpolation.</span></div>
<div class="line">transformer.transformGrid<openvdb::tools::BoxSampler, <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a>>(</div>
<div class="line"> sourceGrid, *targetGrid);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Resample using triquadratic interpolation.</span></div>
<div class="line">transformer.transformGrid<openvdb::tools::QuadraticSampler, <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a>>(</div>
<div class="line"> sourceGrid, *targetGrid);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Prune the target tree for optimal sparsity.</span></div>
<div class="line">targetGrid-><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#a9041f381eeb1287165c1287603de9663">tree</a>().prune();</div>
</div><!-- fragment --><h2><a class="anchor" id="sValueXformTools"></a>
Value transformation</h2>
<p>This example uses <a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ada1c7e219f36d148510ce22d7599171b">tools::foreach()</a> to multiply all values (both tile and voxel and both active and inactive) of a scalar, floating-point grid by two: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/ValueTransformer.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a local function that doubles the value to which the given</span></div>
<div class="line"><span class="comment">// value iterator points.</span></div>
<div class="line"><span class="keyword">struct </span>Local {</div>
<div class="line"> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> op(<span class="keyword">const</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#a7881ea5e6b8538a65a17ef8d0abc3d78">openvdb::FloatGrid::ValueAllIter</a>& iter) {</div>
<div class="line"> iter.setValue(*iter * 2);</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> grid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Apply the function to all values.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ada1c7e219f36d148510ce22d7599171b">openvdb::tools::foreach</a>(grid->beginValueAll(), Local::op);</div>
</div><!-- fragment --><p>This example uses <a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ada1c7e219f36d148510ce22d7599171b">tools::foreach()</a> to rotate all active vectors of a vector-valued grid by 45 degrees about the <em>y</em> axis: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/ValueTransformer.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a functor that multiplies the vector to which the given</span></div>
<div class="line"><span class="comment">// value iterator points by a fixed matrix.</span></div>
<div class="line"><span class="keyword">struct </span>MatMul {</div>
<div class="line"> <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#aee0814e3251871e89dff147270c95f32">openvdb::math::Mat3s</a> M;</div>
<div class="line"> MatMul(<span class="keyword">const</span> <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#aee0814e3251871e89dff147270c95f32">openvdb::math::Mat3s</a>& mat): M(mat) {}</div>
<div class="line"> <span class="keyword">inline</span> <span class="keywordtype">void</span> operator()(<span class="keyword">const</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#a489aa6fa35d5ee2842072babf80c7f0c">openvdb::Vec3SGrid::ValueOnIter</a>& iter)<span class="keyword"> const </span>{</div>
<div class="line"> iter.setValue(M.transform(*iter));</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::Vec3SGrid::Ptr</a> grid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Construct the rotation matrix.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#aee0814e3251871e89dff147270c95f32">openvdb::math::Mat3s</a> rot45 =</div>
<div class="line"> openvdb::math::rotation<openvdb::math::Mat3s>(<a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#ae3996976d8ffb3e58d88f58227473f8eaa1ec9649c0a631b27ad7280af3522dd0">openvdb::math::Y_AXIS</a>, M_PI_4);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Apply the functor to all active values.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ada1c7e219f36d148510ce22d7599171b">openvdb::tools::foreach</a>(grid->beginValueOn(), MatMul(rot45));</div>
</div><!-- fragment --><p><a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ae870e81ce652b9c057d92dbe4b4b9811">tools::transformValues()</a> is similar to <a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ada1c7e219f36d148510ce22d7599171b">tools::foreach()</a>, but it populates an output grid with transformed values from an input grid that may have a different value type. The following example populates a scalar, floating-point grid with the lengths of all active vectors from a vector-valued grid (see also <a class="el" href="classopenvdb_1_1v2__1__0_1_1tools_1_1Magnitude.html">tools::Magnitude</a>): </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/ValueTransformer.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a local function that, given an iterator pointing to a vector value</span></div>
<div class="line"><span class="comment">// in an input grid, sets the corresponding tile or voxel in a scalar,</span></div>
<div class="line"><span class="comment">// floating-point output grid to the length of the vector.</span></div>
<div class="line"><span class="keyword">struct </span>Local {</div>
<div class="line"> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> op(</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#af73f7039c425b2517eb1772881d83ad4">openvdb::Vec3SGrid::ValueOnCIter</a>& iter,</div>
<div class="line"> openvdb::FloatGrid::ValueAccessor& accessor)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">if</span> (iter.isVoxelValue()) { <span class="comment">// set a single voxel</span></div>
<div class="line"> accessor.setValue(iter.getCoord(), iter->length());</div>
<div class="line"> } <span class="keywordflow">else</span> { <span class="comment">// fill an entire tile</span></div>
<div class="line"> openvdb::CoordBBox bbox;</div>
<div class="line"> iter.getBoundingBox(bbox);</div>
<div class="line"> accessor.getTree().fill(bbox, iter->length());</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#ab83a67bd13dbb481297e5d34545a6163">openvdb::Vec3SGrid::ConstPtr</a> inGrid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Create a scalar grid to hold the transformed values.</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> outGrid = <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#afed9748b2280ee9155aa1033cc583bc7">openvdb::FloatGrid::create</a>();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Populate the output grid with transformed values.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ae870e81ce652b9c057d92dbe4b4b9811">openvdb::tools::transformValues</a>(inGrid->cbeginValueOn(), *outGrid, Local::op);</div>
</div><!-- fragment --><h1><a class="anchor" id="sCombiningGrids"></a>
Combining grids</h1>
<p>The following examples show various ways in which a pair of grids can be combined in <a class="el" href="overview.html#subsecVoxSpace">index space</a>. The assumption is that index coordinates <img class="formulaInl" alt="$(i,j,k)$" src="form_51.png"/> in both grids correspond to the same physical, <a class="el" href="overview.html#subsecWorSpace">world space</a> location. When the grids have different transforms, it is usually necessary to first <a class="el" href="codeExamples.html#sResamplingTools">resample</a> one grid into the other grid's <a class="el" href="overview.html#subsecVoxSpace">index space</a>.</p>
<h2><a class="anchor" id="sCsgTools"></a>
Level set CSG operations</h2>
<p>The level set CSG functions in <a class="el" href="Composite_8h.html" title="Functions to efficiently perform various compositing operations on grids. ">tools/Composite.h</a> operate on pairs of grids of the same type, using sparse traversal for efficiency. These operations always leave the second grid empty. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/Composite.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Two grids of the same type containing level set volumes</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> gridA(...), gridB(...);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Save copies of the two grids; CSG operations always modify</span></div>
<div class="line"><span class="comment">// the A grid and leave the B grid empty.</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#ab83a67bd13dbb481297e5d34545a6163">openvdb::FloatGrid::ConstPtr</a></div>
<div class="line"> copyOfGridA = gridA->deepCopy(),</div>
<div class="line"> copyOfGridB = gridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Compute the union (A u B) of the two level sets.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#a63ca059a52fa4df11baa7f641a1e3611">openvdb::tools::csgUnion</a>(*gridA, *gridB);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Restore the original level sets.</span></div>
<div class="line">gridA = copyOfGridA->deepCopy();</div>
<div class="line">gridB = copyOfGridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Compute the intersection (A n B) of the two level sets.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#ac6851d766bae22bdff30bbc8f9167ab9">openvdb::tools::csgIntersection</a>(gridA, gridB);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Restore the original level sets.</span></div>
<div class="line">gridA = copyOfGridA->deepCopy();</div>
<div class="line">gridB = copyOfGridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Compute the difference (A / B) of the two level sets.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#a28a450f27165e0dbfa59e79652ae8ec4">openvdb::tools::csgDifference</a>(gridA, gridB);</div>
</div><!-- fragment --><h2><a class="anchor" id="sCompTools"></a>
Compositing operations</h2>
<p>Like the <a class="el" href="codeExamples.html#sCsgTools">CSG operations</a>, the compositing functions in <a class="el" href="Composite_8h.html" title="Functions to efficiently perform various compositing operations on grids. ">tools/Composite.h</a> operate on pairs of grids of the same type, and they always leave the second grid empty. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"><span class="preprocessor">#include <openvdb/tools/Composite.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Two grids of the same type</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> gridA = ..., gridB = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Save copies of the two grids; compositing operations always</span></div>
<div class="line"><span class="comment">// modify the A grid and leave the B grid empty.</span></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#ab83a67bd13dbb481297e5d34545a6163">openvdb::FloatGrid::ConstPtr</a></div>
<div class="line"> copyOfGridA = gridA->deepCopy(),</div>
<div class="line"> copyOfGridB = gridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// At each voxel, compute a = max(a, b).</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#acf57bff918cf1f0be98f38a9fa18cce6">openvdb::tools::compMax</a>(*gridA, *gridB);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Restore the original grids.</span></div>
<div class="line">gridA = copyOfGridA->deepCopy();</div>
<div class="line">gridB = copyOfGridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// At each voxel, compute a = min(a, b).</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#a6e06fdbb69917492f3706fd07ead8adb">openvdb::tools::compMin</a>(*gridA, *gridB);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Restore the original grids.</span></div>
<div class="line">gridA = copyOfGridA->deepCopy();</div>
<div class="line">gridB = copyOfGridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// At each voxel, compute a = a + b.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#aa6cbb5a769e8b017110c4a24fa84d248">openvdb::tools::compSum</a>(*gridA, *gridB);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Restore the original grids.</span></div>
<div class="line">gridA = copyOfGridA->deepCopy();</div>
<div class="line">gridB = copyOfGridB->deepCopy();</div>
<div class="line"></div>
<div class="line"><span class="comment">// At each voxel, compute a = a * b.</span></div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1tools.html#a731304db65a743a015a7591eebf1c835">openvdb::tools::compMul</a>(*gridA, *gridB);</div>
</div><!-- fragment --><h2><a class="anchor" id="sCombineTools"></a>
Generic combination</h2>
<p>The <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a11ca864d49b3df73bd482307bd800577">Tree::combine()</a> family of methods apply a user-supplied operator to pairs of corresponding values of two trees. These methods are efficient because they take into account the sparsity of the trees; they are not multithreaded, however.</p>
<p>This example uses the <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a11ca864d49b3df73bd482307bd800577">Tree::combine()</a> method to compute the difference between corresponding voxels of two floating-point grids: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a local function that subtracts two floating-point values.</span></div>
<div class="line"><span class="keyword">struct </span>Local {</div>
<div class="line"> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> diff(<span class="keyword">const</span> <span class="keywordtype">float</span>& a, <span class="keyword">const</span> <span class="keywordtype">float</span>& b, <span class="keywordtype">float</span>& result) {</div>
<div class="line"> result = a - b;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> aGrid = ..., bGrid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Compute the difference between corresponding voxels of aGrid and bGrid</span></div>
<div class="line"><span class="comment">// and store the result in aGrid, leaving bGrid empty.</span></div>
<div class="line">aGrid->tree().combine(bGrid->tree(), Local::diff);</div>
</div><!-- fragment --><p>Another <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a11ca864d49b3df73bd482307bd800577">Tree::combine()</a> example, this time using a functor to preserve state: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a functor that computes f * a + (1 - f) * b for pairs of</span></div>
<div class="line"><span class="comment">// floating-point values a and b.</span></div>
<div class="line"><span class="keyword">struct </span>Blend {</div>
<div class="line"> Blend(<span class="keywordtype">float</span> f): frac(f) {}</div>
<div class="line"> <span class="keyword">inline</span> <span class="keywordtype">void</span> operator()(<span class="keyword">const</span> <span class="keywordtype">float</span>& a, <span class="keyword">const</span> <span class="keywordtype">float</span>& b, <span class="keywordtype">float</span>& result)<span class="keyword"> const </span>{</div>
<div class="line"> result = frac * a + (1.0 - frac) * b;</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordtype">float</span> frac;</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> aGrid = ..., bGrid = ...;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Compute a = 0.25 * a + 0.75 * b for all corresponding voxels of</span></div>
<div class="line"><span class="comment">// aGrid and bGrid. Store the result in aGrid and empty bGrid.</span></div>
<div class="line">aGrid->tree().combine(bGrid->tree(), Blend(0.25));</div>
</div><!-- fragment --><p>The <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a71140d5e67f0fce2c7fe0ae119db9711">Tree::combineExtended()</a> method invokes a function of the form <code>void f(CombineArgs<T>& args)</code>, where the <a class="el" href="classopenvdb_1_1v2__1__0_1_1CombineArgs.html">CombineArgs</a> object encapsulates an <em>a</em> and a <em>b</em> value and their active states as well as a result value and its active state. In the following example, voxel values in floating-point <code>aGrid</code> are replaced with corresponding values from floating-point <code>bGrid</code> (leaving <code>bGrid</code> empty) wherever the <em>b</em> values are larger. The active states of any transferred values are preserved. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <openvdb/openvdb.h></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a local function that retrieves a and b values from a CombineArgs</span></div>
<div class="line"><span class="comment">// struct and then sets the result member to the maximum of a and b.</span></div>
<div class="line"><span class="keyword">struct </span>Local {</div>
<div class="line"> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a567891aeefe25ecb9b1729190c60e3d4">max</a>(CombineArgs<float>& args) {</div>
<div class="line"> <span class="keywordflow">if</span> (args.b() > args.a()) {</div>
<div class="line"> <span class="comment">// Transfer the B value and its active state.</span></div>
<div class="line"> args.setResult(args.b());</div>
<div class="line"> args.setResultIsActive(args.bIsActive());</div>
<div class="line"> } <span class="keywordflow">else</span> {</div>
<div class="line"> <span class="comment">// Preserve the A value and its active state.</span></div>
<div class="line"> args.setResult(args.a());</div>
<div class="line"> args.setResultIsActive(args.aIsActive());</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> aGrid = ..., bGrid = ...;</div>
<div class="line"></div>
<div class="line">aGrid->tree().combineExtended(bGrid->tree(), <a class="code" href="namespaceopenvdb_1_1v2__1__0_1_1math.html#a567891aeefe25ecb9b1729190c60e3d4">Local::max</a>);</div>
</div><!-- fragment --><p>Like <code><a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools_1_1internal.html#a6413f5042a30ff406f1ef4a21bdc567d">combine()</a></code>, <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a50b357a64382c90012d0ba23766b155e">Tree::combine2()</a> applies an operation to pairs of corresponding values of two trees. However, <code>combine2()</code> writes the result to a third, output tree and does not modify either of the two input trees. (As a result, it is less space-efficient than the <code><a class="el" href="namespaceopenvdb_1_1v2__1__0_1_1tools_1_1internal.html#a6413f5042a30ff406f1ef4a21bdc567d">combine()</a></code> method.) Here, the voxel differencing example above is repeated using <code>combine2()</code>: </p>
<div class="fragment"><div class="line"><span class="preprocessor"> #include</span></div>
<div class="line"><span class="preprocessor"></span><openvdb/openvdb.h></div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>Local {</div>
<div class="line"> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> diff(<span class="keyword">const</span> <span class="keywordtype">float</span>& a, <span class="keyword">const</span> <span class="keywordtype">float</span>& b, <span class="keywordtype">float</span>& result) {</div>
<div class="line"> result = a - b;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#ab83a67bd13dbb481297e5d34545a6163">openvdb::FloatGrid::ConstPtr</a> aGrid = ..., bGrid = ...;</div>
<div class="line"><a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::FloatGrid::Ptr</a> resultGrid = <a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#afed9748b2280ee9155aa1033cc583bc7">openvdb::FloatGrid::create</a>();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Combine aGrid and bGrid and write the result into resultGrid.</span></div>
<div class="line"><span class="comment">// The input grids are not modified.</span></div>
<div class="line">resultGrid->tree().combine2(aGrid->tree(), bGrid->tree(), Local::diff);</div>
</div><!-- fragment --><p> An <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a4db85c99e2daf1e93fa6ed213e7ceb78">extended combine2()</a> is also available.</p>
<h1><a class="anchor" id="sGenericProg"></a>
Generic programming</h1>
<h2><a class="anchor" id="sTypedGridMethods"></a>
Calling Grid methods</h2>
<p>A common task is to perform some operation on all of the grids in a file, where the operation involves <a class="el" href="classopenvdb_1_1v2__1__0_1_1Grid.html">Grid</a> method calls and the grids are of different types. Only a handful of <code>Grid</code> methods, such as <a class="el" href="classopenvdb_1_1v2__1__0_1_1Grid.html#a5a6a7cd039e1524a3b0a91c8e489970d">activeVoxelCount()</a>, are virtual and can be called through a <a class="el" href="classopenvdb_1_1v2__1__0_1_1GridBase.html">GridBase</a> pointer; most are not, because they require knowledge of the <code>Grid</code>'s value type. For example, one might want to <a class="el" href="classopenvdb_1_1v2__1__0_1_1tree_1_1Tree.html#a462c7056adc55d8da2cc5828934ff859">prune()</a> the trees of all of the grids in a file regardless of their type, but <code>Tree::prune()</code> is non-virtual because it accepts an optional pruning tolerance argument whose type is the grid's value type.</p>
<p>The <code>processTypedGrid()</code> function below makes this kind of task easier. It is called with a <code>GridBase</code> pointer and a functor whose call operator accepts a pointer to a <code>Grid</code> of arbitrary type. The call operator should be templated on the grid type and, if necessary, overloaded for specific grid types.</p>
<div class="fragment"><div class="line"><span class="keyword">template</span><<span class="keyword">typename</span> OpType></div>
<div class="line"><span class="keywordtype">void</span> processTypedGrid(<a class="code" href="classopenvdb_1_1v2__1__0_1_1GridBase.html#ae5f073a322a4a562054f0b2506f48111">openvdb::GridBase::Ptr</a> grid, OpType& op)</div>
<div class="line">{</div>
<div class="line"><span class="preprocessor">#define CALL_OP(GridType) \</span></div>
<div class="line"><span class="preprocessor"> op.template operator()<GridType>(openvdb::gridPtrCast<GridType>(grid))</span></div>
<div class="line"><span class="preprocessor"></span></div>
<div class="line"> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::BoolGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::BoolGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::FloatGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::DoubleGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::DoubleGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Int32Grid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Int32Grid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Int64Grid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Int64Grid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3IGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3IGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3SGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3SGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3DGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::Vec3DGrid</a>);</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (grid->isType<<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::StringGrid</a>>()) CALL_OP(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html">openvdb::StringGrid</a>);</div>
<div class="line"></div>
<div class="line"><span class="preprocessor">#undef CALL_OP</span></div>
<div class="line"><span class="preprocessor">}</span></div>
</div><!-- fragment --><p>The following example shows how to use <code>processTypedGrid()</code> to implement a generic pruning operation for grids of all built-in types: </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include <<a class="code" href="openvdb_8h.html">openvdb.h</a>></span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Define a functor that prunes the trees of grids of arbitrary type</span></div>
<div class="line"><span class="comment">// with a fixed pruning tolerance.</span></div>
<div class="line"><span class="keyword">struct </span>PruneOp {</div>
<div class="line"> <span class="keywordtype">double</span> tolerance;</div>
<div class="line"> PruneOp(<span class="keywordtype">double</span> t): tolerance(t) {}</div>
<div class="line"></div>
<div class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> Gr<span class="keywordtype">id</span>Type></div>
<div class="line"> <span class="keywordtype">void</span> operator()(<span class="keyword">typename</span> GridType::Ptr grid)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> grid->tree().prune(<span class="keyword">typename</span> GridType::ValueType(tolerance));</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// Overload to handle string-valued grids</span></div>
<div class="line"> <span class="keywordtype">void</span> operator()(<a class="code" href="classopenvdb_1_1v2__1__0_1_1Grid.html#aac96d633d8cebcf0f08aa67d3e690dae">openvdb::StringGrid::Ptr</a> grid)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> grid->tree().prune();</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="comment">// Read all grids from a file.</span></div>
<div class="line">openvdb::io::File file(<span class="stringliteral">"mygrids.vdb"</span>);</div>
<div class="line">file.open();</div>
<div class="line"><a class="code" href="namespaceopenvdb_1_1v2__1__0.html#aab1ee9f1c00e75f96098bbad7a368bbc">openvdb::GridPtrVecPtr</a> myGrids = file.getGrids();</div>
<div class="line">file.close();</div>
<div class="line"></div>
<div class="line"><span class="comment">// Prune each grid with a tolerance of 1%.</span></div>
<div class="line"><span class="keyword">const</span> PruneOp pruner(<span class="comment">/*tolerance=*/</span>0.01);</div>
<div class="line"><span class="keywordflow">for</span> (<a class="code" href="namespaceopenvdb_1_1v2__1__0.html#a492eebbb69bb00db9ebb2bf7f2bc24ea">openvdb::GridPtrVecIter</a> iter = myGrids->begin();</div>
<div class="line"> iter != myGrids->end(); ++iter)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="classopenvdb_1_1v2__1__0_1_1GridBase.html#ae5f073a322a4a562054f0b2506f48111">openvdb::GridBase::Ptr</a> grid = *iter;</div>
<div class="line"> processTypedGrid(grid, pruner);</div>
<div class="line">}</div>
</div><!-- fragment --> </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>
|