Compare commits

...
Author SHA1 Message Date
Jonathan Swartz 4725d8b20e Merge pull request #2120 from swahtz/fvdb_new_repo
Redirect to new fVDB repositories
2025-10-24 18:41:36 -04:00
Jonathan Swartz 227cfbab61 Remove all but a README pointing to fVDB's new home in https://github.com/openvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-10-24 09:31:29 +13:00
Jonathan Swartz 3fad26296f Merge pull request #2052 from swahtz/feature/fvdb
Update feature/fvdb
2025-06-17 11:34:07 +12:00
Jonathan Swartz a41e9319aa Merge remote-tracking branch 'downstream/feature/fvdb' into feature/fvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-17 11:32:37 +12:00
Jonathan SwartzandMark Harris 1563730c0a GaussianRasterizeForward shared memory calculation fix (#539)
* Fix for shared memory calculation to account for Gaussian2D alignment

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Mark Harris <mharris@nvidia.com>
2025-06-17 11:27:07 +12:00
Andrew 6fd95083d4 Unify editor shaders. 2025-06-16 10:10:18 -05:00
Petra Hapalova 3cc26291ca NanoVDB editor - track shader includes changes (#540)
* track shader includes changes
* clear shader cache button
2025-06-16 14:13:24 +00:00
Petra HapalovaandAndrew Reidmeyer 9f08f33fe6 Merge NanoVDB editor into fVDB (#534)
* adding NanoVDB Editor
---------

Co-authored-by: Andrew Reidmeyer <areidmeyer@nvidia.com>
2025-06-13 22:32:43 +02:00
Jonathan Swartz 0741614991 Merge pull request #2050 from swahtz/feature/fvdb
feature/fvdb update
2025-06-13 18:01:58 +12:00
Jonathan Swartz 0de6bf111a Merge remote-tracking branch 'downstream/feature/fvdb' into feature/fvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-13 17:57:56 +12:00
Jonathan Swartz 216ef435fc Improve launch_bounds coverage (#530)
* Improve launch_bounds coverage everywhere there's an easily inferred number of threads
* Add a global DEFAULT_NUM_THREADS_PER_BLOCK and made sure all kernels use GET_BLOCKS

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-13 17:54:36 +12:00
Jonathan Swartz 07a099136c Fix an issue where the PCA performed by the ColmapDataset in 3dgs was non-deterministic when using numpy built with OpenBLAS. Substitute for MKL blas. (#531)
Fix README error

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-12 16:55:30 +12:00
Jonathan Swartz 504fa0fcdf Added up_axis controls to 3dgs Viser viewer (#532)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-12 16:55:21 +12:00
Matthew Cong 3a260e0374 Remove compile_commands.json symlink and add to .gitignore (#520)
* Remove compile_commands.json
* Add compile_commands.json symlink to .gitignore

Signed-off-by: Mark Harris mharris@nvidia.com
2025-06-11 10:40:59 +10:00
Mark Harris 4963380b23 Store image dims in input data sets, use in gtests (#518)
Adds image dims to the test data generation for forward gsplat rasterization. uses this in gtests. Adds a new script for inspecting generated datasets. Updates test data commit hash in cmake.

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-11 10:36:33 +10:00
Jonathan Swartz 8ad3e9ba75 Add camera images to gsplat viser viewer (#514)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-10 19:15:19 +12:00
Mark Harris 8ce1fca72e Add debug build option to build.sh (#515)
* build.sh: add debug build option

* Auto update compile_commands.json symlink
2025-06-10 19:03:59 +12:00
Mark Harris d871dc46d3 Move implementation of tensor loading utilities to .cpp file, inline other utilities in headers. (#516)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-10 19:01:08 +12:00
Mark Harris 9e3b691e2a Seaube clang-format extension requries env.VAR rather than env:VAR (#517)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-10 18:58:00 +12:00
Matthew Cong 74581cdc6b Use PIMPL idiom for GridBatch/GridBatchImpl (#513)
* WIP: Use PIMPL idiom for GridBatch/GridBatchImpl

* Expose remaining sparse conv functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove variants of GridBatch::to(...)

* Remove address()

* Refactor Python bindings

* Restore address

* Remove implementations from header files

* Clean up API more

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-06-09 16:09:19 -07:00
Matthew Cong 9c537c776e Remove unused RAIIDeviceBuffer includes (#511) 2025-06-05 08:45:28 -07:00
Matthew Cong 938e02b5d6 Remove RAIIDeviceGuard (#510) 2025-06-05 08:45:19 -07:00
Matthew Cong d51a25714f Remove NanoVDBFileGridIdentifier union type (#505)
* Remove NanoVDBFileGridIdentifier from Python API

* Format

* Remove NanoVDBFileGridIdentifier from C++ API

* Expose parseDeviceString

* Centralize device string overloads to Python bindings
2025-06-05 07:01:16 -04:00
Mark Harris 24aa6d706b Use unique_ptr in RAIIDeviceGuard (#509)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-05 06:55:17 -04:00
Jonathan Swartz 010cbd9b5c Merge pull request #2049 from swahtz/feature/fvdb
feature/fvdb update
2025-06-05 21:44:57 +12:00
Mark Harris d6b2f243d3 Use Seaube.clangFormat vscode extension for clang-format (#508)
We have been getting intermittent crashes of clangd, and since we have been using the clang-format that is built into the clangd server, when clangd crashes we lose the format-on-save capability of vscode for C++ and CUDA C++ files.

This PR adds settings and recommendation for the vscode extension Seaube.clangFormat which allows specifying a clang-format executable to be used for formatting C++ and CUDA C++ files. This is a fork of the more widely used xaver.clang-format vscode extension because the latter has not released an update in years, in spite of having merged NVIDIA pull requests to support the cuda-cpp language.

After merging, you will need to make sure to install the vscode extension Seaube.clangFormat. VSCode will prompt to install it.

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-05 18:13:48 +12:00
Matthew Cong 32aac9e6e4 Remove JaggedTensorIndex union type (#503)
* Remove JaggedTensorIndex union type

* Fix error type

* Fix error type again

* Restore accidentally commented import
2025-06-04 21:58:27 -07:00
Mark Harris 7e0e66645d Add verbose option to build.sh, use it in CI workflow, add build.sh help (#507)
Add `verbose` option to build.sh and use it in CI.  Add -h/--help
---------
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-05 12:42:11 +10:00
Francis Williams 6221f03a83 Move voxel size and bounding box functions into GridBatchImpl (#500)
* more gridbatch slimming

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more slimming

Signed-off-by: Francis Williams <francis@fwilliams.info>

* even more slimming

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more deviceguard cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more deviceguard

Signed-off-by: Francis Williams <francis@fwilliams.info>

* naming convention

Signed-off-by: Francis Williams <francis@fwilliams.info>

* address more comments

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more thinning

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more lean, and commetns

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-06-04 21:10:44 -04:00
Jonathan Swartz 64ceb23374 Merge remote-tracking branch 'downstream/feature/fvdb' into feature/fvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-06-05 11:18:44 +12:00
Mark Harris ca9ff4a4ee Add CUDA attribute formatting and kernel launch bounds improvements (#498)
* Add AttributeMacros to .clang-format for CUDA attributes

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Reformat source for CUDA attributes, add launch bounds to some 3DGS kernels

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Update script for running clang-format

Signed-off-by: Mark Harris <mharris@nvidia.com>

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-04 13:06:48 -04:00
Matthew Cong 278a3ae8c9 Remove unused definitions which have moved into GridBatchImpl (#502) 2025-06-04 13:06:17 -04:00
Matthew Cong c95e422243 Remove Tensor -> JaggedTensor typecaster in favor of implicit conversion (#501) 2025-06-04 13:06:07 -04:00
Eftychios Sifakis 3d36ec7e99 Added grid merging functionality to fVDB (#494)
* Initial steps for grid merging routine

* cleanup and completion of root node merge

* completed enumeration of nodes on merge operation

* finished MergeGrids operation; cleanup

* Exposed MergeGrids in fVDB

* formatting fixes

* formatting fixes

* formatting fixes
2025-06-04 10:13:38 -04:00
Mark Harris 64c8d65333 Fix spherical harmonic tensor shapes in test data generation script (#497)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-04 15:08:00 +12:00
Mark Harris bb8dda8987 Update VSCode settings for CUDA support and clean up C++ file associations (#496)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-06-04 13:57:58 +12:00
Matthew Cong bdc38eb961 Cleanup unneeded includes (#495) 2025-06-03 11:06:45 -07:00
Christopher Horvath 6ab2ed501a fvdb source location restructure (#490)
Refactor: move of fvdb library sources to src/fvdb, update includes and .clang-format rules.

---------

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>
2025-06-03 15:11:51 +10:00
Francis Williams 624b227afa Move more grid building functions from GridBatch into detail (#477)
* build grid

Signed-off-by: Francis Williams <francis@fwilliams.info>

* unskip test

Signed-off-by: Francis Williams <francis@fwilliams.info>

* check device for optionals

Signed-off-by: Francis Williams <francis@fwilliams.info>

* pull out grid building code into seperate module

Signed-off-by: Francis Williams <francis@fwilliams.info>

* cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more migration

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* another one

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* move to GridBatchImpl

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clang fmt

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm write accessor

Signed-off-by: Francis Williams <francis@fwilliams.info>

* need writeaccessor

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

* update

Signed-off-by: Francis Williams <francis@fwilliams.info>

* cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* move to static

Signed-off-by: Francis Williams <francis@fwilliams.info>

* typo

Signed-off-by: Francis Williams <francis@fwilliams.info>

* typo 2

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rename

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rename

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rename

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-06-02 19:18:06 +00:00
Matthew Cong 533cf4c20e Restore mGPU support for createGridFromPoints/IJK (#489) 2025-06-02 12:07:26 -07:00
Matthew Cong 22de0d9aca Fix build error (#488) 2025-05-30 21:06:34 -04:00
zlalena 384198f3ee Gaussian Splatting Camera Pose Optimization with multiGPU (#422) 2025-05-30 20:18:18 -04:00
Matthew Cong 4213aa354a Re-enable warning as errors (#484)
* Fix class-memaccess warning in CreateNanoGrid.h

* Revert "comment out Werr (#464)"

This reverts commit c760c1ccbe.
2025-05-30 17:57:58 -04:00
Francis Williams f4ef228672 re-enable test (#486)
Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-30 21:19:16 +00:00
Francis Williams 5b011d23c4 Move grid building logic and error checking out of GridBatch into detail (#476)
* build grid

Signed-off-by: Francis Williams <francis@fwilliams.info>

* unskip test

Signed-off-by: Francis Williams <francis@fwilliams.info>

* check device for optionals

Signed-off-by: Francis Williams <francis@fwilliams.info>

* pull out grid building code into seperate module

Signed-off-by: Francis Williams <francis@fwilliams.info>

* cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

Signed-off-by: Francis Williams <francis@fwilliams.info>

* move to GridBatchImpl

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clang fmt

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm write accessor

Signed-off-by: Francis Williams <francis@fwilliams.info>

* need writeaccessor

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

* skip test again

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-30 21:12:48 +00:00
Matthew Cong 05b2bf6f11 Fix one more warning (#481) 2025-05-29 21:51:40 -07:00
Matthew Cong cde4160d42 Fix newly introduced warnings in fVDB (#480) 2025-05-29 16:50:19 -07:00
Matthew Cong 1b29548661 Add initial support for Unified Memory backend (#460)
* Add initial support for Unified Memory

* Add MGPU support for transform points

* Cleanup

* Add guard for CUDA version

* Add cudamanaged support for JOffsetsFromJIdx and PointsInGrid

* Fixes for signed/unsigned warnings

* Rename for consistency

* Remove hardcoded launch bounds

* Internalize numThreads to forEach kernels

* Rename macro to explicitly call out backends

* Clean up signed/unsigned indexing and reduce default block size

* Clean up macro

* Format code

* Remove unnecessary includes

* Address some review comments

* Fix helper function and formatting

* Encapsulate allocation logic
2025-05-29 15:11:43 -07:00
Francis Williams a414cef4c5 Don't use verbosity 1 in dilation and restore dilation in ray marching tests (#475)
* small clangd fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

* Don't use verbosity 1 in dilation and restore previously crashing dilation in test_ray_marching.py

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-29 14:17:52 +00:00
Francis Williams 55d80ce33d small clangd fix (#474)
Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-29 14:11:17 +00:00
Eftychios Sifakis 87ce3b6c71 Adding support for dilation operations that generate new root nodes (#473)
* Bugfix: consistent passing of stream parameter & synchronization

* using cub::WarpReduce instead of sm80 intrinsic

* replacing sm80+ intrinsic with cub::WarpReduce

* Supporting dilation scenarios that create new root nodes
2025-05-29 09:32:33 -04:00
Francis WilliamsandMatthew Cong c875c46a20 Remove mutable grids from internal API (#462)
* grid dilation in fVDB

Signed-off-by: Francis Williams <francis@fwilliams.info>

* SPDX

Signed-off-by: Francis Williams <francis@fwilliams.info>

* start removing pad args

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm mutable grids from public API

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more nuking

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix comments

Signed-off-by: Francis Williams <francis@fwilliams.info>

* Fix CI failures due to dilation (#454)

* Remove unneeded atomic include (#451)

* Add minor cleanup (#452)

* move dilate to ops

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more mutable reference removal

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fine from coarse

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* mas cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm all of build directory

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clean up build kernels

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

* checkpoint

* rm prints

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm macros

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm custom accessors

Signed-off-by: Francis Williams <francis@fwilliams.info>

* comment out Werr

* clang format

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clang format after downgrade to 18

Signed-off-by: Francis Williams <francis@fwilliams.info>

* small fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

* use OnIndexGrid instead of NanoGrid<...>

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
Co-authored-by: Matthew Cong <1372750+matthewdcong@users.noreply.github.com>
2025-05-29 09:29:45 -04:00
Francis Williams 88b69a968b Remove allocate/free functions from GridBatchImpl header (#471)
* clean up header

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm if

Signed-off-by: Francis Williams <francis@fwilliams.info>

* herp derp

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-28 20:15:56 -07:00
Matthew Cong 782c0c403e Merge pull request #470 from matthewdcong/develop_fvdb_merge
Merge latest develop into feature/fvdb
2025-05-28 09:52:06 -07:00
Francis WilliamsandMatthew Cong 8162fb42fe Remove mutable grids from public API (#461)
* grid dilation in fVDB

Signed-off-by: Francis Williams <francis@fwilliams.info>

* SPDX

Signed-off-by: Francis Williams <francis@fwilliams.info>

* start removing pad args

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm mutable grids from public API

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more nuking

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix comments

Signed-off-by: Francis Williams <francis@fwilliams.info>

* Fix CI failures due to dilation (#454)

* Remove unneeded atomic include (#451)

* Add minor cleanup (#452)

* move dilate to ops

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more mutable reference removal

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fine from coarse

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* mas cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* more cleanup

Signed-off-by: Francis Williams <francis@fwilliams.info>

* rm all of build directory

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clean up build kernels

Signed-off-by: Francis Williams <francis@fwilliams.info>

* include guards

* comment out Werr

* fix clangd crash

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix tests for now

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
Co-authored-by: Matthew Cong <1372750+matthewdcong@users.noreply.github.com>
2025-05-28 12:40:05 -04:00
Matthew Cong d1b970b688 Merge branch 'develop' into develop_fvdb_merge 2025-05-28 08:18:17 -07:00
Francis Williams 38c078a773 Fix clangd crash in GridBatchImpl (#469)
* fix clangd crash

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-28 14:44:28 +00:00
Matthew Cong d02dc930f0 Fixes for signed/unsigned warnings (#465) 2025-05-27 16:05:03 -07:00
Francis Williams c760c1ccbe comment out Werr (#464) 2025-05-27 12:40:04 -07:00
Mark Harris 07993354a7 Warnings are Errors (#437)
This PR fixes all current warnings in fVDB. The goal is that by default, the build should only print messages when there is something wrong. It is quiet by default and there are no warnings.

 -  Fixes existing warnings that occur without -Wall
 - Fixes additional (many more) warnings that occur with -Wall. Mostly signed/unsigned comparisons and unused variables.
 - Enables -Wall -Werror for CXX options
 - Enables -Werror=all-warnings -XCompiler=-Wall,-Werror for CUDA options.
 - Disables a bunch of #pragma message output by default
 - Makes the build quiet by default rather than verbose.

Once this is merged, compilation will fail if there are any warnings.

To do a verbose build now, add -v for verbose pip output, and -C build.verbose=true for verbose CMake output (print every compilation command line).

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-05-27 13:08:53 +10:00
Eftychios Sifakis f5b68239b1 Bug fixes in DilateGrid (#458)
* Bugfix: consistent passing of stream parameter & synchronization

* using cub::WarpReduce instead of sm80 intrinsic

* replacing sm80+ intrinsic with cub::WarpReduce
2025-05-23 17:18:44 -04:00
Matthew Cong 712839bed5 Move tensorBytePointer into GaussianSplatting TU (#459) 2025-05-23 11:05:41 -07:00
Matthew Cong 8fb305aa28 Add minor cleanup (#452) 2025-05-23 09:47:22 -04:00
Matthew Cong 49ca5c2a7a Remove unneeded atomic include (#451) 2025-05-23 09:46:55 -04:00
Matthew Cong 7b0f8bf685 Fix CI failures due to dilation (#454) 2025-05-22 22:47:52 -07:00
Francis Williams 2009f7da08 Integrate new dilation into fvdb GridBatch (#447)
* grid dilation in fVDB

Signed-off-by: Francis Williams <francis@fwilliams.info>

* SPDX

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-22 14:03:15 -04:00
Mark Harris d6a68d1ef3 Clang-format: disable bin packing and other improvements. (#434)
* Improve clang-format settings and .clang-format organization

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-05-22 14:07:22 +10:00
Eftychios Sifakis 063b4b9bee Morphological dilation in NanoVDB (#420)
This new feature provides a device-accelerated process for computing a morphological dilation of a NanoVDB IndexGrid.
3 modes of dilation are supported (see NearestNeighbors in util/MorphologyHelpers.h):
NN_FACE (6-connected); NN_FACE_EDGE (18-connected); NN_FACE_EDGE_VERTEX (26-connected).

Known limitation: As of right now (easily fixable when we have a real-world test case), the operation will proceed correctly only if the dilation operation does not create any new ROOT (4096^3) node.

An example of use can be found in examples/ex_dilate_nanovdb_cuda, which dilates an OpenVDB .vdb file, and compares the result against the NanoVDB/CUDA new implementation.
2025-05-21 14:00:26 -05:00
Mark Harris 0987d220ba Rename AccessorHelpers.h to AccessorHelpers.cuh (#436)
The file AccessorHelpers.h added in #432 is only included from .cu source files, and clangd reports problems because some of the types it uses are only defined when compiling CUDA code. So it's better to make this a CUDA header (.cuh). This PR renames it and updates all includes.

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-05-21 15:35:14 +10:00
Matthew Cong 005cd8fc48 Modularize functionality in Utils.cuh (#432)
* Separate countEnabledPerLeaf

* Separate forEachCUDA functions from Utils.cuh

* Separate out forEachCPU calls

* Separate out Accessor helper functions

* Remove PrivateUse1

* Rename
2025-05-20 08:41:26 -07:00
Matthew Cong ecbc9ff68f Replace Torch type <-> string functions with PyTorch built-ins (#429)
* Replace Torch type <-> string functions with PyTorch built-ins

* Revert "Replace Torch type <-> string functions with PyTorch built-ins"

This reverts commit 2e9e43515af924459cf48875ebd75698efecf0b9.

* Use PyTorch built-ins in later versions
2025-05-19 16:01:28 -04:00
Matthew Cong d79383c194 Separate RAII device buffer from forEach macros (#431)
* Separate RAII device buffer from forEach macros

* Fix header guard
2025-05-19 12:57:41 -07:00
Matthew Cong 66013466c3 Replace c10::optional with std::optional (#430) 2025-05-19 14:50:31 -04:00
Francis Williams c70b3dbac4 Jagged Tensor squeeze (#423) 2025-05-16 19:03:22 -04:00
Matthew Cong 6545a4b620 Cleanup accessor utility functions using std::conditional (#427) 2025-05-16 15:49:00 -07:00
Matthew Cong e8ea08db78 Fix test_gsplat formatting which is breaking CI (#428) 2025-05-16 14:47:15 -07:00
j-nordling 5a741ae46f bugfix: save nan splat (#426) 2025-05-16 17:25:01 -04:00
Francis Williams 8dba107547 Add optional stream and shared memory arguments to forEachVoxelCUDA/etc. (#416)
* streams and shared memory in forEachXXX

Signed-off-by: Francis Williams <francis@fwilliams.info>

* overload

Signed-off-by: Francis Williams <francis@fwilliams.info>

* option to call callback everytime

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-16 11:23:26 -04:00
Jonathan Swartz 9e531b0a16 Merge pull request #2045 from swahtz/fvdb_update 2025-05-15 16:28:37 +12:00
Matthew Cong c2eb7e6ce3 Switch to modern AT_DISPATCH_V2 macro (#402) 2025-05-14 15:24:53 -07:00
Matthew Cong cba1da5961 Merge pull request #406 from matthewdcong/develop_fvdb_merge
Redo develop to feature/fvdb merge to account for squashing changes
2025-05-14 10:22:05 -07:00
Matthew Cong b0b26884a1 Merge remote-tracking branch 'upstream/develop' into feature/fvdb 2025-05-14 10:19:00 -07:00
e5d9c13b5d Merge latest develop into feature/fvdb (#405)
* Merge latest master into develop (#394)

* Avoid unnecessary and expensive getLastWriteTime calls for memory mapped files on windows

Signed-off-by: jjtParadox <jturner@4nsi.com>

* Add [[nodiscard]] to confusing math functions.

Signed-off-by: Jeff Lait <jlait@andorra.sidefx.com>

* Fix missing OpenVDB dependency for NanoVDB-only build

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* improved change notes and updated version number

* improved change notes and updated version number

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* improved documentation

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Separate PointsToGrid kernel lambdas into functors

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing iomanip include for latest GTest

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* improved nanovdb_convert

* improved nanovdb_convert

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* review feedback

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix format strings and Windows conversion warning

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix ODR violation due to anonymous namespace in SignedFloodFill

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Minor fix to unit-test of NanoVDB

* Minor fix to unit-test of NanoVDB

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* minor change

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add DeviceMesh and (optional) NCCL CMake Support

* Add device mesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Restore current device in constructor and destructor

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Enable range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove uneeded accessors and modularize functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Statically initialize entry point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Encapsulate

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to lightweight wrapper class for DeviceNodes vector

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Minor changes needed for DistributedPointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add RAII DeviceGuard

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up NCCL dependency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove parallel_for to modularize

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Implement and test move constructor/assignment

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add docs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Expand test and documentation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Move non-reinit comment to function description

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Switch to using aliases and modern type names

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Use size_type instead of int for return

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Separate out DeviceGuard and clean up API

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to DeviceMesh for MGPU sparse convolution example

* Convert MGPU convolution example to use DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typos and clarify

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Check for errors and switch to for_each

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing const variant of deviceData(device)

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing inline for DeviceMesh functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing NCCL ifdef

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix invalid free in UnifiedBuffer move constructor

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Change UnifiedBuffer prefetch and advise to be const

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix missing relocatable device code flag

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix namespace for AbsDiff and RelDiff ostream overloads

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix out-of-bounds device id

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix TBB template deduction in C++20

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fixed issue in signedfloodfill

* Fixed issue in signedfloodfill

Signed-off-by: Ken <ken.museth@gmail.com>

* partially addressed review comments

Signed-off-by: Ken <ken.museth@gmail.com>

* added RootData::TileIterator

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed assert bug

Signed-off-by: Ken <ken.museth@gmail.com>

* snapshot

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed bug and improved unit-test

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit test and documentation

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix DeviceMesh.h header to be self-contained

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing constructor for C++20 used in AddBlindData.cuh

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* removed dead code and updated the minor version number

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix class-memaccess warning due to non-trivial copy-assignment in GridBlindMetaData

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* major improvements to GridBlindMetaData

* major improvements to GridBlindMetaData

Signed-off-by: Ken <ken.museth@gmail.com>

* minor changes to fix clang issue

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* minor simplification in CreateNanoGrid

* minor simplification in CreateNanoGrid

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* introducing new magic numbers for grids and files

* introducing new magic numbers for grids and files

Signed-off-by: Ken <ken.museth@gmail.com>

* removed two redundant magic numbers

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* fixed typos and improved documentation in NanoVDB

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Consolidate DeviceGuard into DeviceMesh header

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add distributed implementation of PointsToGrid

* Add distributed implementation of PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition in merge and single GPU case

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix kernel/cudaFree race conditions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add DistributedPointsToGrid unittest

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up example

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix Windows build and some warnings

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update for refactored DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix copyright/include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add parallelForEach helper

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Templatize kernels to align with CUB better

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Shorten TemporaryDevicePool to TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Refactor to use TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to class

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch in build

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition wrt to root node processing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Speed up synchronization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add comments and fix deprecated TransformInputIterator

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address review comments

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address more review comments

* Add more cudaCheck calls and restrict EqualityIndicator type

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix license identifiers and remove unused code

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: = <=>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* revert deprecation warning

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Silence CMake warning about FindBoost module deprecation

* Silence CMake warning about FindBoost module deprecation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typo

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failures

* Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failure
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Suppress stringop-overflow warning due to GCC 11 regression

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Generalize MGPU grid construction to any power-of-two number of GPUs

* Start support for more than two GPUs in key merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Flip flop storage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Generalize concurrent leftIntervals/rightIntervals usage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix median search

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix rebalancing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix recursive MGPU merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update TODO

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add guards for zero-tile GPUs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition across different merge levels (and memory leak in corresponding tests)

* Fix memory leaks in PointsToGrid tests

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix leapfrogging across recursion levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch for different levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Feature/fix get set methods

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed issue in get/set random access methods

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* deleted white space

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add optimizations to MGPU PointsToGrid

* Add timer for MGPU PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Avoid blocking kernel launches due to cudaFree

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix overlapping of copies

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Pipeline pointsPerVoxelPrefix sum

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup and optimization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Further improve pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove unnecessary sync point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert "Remove unnecessary sync point"

This reverts commit f01b36ad852f32ec65517b3baa08ea267d5edc2d.

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to GPU sync

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event destruction race condition and reduce host thread latency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert timer add

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More fine-grained pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event wait/destruction race condition

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Improve points to grid

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* minor improvements to nanovdb::tools::cuda::PointsToGrid

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix Windows warnings

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Force set _WIN32 flag

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Move away from deprecated 20.04 runners

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: jjtParadox <jturner@4nsi.com>
Signed-off-by: Jeff Lait <jlait@andorra.sidefx.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: jjtParadox <jturner@4nsi.com>
Co-authored-by: Jeff Lait <jlait@andorra.sidefx.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>

* Templatize buffer type for distributed points to grid (#403)

* Templatize buffer type for distributed points to grid

* Add missing template parameter

* Add pool

---------

Signed-off-by: jjtParadox <jturner@4nsi.com>
Signed-off-by: Jeff Lait <jlait@andorra.sidefx.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: jjtParadox <jturner@4nsi.com>
Co-authored-by: Jeff Lait <jlait@andorra.sidefx.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
2025-05-14 13:03:06 -04:00
Matthew Cong 566f6c6d6c Templatize buffer type for distributed points to grid (#403)
* Templatize buffer type for distributed points to grid

* Add missing template parameter

* Add pool
2025-05-14 08:43:45 -07:00
Mark HarrisandJonathan Swartz ff9f4a5532 Fix get_torch.cmake for pytorch packages without libtorch_python.so symlink (#404)
* Make get_torch.cmake robust to missing conda symlink
* Fix setting `nvtx3_dir` to help torch find nvtx3 installed in fvdb build

Signed-off-by: Mark Harris <mharris@nvidia.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-05-14 20:37:48 +10:00
Mark HarrisandJonathan Swartz a06dc77fc5 Add clangd configuration for vscode (#382)
Add clangd configuration, docs and vscode settings to use it.

Signed-off-by: Mark Harris <mharris@nvidia.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-05-14 11:29:39 +10:00
Francis Williams d196ae04ea Permute dimensions of SH coefficients to have gaussians first (#317)
* split sh into two files

move spherical harmonics autograd into its own file

small refactor

factor out jagged spherical harmonics

split jagged spherical harmonics in autograd

cleanup

cleanup

even more cleanup

remove camera dim from sh coeffs

split out shN and sh0

* more cleanup

* no more separate jagged op

* rm old jagged kernel

* don't hardcode float32

* tests

* more tests

* typo fix

* whitespace

* permute SH axes in kernel

* n first

* fix naninfmask tests

* fix merge issues

Signed-off-by: Francis Williams <francis@fwilliams.info>

* clang format

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix gsplat tests

Signed-off-by: Francis Williams <francis@fwilliams.info>

* comments

Signed-off-by: Francis Williams <francis@fwilliams.info>

* fix PR comments

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-05-12 13:16:56 -04:00
bbartlett-nv cd29610ade Multi-GPU Splat Training (#380)
* wip split script

* working split, but grows beyond target region

* first working split training

* working multi-gpu script

* refactor into sandbox

* adding dockerfile for 3dgs

* adding script to downsize colmap images

* updates after multi-gpu testing

* updates after testing

* refactor back to project and remove sandbox

* merge with upstream feature branch

* added docs more testing cleanups

* formatting / license updates

* updates to ortho script to address comments
2025-05-09 12:36:05 -04:00
380a8d698c Merge latest master into develop (#394)
* Avoid unnecessary and expensive getLastWriteTime calls for memory mapped files on windows

Signed-off-by: jjtParadox <jturner@4nsi.com>

* Add [[nodiscard]] to confusing math functions.

Signed-off-by: Jeff Lait <jlait@andorra.sidefx.com>

* Fix missing OpenVDB dependency for NanoVDB-only build

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* improved change notes and updated version number

* improved change notes and updated version number

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* improved documentation

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Separate PointsToGrid kernel lambdas into functors

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing iomanip include for latest GTest

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* improved nanovdb_convert

* improved nanovdb_convert

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* review feedback

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix format strings and Windows conversion warning

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix ODR violation due to anonymous namespace in SignedFloodFill

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Minor fix to unit-test of NanoVDB

* Minor fix to unit-test of NanoVDB

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* minor change

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add DeviceMesh and (optional) NCCL CMake Support

* Add device mesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Restore current device in constructor and destructor

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Enable range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove uneeded accessors and modularize functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Statically initialize entry point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Encapsulate

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to lightweight wrapper class for DeviceNodes vector

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Minor changes needed for DistributedPointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add RAII DeviceGuard

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up NCCL dependency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove parallel_for to modularize

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Implement and test move constructor/assignment

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add docs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Expand test and documentation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Move non-reinit comment to function description

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Switch to using aliases and modern type names

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Use size_type instead of int for return

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Separate out DeviceGuard and clean up API

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to DeviceMesh for MGPU sparse convolution example

* Convert MGPU convolution example to use DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typos and clarify

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Check for errors and switch to for_each

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing const variant of deviceData(device)

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing inline for DeviceMesh functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing NCCL ifdef

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix invalid free in UnifiedBuffer move constructor

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Change UnifiedBuffer prefetch and advise to be const

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix missing relocatable device code flag

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix namespace for AbsDiff and RelDiff ostream overloads

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix out-of-bounds device id

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix TBB template deduction in C++20

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fixed issue in signedfloodfill

* Fixed issue in signedfloodfill

Signed-off-by: Ken <ken.museth@gmail.com>

* partially addressed review comments

Signed-off-by: Ken <ken.museth@gmail.com>

* added RootData::TileIterator

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed assert bug

Signed-off-by: Ken <ken.museth@gmail.com>

* snapshot

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed bug and improved unit-test

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit test and documentation

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix DeviceMesh.h header to be self-contained

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing constructor for C++20 used in AddBlindData.cuh

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* removed dead code and updated the minor version number

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix class-memaccess warning due to non-trivial copy-assignment in GridBlindMetaData

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* major improvements to GridBlindMetaData

* major improvements to GridBlindMetaData

Signed-off-by: Ken <ken.museth@gmail.com>

* minor changes to fix clang issue

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* minor simplification in CreateNanoGrid

* minor simplification in CreateNanoGrid

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* introducing new magic numbers for grids and files

* introducing new magic numbers for grids and files

Signed-off-by: Ken <ken.museth@gmail.com>

* removed two redundant magic numbers

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* fixed typos and improved documentation in NanoVDB

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Consolidate DeviceGuard into DeviceMesh header

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add distributed implementation of PointsToGrid

* Add distributed implementation of PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition in merge and single GPU case

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix kernel/cudaFree race conditions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add DistributedPointsToGrid unittest

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up example

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix Windows build and some warnings

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update for refactored DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix copyright/include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add parallelForEach helper

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Templatize kernels to align with CUB better

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Shorten TemporaryDevicePool to TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Refactor to use TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to class

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch in build

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition wrt to root node processing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Speed up synchronization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add comments and fix deprecated TransformInputIterator

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address review comments

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address more review comments

* Add more cudaCheck calls and restrict EqualityIndicator type

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix license identifiers and remove unused code

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: = <=>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* revert deprecation warning

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Silence CMake warning about FindBoost module deprecation

* Silence CMake warning about FindBoost module deprecation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typo

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failures

* Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failure
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Suppress stringop-overflow warning due to GCC 11 regression

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Generalize MGPU grid construction to any power-of-two number of GPUs

* Start support for more than two GPUs in key merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Flip flop storage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Generalize concurrent leftIntervals/rightIntervals usage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix median search

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix rebalancing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix recursive MGPU merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update TODO

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add guards for zero-tile GPUs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition across different merge levels (and memory leak in corresponding tests)

* Fix memory leaks in PointsToGrid tests

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix leapfrogging across recursion levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch for different levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Feature/fix get set methods

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed issue in get/set random access methods

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* deleted white space

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add optimizations to MGPU PointsToGrid

* Add timer for MGPU PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Avoid blocking kernel launches due to cudaFree

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix overlapping of copies

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Pipeline pointsPerVoxelPrefix sum

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup and optimization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Further improve pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove unnecessary sync point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert "Remove unnecessary sync point"

This reverts commit f01b36ad852f32ec65517b3baa08ea267d5edc2d.

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to GPU sync

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event destruction race condition and reduce host thread latency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert timer add

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More fine-grained pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event wait/destruction race condition

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Improve points to grid

* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* minor improvements to nanovdb::tools::cuda::PointsToGrid

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix Windows warnings

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Force set _WIN32 flag

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Move away from deprecated 20.04 runners

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: jjtParadox <jturner@4nsi.com>
Signed-off-by: Jeff Lait <jlait@andorra.sidefx.com>
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Ken <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: jjtParadox <jturner@4nsi.com>
Co-authored-by: Jeff Lait <jlait@andorra.sidefx.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
2025-05-07 16:36:22 -07:00
Matthew Cong 2ba8712023 Clean up API by switching to CoordBBox (#397) 2025-05-07 16:36:05 -07:00
Mark Harris 9cec4f1934 Update the test data commit hash to the latest (#396)
* Update test data commit hash
---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-05-07 16:10:22 +12:00
Mark Harris 652b7bff97 Add multicamera rasterization test and writePNG utility (#393)
* Add new image saving test utility and create fvdb_test_utils static lib
* Add `gtests` and `benchmarks` args to build.sh
* Add multicamera rasterization test
---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-05-07 01:15:41 +00:00
Matthew Cong 34996d0f0b Revert "Replace binary search for jidx computation with nested kernels (#375)" (#392)
This reverts commit 378b08b84d.
2025-05-06 15:50:37 -07:00
Jonathan Swartz 39d2c17c89 Merge pull request #2040 from swahtz/fvdb_update
fvdb update
2025-05-01 16:16:31 +12:00
Matthew Cong dd8862cca3 Add venv docs and update build requirements file (#373) 2025-05-01 14:57:28 +12:00
Francis Williams 0d79d8d35c Rewrite colmap dataset (#388)
* rewrite colmap dataset

Signed-off-by: Francis Williams <francis@fwilliams.info>

* named args

Signed-off-by: Francis Williams <francis@fwilliams.info>

---------

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-04-30 17:25:33 +00:00
Francis Williams e97d916284 remove stray cerr (#389) 2025-04-30 13:05:06 -04:00
Matthew Cong 378b08b84d Replace binary search for jidx computation with nested kernels (#375)
* Replace binary search for computing jidx with nested kernels

* Cleanup for CPU implementation
2025-04-30 09:21:35 -04:00
Jonathan Swartz c31b75ce69 Fix bug where the maximum radius was not being calculated across all cameras in computeGradientState (#385)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-30 09:12:56 -04:00
Jonathan Swartz 76ad1c97d4 3dgs: Replace ProjectBackwards GLM math use with NanoVDB Math (#344)
This remove the last vestiges of glm usage from our code by refactoring any Gaussian Projection Backwards code to use nanovdb::math classes and to cleanup any style/naming conventions on code that is refactored. To that end, several themes of work in this PR include:

Removing GLM from our build infrastucture
Transitioning the code in GaussianProjectedBackward.cu & GaussianProjectedJaggedBackward.cu to using nanovdb::math in place of glm
Adding functionality to nanovdb::math to support a few needed missing operators
Removing GaussianTypes.cuh which was used to define glm types for Projection
Consolidated any remaining, needed warp-prefix functions from GaussianTypes.cuh and GaussianVectorTypes.cuh into GaussianWarpUtils.cuh
Refactored functions in GaussianUtils.cuh to return their calculated results instead of directly modifying output parameters where possible. The return values of these functions is then used by the calling code for modifying variables in the calling code. For instance, instead of add_blur_vjp adding blur to a parameter passed by reference, generateBlurVectorJacobianProduct now builds a nanovdb::Math::Mat2 which is used by the calling code.
Add docstrings to GaussianUtils.cuh
Moving snake_case variables/functions to camelCase and being more descriptive in their naming
Making variable types and names consistent between related functions (forward/backwards)
Fixing worldToCamMatrices being mistakenly called camToWorldMatrices

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-30 00:17:00 +00:00
Jonathan Swartz 2878a819d8 3dgs Backward Projection Test Fix (#372)
* Debugging

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Clarifying comments

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Fix logic in computeGradientState
Fixed appropriate sizing of the tensors it writes to

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Change the computeGradientState loops over C*N to save on some multiplications

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* backward test checkpoint

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Revert BackwardTest rework

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* update test data tag

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* cleanup

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-29 20:41:09 +12:00
Christopher Horvath 27a59587a5 Added a fvdb devcontainer (#381)
* Added a fvdb devcontainer so that VSCode and Github Codespaces can run inside the docker environment automatically

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>

* Improved the language in the comments

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>

* Made suggested configuration changes from VSCode copilot

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>

---------

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>
2025-04-28 11:38:41 -04:00
Matthew Cong 5dc696e88c Use PyTorch's pybind11 instead of source checkout (if possible) (#359) 2025-04-23 19:27:18 -07:00
Jonathan Swartz 4665c441a3 Merge pull request #2033 from swahtz/fvdb_update 2025-04-24 12:27:12 +12:00
Jonathan Swartz 5592b5fca8 Merge branch 'feature/fvdb' into fvdb_update
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-24 12:22:48 +12:00
Jonathan Swartz e5c380d127 Merge pull request #371 from matthewdcong/develop_fvdb_merge
Merge latest develop into feature/fvdb
2025-04-24 12:00:36 +12:00
Matthew Cong 360513e139 Merge remote-tracking branch 'upstream/develop' into feature/fvdb 2025-04-23 14:51:58 -07:00
Mark Harris 923be735a0 Refactor GaussianRasterizeForward (#308)
Similar to #231 this PR refactors the forward pass of gaussian rasterization.

    Adds a new Gaussian structure for use in both passes
    Adds a DeviceArgs class that simplifies configuring and passing arguments for the kernel, and contains the method volumeRenderTileForward which operates on the class data directly.
    Updates code for our coding style standard (e.g. camel case names)
    Renames "colors" to "features" everywhere to better match high-dimensional rendering capabilities.
    Removes redundant "pixel" and "perPixel" prefix/suffixes from some variables.

Signed-off-by: Mark Harris mharris@nvidia.com

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-04-24 07:48:51 +10:00
Matthew Cong 68160beb58 Merge pull request #370 from matthewdcong/master_develop_merge_part2
Merge latest master into develop
2025-04-23 14:47:29 -07:00
Matthew Cong 3ff8a4bb17 Squashed commit of the following:
Merge latest master into develop (squashed to avoid duplicates)
2025-04-23 14:41:05 -07:00
Matthew Cong 050ac875b5 Merge pull request #369 from matthewdcong/master_develop_merge_part1
Merge upstream commits from ASWF master into develop
2025-04-23 14:36:41 -07:00
Matthew Cong 09b77cb8ba Merge branch 'master' into develop 2025-04-23 14:33:17 -07:00
Mark Harris eadf8e38a1 Add a CMakeLists for standalone caching of fvdb_test_data (#362)
This adds a CMakeLists.txt that simply uses CPM to download / cache the FVDB test data if it is not already in the CPM_SOURCE_CACHE.

This is run by build.sh when running ctest (build.sh ctest).

Note that the CPM_SOURCE_CACHE needs to be set to the same value as set when building the gtests (or unset on both).


Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add CPM_SOURCE_CACHE to env in fvdb-gtests GHA job

Signed-off-by: Mark Harris <mharris@nvidia.com>

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-04-23 15:49:49 +10:00
Francis Williams 356efd6d00 Refactor projection forward pass (#334)
Refactors forward pass of projection to use tensor accessors and wrap kernel call in a class.
Also load cameras into shared memory which should be more efficient than having each thread load the same camera.

Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-04-23 15:28:11 +10:00
Jonathan Swartz c2d6ea99ed 3dgs projection tests (#356)
Adding gtests for the 3D Gaussian Splatting Projection code using the garden scene.

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-22 22:34:11 +00:00
Christopher Horvath 91846684b4 Moved docker troubleshooting into a separate markdown file (#360)
* Moved docker troubleshooting into a separate markdown file

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>

* Contents of docker_readme updated.

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>

---------

Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>
2025-04-22 13:05:23 -07:00
Matthew Cong bc07dba8c5 Merge pull request #354 from matthewdcong/develop_fvdb_merge
Merge latest develop into feature/fvdb
2025-04-21 22:18:21 -07:00
Mark Harris c678006f6e Use object libraries to reduce recompilation of bindings and tests. (#349)
Use intermediate object libraries to reduce recompilation of gtests when modifying libfvdb sources.

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-04-22 14:40:49 +10:00
Christopher Horvath 4fba75b70d Added WSL2/Ubuntu docker troubleshooting to the README (#355)
Signed-off-by: Christopher Horvath <blackencino+git@gmail.com>
2025-04-21 20:39:45 -07:00
Matthew Cong 8607b78e4d Fix calling host function from hostdev function warning (#351) 2025-04-21 19:14:39 -07:00
Matthew Cong 9d3efb8a21 More updates 2025-04-18 11:51:37 -07:00
Matthew Cong 695729a0c0 Update FVDB accessors 2025-04-18 09:43:48 -07:00
Matthew Cong 79f732ad1a Merge branch 'develop' into feature/fvdb 2025-04-18 08:46:47 -07:00
Francis Williams 48d68e9f60 unfuck git (#312)
Signed-off-by: Francis Williams <francis@fwilliams.info>
2025-04-17 17:56:08 -04:00
Matthew Cong 97472f6ef1 Minor changes to GridBatchImpl in preparation for Unified Memory support (#341)
* Switch mHostMetadata to raw pointer in preparation for unified memory

* Set GPU metadata via kernels

* Add missing device guard

* Insert newline

* Use kernels for setFineTransform and setCoarseTransform

* Fix GridBatchImpl for empty grid

* More cleanup

* Move indexInternal to .cu file

* Add missed file
2025-04-17 11:24:09 -07:00
Mark Harris afd31e5509 Add fvdb-dev as CODEOWNERS for the fvdb directory (#346)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-04-17 14:35:14 +12:00
Matthew Cong e8a28fe1fb Merge pull request #343 from matthewdcong/upstream_aswf_merge
Merge latest master into develop
2025-04-16 16:34:45 -07:00
Matthew Cong 753d98fb7d Merge branch 'master' into upstream_aswf_merge 2025-04-16 14:06:19 -07:00
Jonathan SwartzandMark Harris 3b6880d96d CI: gtest build and run setup (#336)
This PR sets up running our gtest build targets as part of our automated fVDB CI actions.

First, all the gtests are built as part of the library & wheel building and the whole build directory is uploaded as an artifact separately of the wheel.
In a separate task on a CI machine with a GPU, the tar'd build directory is downloaded. The build directory is un-tar'd and the gtests are run normally with ./build.sh ctest
Fixes #172
Fixes #173

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Mark Harris <mharris@nvidia.com>
2025-04-15 16:51:06 +10:00
Matthew Cong 535923f2be Re-enable NumPy 2 support (#338)
Previously we pinned NumPy to versions prior to v2.0.0 (i.e. v1.x.x) due to the lack of NumPy 2 ABI support in point-cloud-utills. The latest version of point-cloud-utils now supports the NumPy 2 ABI so we can relax this pinning.

PyTorch v2.6.0 requires NumPy v2.x.x and it's likely that slightly earlier versions also built with NumPy v2.x.x as well.
2025-04-15 15:51:40 +12:00
Matthew Cong 150c901bf8 Remove StringOrListOfStrings in favor of function overloads (#339)
* Remove StringOrListOfStrings in favor of function overloads

* Replace default constructor with nullopt

* Fix formatting

* Another formatting fix
2025-04-14 20:44:43 -07:00
Matthew Cong fbd61b1b4b Fix missing device ordinals in examples (#337) 2025-04-14 20:14:13 -07:00
Matthew CongandJonathan Swartz fa12f4e5ce Remove TorchDeviceOrString in favor of stricter function overloads (#330)
* Remove TorchDeviceOrString in favor of stricter function overloads

* Small fixes to device index

* Fix formatting

* Remove trailing whitespace

* Add missing binding

* Small fixes

* Switch from torch::optional to std::optional

* Fix missing device ordinal

* Update stub file

* Format

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-14 14:26:02 -07:00
Matthew Cong a5380f30c5 Add support for editable PyTorch installs (#333)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-04-14 13:23:43 -07:00
Sérgio AgostinhoandJonathan Swartz 1225b9c798 fVDB: Promote SyncBatchNorm to a first-class layer (#322)
Promotes the SyncBatchNorm layer to a first-class citizen.
Addresses the issue with the original implementation where checkpoints created with SyncBatchNorm were incompatible with vanilla BatchNorm, which is a behavior PyTorch natively supports.

---------

Signed-off-by: Sérgio Agostinho <sagostinho@nvidia.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-14 05:33:21 +00:00
Jonathan Swartz f290b512ca CI Fix Benchmarks job (#332)
* Fix benchmark task branch checkout failure

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-14 16:20:12 +12:00
Jonathan Swartz 9101f1dfdf Renamed gsplat headers that had prefix 'Gsplat' or had no mention of Gaussian to 'Gaussian*' prefix (#326)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-11 10:55:02 -04:00
Matthew Cong aa3e269b6d More cleanup for TorchDeviceBuffer (#320)
* More cleanup for TorchDeviceBuffer

* Format

* More cleanup
2025-04-11 00:33:32 -07:00
Jonathan Swartz 9ab8037226 CI: Fix merging reference branch to PR branch before building (#329)
* Added fvdb CI build steps to merge feature/fvdb branch in PR to PR branch before testing


---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-11 18:27:36 +12:00
Jonathan Swartz 868ef3a1eb Add global cmake download timeout and CPM_SOURCE_CACHE to fvdb CI(#328)
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-11 17:18:29 +12:00
Jonathan SwartzandMark Harris 24a942d5b6 Replaced use of glm with nanovdb math in projectForwardKernel (#238)
Implemented overloaded fucntions in GsplatUtils, Projection, etc. to not break other pieces of pipeline that still use glm
Implemented various Matrix classes in nanovdb::math that were required.

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Mark Harris <mharris@nvidia.com>
2025-04-11 02:55:15 +00:00
Mark HarrisandJonathan Swartz 40b1e6a8de Build fVDB module using scikit-build-core / CMake (#264)
Switched from using the PyTorch built-in setuptools-based cpp_extension module to a scikit-build-core + CMake build system. Additionally this includes the introduction of a new build script, updates to the Dockerfile, and updates to the documentation.

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-11 12:32:22 +12:00
Ken Museth f18d30ca0d Improve points to grid (#318)
* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* minor improvements to nanovdb::tools::cuda::PointsToGrid

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-04-09 11:15:20 -07:00
Matthew Cong 87d053396f Fix missing declaration in TorchDeviceBuffer (#319)
* Fix missing declaration in TorchDeviceBuffer
2025-04-09 00:33:25 +00:00
Francis Williams 8d876b90c8 fix grid stride loops (#316) 2025-04-08 15:51:57 -04:00
Matthew Cong e9277d5fe8 Refactor TorchDeviceBuffer to support an arbitrary single torch::Device (#302) 2025-04-04 13:47:54 -07:00
e05dd592bb Use new Gaussian Splat C++ API from Python (#290)
Implements a new GaussianSplat3d class in C++ that also tracks appropriate gradient state for optimization.
Clean up the Gaussian splatting code in python. We now only depend on Pytorch!
Clean up the optimizer code a lot by moving gradient state tracking to C++ class.
Move refinement part of optimization code to training script since it's clearer. The whole algorithm can now be read in one file.
Add a bunch of new error checking.

Still outstanding:

    Implement pruning/splitting/duplication in CUDA (Going to be a seperate PR)

-----
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-04-03 14:22:22 +11:00
Matthew Cong e217cbe6f2 Add patches to external dependencies required for CMake 4 (#305) 2025-04-02 13:12:26 -07:00
Matthew Cong 836d4a14d8 Merge pull request #306 from matthewdcong/upstream_aswf_merge
Merge in latest master into develop
2025-04-02 10:58:45 -07:00
Matthew Cong dcf8724324 Merge branch 'master' into develop 2025-04-02 09:43:35 -07:00
Matthew Cong e281e93a97 Merge pull request #300 from matthewdcong/upstream_aswf_merge
Merge latest master into develop
2025-03-31 14:07:27 -07:00
Matthew Cong 987cf322d6 Merge branch 'master' into develop 2025-03-31 12:16:02 -07:00
Mark Harris f87be92caa Add Doxygen docs for Gaussian Splatting C++ functions (#278)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-03-26 14:01:01 +11:00
Jonathan Swartz d977b72a4a fVDB: Add transform metadata when saving non-index grids (#295)
* Add transform metadata to non-index grids we're saving
fixes #32
* Fix data grid saving to be able to save non-uniform voxel scales
Add tests
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-03-24 11:06:45 +13:00
Mark Harris c877c9e7f0 Unit tests for GaussianForwardRasterization (#289)
New GaussianRasterizeForward unit tests.

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-03-18 05:46:59 +11:00
Matthew Cong 74d46e5601 Add optimizations to MGPU PointsToGrid (#283)
* Add timer for MGPU PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Avoid blocking kernel launches due to cudaFree

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix overlapping of copies

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Pipeline pointsPerVoxelPrefix sum

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup and optimization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Further improve pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove unnecessary sync point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert "Remove unnecessary sync point"

This reverts commit f01b36ad852f32ec65517b3baa08ea267d5edc2d.

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to GPU sync

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event destruction race condition and reduce host thread latency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Revert timer add

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More fine-grained pipelining

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix event wait/destruction race condition

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-03-13 15:49:17 -07:00
Ken Museth 9f52c46ad0 Feature/fix get set methods (#288)
* minor cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed issue in get/set random access methods

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* deleted white space

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit tests

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-03-13 13:21:24 -07:00
Francis WilliamsandFrancis Williams 4e376ff930 C++ Class for GaussianSplat3d (#280)
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-03-12 12:34:29 +13:00
Matthew Cong 8edb137baa Fix race condition across different merge levels (and memory leak in corresponding tests) (#274)
* Fix memory leaks in PointsToGrid tests

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix leapfrogging across recursion levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch for different levels

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-03-05 12:52:38 -08:00
Francis Williams 82aab4082c Wide channel width in GaussianRasterizeBackwards (#262)
* move atomic adds to helper

* add fixture and basic cat test

* move gradient contribution to its own function

* renaming

* remove color struct to allow different shared memory channels

* channel ranges for atomic add and shared memory color dim arg

* channel range for color fetching into shared memory and split color and gaussian shared memory fetching into two functions

* size_t

* add template parameter for shared channels

* stub for chunked

* checkpoint

* checkpoint

* rm prints

* some constexpr

* more loop unrolling

* more unrolling

* fix

* more tests

* rm old codepath

* start renaming

* more renames

* rename

* rename all members to use m prefix

* rename template args

* more renames

* cpu throws test

* error checking and bring back all dimensions

* small cleanup
2025-03-05 00:34:15 +00:00
Matthew Cong 270d2238b8 Generalize MGPU grid construction to any power-of-two number of GPUs (#270)
* Start support for more than two GPUs in key merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Flip flop storage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Generalize concurrent leftIntervals/rightIntervals usage

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix median search

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix rebalancing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix recursive MGPU merge

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update TODO

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add guards for zero-tile GPUs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-03-04 12:42:17 -08:00
Matthew Cong 0e8e1966b7 Merge pull request #271 from matthewdcong/sync/master_to_develop
Merge latest ASWF master into develop
2025-03-04 12:13:18 -08:00
Matthew Cong 84c258562e Merge branch 'master' into develop 2025-03-04 11:10:29 -08:00
12276a7afc Unit tests for GaussianSplatBackward (#259)
* move gaussian accumulation into a function. Move delta and sigma into methods on Gaussians
* Added a simple test to compare GaussianRasterizeBackward against some saved data.
* Fixed a bug where packed was uninitialized.
* Fixed another latent bug where we were getting a pointer from a tensor accessor. This might fail if that accessor is strided in the last dimension.
* Populate compile time definition of path to test data in C++ unit tests.

Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Mark Harris <harrism@users.noreply.github.com>
Co-authored-by: Jonathan Swartz <swahtz@users.noreply.github.com>
2025-02-26 16:33:33 +11:00
Mark Harris e2b295a197 CMake configuration for building libfvdb (#237)
* Add CMakeLists and dependency getters for libfvdb

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add cudnn to dev conda environment

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix compilation errors uncovered when building with cmake

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add build dir to gitignore

* cudnn_fe --> cudnn_frontend, fix cutlass

* Revert adding cudnn to conda dev_environment

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Build gtests and gbenchmarks from main cmakelists

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix tensor dimension corruption by scoping IntArrayRef's vector lifetime

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add Cutlass patch

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add cpm source cache.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix CPM source cache and make it overrideable

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add blosc and missing compilation settings.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Since we require CUDA 12+, we can drop the cutlass patch.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix blosc build options

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix up compiler options and properly scope cmake options, and generate compile_commands.json

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Remove commented out lines.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add install rules

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Whitespace

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Make get_torch.cmake a bit more robust (more informative error on import failure)

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add missing typename keyword (pre-C++20)

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Update to C++20, which for some reason makes us need the cutlass patch again, so enable it.

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-02-26 07:51:31 +11:00
Jonathan Swartz bafe8fe86e add CMAKE_CUDA_ARCHITECTURES to nanovdb weekly tests (#257)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-02-25 08:56:56 -08:00
bbartlett-nvandFrancis Williams e1cf99fbed adding in scripts for ortho, mesh, mask training etc (#247)
* adding in scripts for ortho, mesh, mask training etc

* rm dep on colmapparser in gaussiansplatting

* move colmap dataset out of core fvdb into project

* update imports in gaussian splatting project

* revert dev env

* autoformat and rename T1 -> normalizat_transform

* clean up normalization argument

* print to warning

* rm print

* bring back sorting

---------

Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-02-25 11:36:52 -05:00
Francis Williams 794820311b Refactor Backward Gaussian Rasterization and remove glm (#231)
* remove glm dep and use struct

* rename macros

* small cleanup and const some things

* move volume render backward to helper function

* checkpoint

* rename S -> ScalarType

* pass in warp as variable

* camel case and type cleanup

* S -> ScalarType

* clean up full file

* address PR comments

* rename thread -> blockDim, blocks -> gridDim

* fixed and moved to class

* checkpoint

* checkpoint

* checkpoint

* rename

* cleanup

* checkpoint

* cleanup

* more cleanup

* Fix comment

* handle empty inputs

* fix

* fix error checking
2025-02-22 20:07:44 +00:00
Jonathan Swartz 350febee18 Merge pull request #248 from matthewdcong/fvdb_develop_integ
Merge develop into feature/fvdb
2025-02-21 12:37:39 +13:00
Matthew Cong ebca97a1a2 Merge develop into feature/fvdb
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-20 14:09:23 -08:00
Matthew Cong 4f60c64028 Suppress stringop-overflow warning due to GCC 11 regression (#246)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-20 13:08:44 -08:00
Mark Harris fb999c49e4 Fix strict aliasing violation in encode_depth, and document helper functions. (#236)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-02-19 08:46:26 +13:00
Jonathan Swartz 2a7498f7f7 Merging current develop into feature/fvdb (#234)
---------
Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-18 14:22:08 +13:00
Jonathan Swartz c9a06baf88 Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failures (#235)
* Adding /bigobj to TestNanoVDB.cu compilation options to fix Windows build failure
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-02-18 11:33:27 +13:00
Matthew Cong e170b879ae Use cuDNN 9 that's included in PyTorch 2.4 and above (#222)
Add cuDNN include directory and vendor in cuDNN frontend

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-18 09:04:43 +13:00
Jonathan SwartzandFrancis Williams 8c6c449898 Change status_checks to use self-hosted runner (#226)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Francis Williams <fwilliams@users.noreply.github.com>
2025-02-15 00:07:35 +00:00
Matthew CongandKen Museth 1cc5aa13ee Silence CMake warning about FindBoost module deprecation (#230)
* Silence CMake warning about FindBoost module deprecation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typo

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
2025-02-14 14:44:54 -08:00
Ken Museth 692cdde46c minor cleanup (#229)
Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-14 13:59:38 -08:00
Ken Museth 0d157c199f revert deprecation warning (#228)
Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-14 12:02:33 -08:00
Mark HarrisandFrancis Williams 7b040d3c67 Gaussian Splatting sparse tile intersection (#213)
* Implementation and tests of dispatchGaussianTileIntersectionSparse (not yet passing)

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Some bug fixes, intermediate changes, still failing tests.

* fix

* Use custom kernel for sparse tile_offsets. Fixes current sparse test failures.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Make non-sparse tile_offsets look like it used to.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Refactor dispatchGaussianTileIntersection to reduce repetition between dense and sparse.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add a random sparsity test.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* docs and move sparse intersection into a different header

* grid stride loops

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-02-14 14:18:10 -05:00
Matthew Congand= 0783b2a7e1 Add distributed implementation of PointsToGrid (#102)
* Add distributed implementation of PointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition in merge and single GPU case

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix kernel/cudaFree race conditions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add DistributedPointsToGrid unittest

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up example

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix Windows build and some warnings

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update for refactored DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix copyright/include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add parallelForEach helper

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Templatize kernels to align with CUB better

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Shorten TemporaryDevicePool to TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Refactor to use TempDevicePool

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to class

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Parallelize kernel dispatch in build

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix race condition wrt to root node processing

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Speed up synchronization

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add comments and fix deprecated TransformInputIterator

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address review comments

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Address more review comments

* Add more cudaCheck calls and restrict EqualityIndicator type

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix license identifiers and remove unused code

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add missing include

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: = <=>
2025-02-14 08:51:18 -08:00
Matthew Cong 20c22d71e5 Add support for venv builds (#219)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-14 00:12:25 +00:00
Matthew Congand= 372e48a430 Defer psutil import which is not specified as a Python requirement (#217)
* Defer psutil import which is not specified as a Python requirement

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix formatting

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: = <=>
2025-02-14 00:02:08 +00:00
Matthew Cong ad63e07a03 Consolidate DeviceGuard into DeviceMesh header (#221)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-13 12:40:14 -08:00
Ken Museth 1bb3b12482 fixed typos and improved documentation in NanoVDB (#220)
Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-13 11:46:16 -08:00
Matthew Cong 273d63e2ca Switch AX CI jobs to be weekly (#216)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-12 19:03:39 -08:00
Ken Museth 7cdf89202f introducing new magic numbers for grids and files (#210)
* introducing new magic numbers for grids and files

Signed-off-by: Ken <ken.museth@gmail.com>

* removed two redundant magic numbers

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-12 13:45:38 -08:00
Matthew Cong 69a7808d4d Remove TBB dependency introduced by GCC (#215)
* Remove TBB dependency introduced by GCC

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix formatting

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-12 12:16:33 -08:00
Mark Harris 7f22194e09 Return activeTileMask from computeSparseInfo (#211)
Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-02-11 18:43:10 -05:00
7c04627c24 Add C++ unit tests for GaussianTileIntersection (#203)
* Rename computeSparseInfoTest and add new unit tests for GaussianTileIntersection.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix handling of all-zero-radius splats. Fixes failing unit test.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* spdx header

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Fix the failing BasicIntersectionTest

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add an explanatory comment about packed mode.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* refactoring

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Add failing test, commented out.

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Separate GaussianFullyFusedProjection*.cu into distinct files (#201)

* separate projection files

* rename some functions

* rename jagged

* fix empty gaussian test, add error checking, and add error checking test

* Rename NanInfMaskTest to match other test file naming

Signed-off-by: Mark Harris <mharris@nvidia.com>

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Francis Williams <fwilliams@users.noreply.github.com>
Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-02-11 18:00:24 -05:00
Francis Williams 813ccdcf6b C++ PLY saving (#188)
* save ply for gaussian splats

* fixes

* filter operation in cuda

* checkpoint

* fixes and python bindings

* end to end test in python

* rm unused imports

* helper function for getting bytes from tensor

* rm thread divergent returns and inline on header only function

* use std generate

* use tensorOpts

* use config array

* const filename

* error message fix

* contiguous

* stylefix

* whitespace

* stylefix2

* grid stride loop and launch bounds

* use stream in sparse info computation (#190)

* Add a Vec2 type to nanovdb math (#166)

* orthographic projection in gaussian splatting

add orthographic flag to depth rendering function

derp

add ortho projection to jagged projection

* small refactor

* add vec2 class to nanovdb math

* fix

* Separate GaussianFullyFusedProjection*.cu into distinct files (#201)

* separate projection files

* rename some functions

* rename jagged
2025-02-11 16:12:45 -05:00
Matthew Cong bb0c4d141f Replace deprecated torch::linalg::inv with equivalent at::linalg_inv (#209)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-11 14:15:13 -05:00
Francis Williams 0f3578d60a Separate GaussianFullyFusedProjection*.cu into distinct files (#201)
* separate projection files

* rename some functions

* rename jagged
2025-02-11 10:36:48 -05:00
Ken Museth 35d6eea9d2 minor simplification in CreateNanoGrid (#202)
* minor simplification in CreateNanoGrid

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-10 17:16:09 -08:00
Francis Williams 91d8bcf3c0 Add a Vec2 type to nanovdb math (#166)
* orthographic projection in gaussian splatting

add orthographic flag to depth rendering function

derp

add ortho projection to jagged projection

* small refactor

* add vec2 class to nanovdb math

* fix
2025-02-10 16:23:13 -05:00
Ken Museth 90ac7aa909 major improvements to GridBlindMetaData (#199)
* major improvements to GridBlindMetaData

Signed-off-by: Ken <ken.museth@gmail.com>

* minor changes to fix clang issue

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-10 12:56:39 -08:00
Matthew CongandKen Museth a206519467 Fix class-memaccess warning due to non-trivial copy-assignment in GridBlindMetaData (#147)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
2025-02-07 22:12:29 -08:00
Ken Museth b4634c76b8 removed dead code and updated the minor version number (#198)
Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-07 17:11:38 -08:00
Matthew CongandKen Museth 2144e0efd4 Add missing constructor for C++20 used in AddBlindData.cuh (#197)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
2025-02-07 16:26:05 -08:00
Matthew Cong fc2c4b44b6 Fix DeviceMesh.h header to be self-contained (#196)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-07 23:34:49 +00:00
Ken Museth 6d54f0e50c Fixed issue in signedfloodfill (#185)
* Fixed issue in signedfloodfill

Signed-off-by: Ken <ken.museth@gmail.com>

* partially addressed review comments

Signed-off-by: Ken <ken.museth@gmail.com>

* added RootData::TileIterator

Signed-off-by: Ken <ken.museth@gmail.com>

* cleanup

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed assert bug

Signed-off-by: Ken <ken.museth@gmail.com>

* snapshot

Signed-off-by: Ken <ken.museth@gmail.com>

* fixed bug and improved unit-test

Signed-off-by: Ken <ken.museth@gmail.com>

* improved unit test and documentation

Signed-off-by: Ken <ken.museth@gmail.com>

---------

Signed-off-by: Ken <ken.museth@gmail.com>
2025-02-07 15:01:11 -08:00
Francis Williams 7f015429ca use stream in sparse info computation (#190) 2025-02-06 11:46:09 -05:00
Matthew Cong 72ffce9949 Fix TBB template deduction in C++20 (#189)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-05 16:33:41 -08:00
Matthew Cong 9733b0882e Fix out-of-bounds device id (#180)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-02-05 08:18:02 -08:00
Mark HarrisandFrancis Williams baab90646e Add support for multiple images in sparse gsplat config (#182)
Extends computeSparseInfo() (from #137) to work with a JaggedTensor of pixels to render with outer dimension > 1. In other words, pixels from more than one image.

Adds unit tests to exercise this functionality. Also parameterizes the strided-pixel unit tests to further DRY up the test code.

Collaboration with @swahtz and @fwilliams

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-02-05 19:21:37 +13:00
8c41e2b822 Sparse Gaussian Splatting Configuration (#137)
Closes #60

This pull request adds functionality to compute the configuration tensors for Sparse 3D Gaussian Splatting. These tensors will be used to mask the output of 3DGS when fed a list of sparse pixels to render, and to "regather" the sparse rendered pixels corresponding to the input pixel UV coordinates.

A fairly comprehensive C++ unit test suite is also added.

Build Configuration Updates:
fvdb/.vscode/c_cpp_properties.json: Updated include paths to reflect new dependencies and updated Python version from 3.10 to 3.11.
fvdb/setup.py: Added psutil import and set MAX_JOBS environment variable based on available RAM to control the number of parallel jobs for building. [1] [2]
fvdb/src/cmake/get_fvdb.cmake: Modified to dynamically find the Python version and update the FVDB_BUILD_DIR accordingly.
fvdb/src/tests/CMakeLists.txt: Added compile options for CUDA and C++ in debug mode and configured new unit tests for Gaussian splatting. [1] [2]
Functionality Enhancements:
fvdb/src/detail/ops/gsplat/GaussianSplatSparse.cu: Added new CUDA kernels and functions to implement sparse Gaussian splatting, including detailed comments explaining the algorithm and its components.
fvdb/src/detail/ops/gsplat/GaussianSplatSparse.h: Added header declarations for the new sparse Gaussian splatting functions.

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Signed-off-by: Matthew Cong <mcong@nvidia.com>
Signed-off-by: Mark Harris <mharris@nvidia.com>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Francis Williams <francis@fwilliams.info>
2025-02-04 12:07:53 +13:00
Matthew Cong 964c4270d6 Fix namespace for AbsDiff and RelDiff ostream overloads (#177)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-30 16:35:17 -08:00
Francis Williams 03cd858bf0 Merge remote-tracking branch 'fwilliams/fw/orthographic_gaussian_splats' into feature/fvdb 2025-01-30 08:51:00 -08:00
Francis Williams ca8fbd1ab4 naming 2025-01-30 07:07:51 -08:00
Francis Williams 3f72e2444a return values out of projection vjp 2025-01-30 07:03:23 -08:00
Jonathan Swartz 1a376f21d0 Moving 3dgs example to projects directory (#175)
* Moved examples/3dgs->projects/3d_gaussian_splatting/training

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Fix up READMEs

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-30 14:53:01 +13:00
Francis Williams 6485bca2db add documentation and move projections to their own header 2025-01-29 16:53:39 -08:00
Francis Williams b47913e604 fix some comments 2025-01-29 16:44:35 -08:00
Matthew Cong 16f190b574 Fix missing relocatable device code flag (#170)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-29 13:45:53 -08:00
Francis Williams 9d55e6397a return projection values rather than use output params.
template ortho in jagged projecction
2025-01-29 13:07:15 -08:00
Francis Williams 79a3b3a155 another typo 2025-01-29 08:24:22 -08:00
Francis Williams 1e7ecc2c2a typo fix 2025-01-29 08:20:19 -08:00
Francis Williams b74bad0a3f template ortho for backward 2025-01-29 07:50:55 -08:00
Francis Williams 3ca570de27 fix backward number of return values 2025-01-29 07:50:48 -08:00
Francis Williams 7c5ff85553 fix typo 2025-01-29 07:50:36 -08:00
Jonathan Swartz 470205d833 Removing pull_request trigger from 'Wait for Status Checks' (#163)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-29 17:21:50 +13:00
Jonathan Swartz 7f0b162766 Removing pull_request trigger from 'Wait for Status Checks' (#165)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-29 16:49:03 +13:00
ed220e48d8 Boolean template parameter for orthographic projection.
Co-authored-by: Mark Harris <harrism@users.noreply.github.com>
Co-authored-by: Jonathan Swartz <swahtz@users.noreply.github.com>
2025-01-28 19:17:22 -08:00
Matthew Cong 526a693b43 Change UnifiedBuffer prefetch and advise to be const (#160)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-27 23:52:29 +00:00
Matthew Cong 520085852c Fix invalid free in UnifiedBuffer move constructor (#156)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-27 22:34:16 +00:00
Francis Williams 500e158f97 small refactor 2025-01-27 14:13:02 -08:00
Jonathan Swartz 6ff3939a05 Fixing build_environment; should be 2.4.1 (#162)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-28 07:54:21 +11:00
Matthew Cong c146d17513 Add missing NCCL ifdef (#164)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-28 09:30:39 +13:00
Francis Williams fef302f5ff Revert "orthographic projection in gaussian splatting"
This reverts commit bfe68a0d82.
2025-01-24 13:26:21 -08:00
Francis Williams f38a52d8e6 Revert "add orthographic flag to depth rendering function"
This reverts commit 7803589d9d.
2025-01-24 13:26:08 -08:00
Francis Williams 3673dabd9c Revert "derp"
This reverts commit af38b51cf9.
2025-01-24 13:25:57 -08:00
Francis Williams 00a035affb Revert "add ortho projection to jagged projection"
This reverts commit d800ecfa88.
2025-01-24 13:25:43 -08:00
Francis Williams 589b9c9d16 orthographic projection in gaussian splatting
add orthographic flag to depth rendering function

derp

add ortho projection to jagged projection
2025-01-24 13:24:51 -08:00
Francis Williams d800ecfa88 add ortho projection to jagged projection 2025-01-24 13:21:54 -08:00
Francis Williams af38b51cf9 derp 2025-01-24 12:57:20 -08:00
Francis Williams 7803589d9d add orthographic flag to depth rendering function 2025-01-24 10:19:16 -08:00
Francis Williams bfe68a0d82 orthographic projection in gaussian splatting 2025-01-24 09:42:28 -08:00
Mark Harris 86f2734cd2 Fix conda envs and cmake for unit tests (#153)
* Fix build- and dev- environments and cmake so unit tests will build with conda-forge packages

Signed-off-by: Mark Harris <mharris@nvidia.com>

* Remove no-longer-needed env

Signed-off-by: Mark Harris <mharris@nvidia.com>

---------

Signed-off-by: Mark Harris <mharris@nvidia.com>
2025-01-23 11:38:53 +13:00
Jonathan Swartz 06f003e85a Merge pull request #1997 from swahtz/omni_fvdb_update
fVDB 0.2.1 update
2025-01-23 10:38:01 +13:00
Jonathan Swartz cd5fdeb92a fVDB version bumped to 0.2.1 (#151) (#152)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-22 17:40:25 +13:00
Jonathan Swartz 8145597272 Adding back fix to NanoVDB CI for test failures
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-22 14:49:50 +13:00
Jonathan Swartz 04e3193377 Revert any changes to .github/ made to accomodate CI
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-22 13:21:19 +13:00
Jonathan Swartz 16bfecf4c6 fVDB version bumped to 0.2.1 (#151)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-22 13:15:17 +13:00
Jonathan Swartz eb489a2bdc Remove test env accidentally merged in previous PR (#150)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-22 12:51:20 +13:00
Francis Williams a8e52da53c Fix bug where image cropping wasn't working in Gaussian Splatting 2025-01-22 12:21:48 +13:00
Matthew Cong 7d13055ceb Add missing inline for DeviceMesh functions (#145)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-21 09:46:15 -08:00
Francis Williams 2db574080d fix itertools.cycle (#142) 2025-01-21 15:51:32 +13:00
Matthew Cong 2d7bc30af3 Add missing const variant of deviceData(device) (#146)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-21 15:48:25 +13:00
Jonathan SwartzandKen Museth a75a507ecb PyTorch, CUDA package sources moved to conda-forge channel (#131)
Moved the recommended build/test/dev environments to use the conda-forge channel as their package source. This has required moving to CUDA 12.0, PyTorch 2.4.1.  Also removed the NKFW tests because they were breaking in the new environment but these tests’ functionality were covered by other unit tests.

closes #121 closes #135
---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
2025-01-21 13:01:25 +11:00
Matthew CongandMark Harris f9a9876ee9 Switch to DeviceMesh for MGPU sparse convolution example (#106)
* Convert MGPU convolution example to use DeviceMesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Fix typos and clarify

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Check for errors and switch to for_each

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
2025-01-16 10:57:19 -08:00
1b7f60fe53 remove tensor conversion on images from dataloader to save on ram useage for large datasets (#129)
Co-authored-by: Francis Williams <fwilliams@users.noreply.github.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
2025-01-17 07:50:58 +13:00
Matthew CongandMark Harris 31b5fee9ab Add DeviceMesh and (optional) NCCL CMake Support (#99)
* Add device mesh

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Restore current device in constructor and destructor

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Enable range-based for loops

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Use structured bindings inside for loop

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove uneeded accessors and modularize functions

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Statically initialize entry point

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Encapsulate

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Switch to lightweight wrapper class for DeviceNodes vector

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Minor changes needed for DistributedPointsToGrid

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add RAII DeviceGuard

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* More cleanup

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Clean up NCCL dependency

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Remove parallel_for to modularize

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Implement and test move constructor/assignment

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Add docs

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Expand test and documentation

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Move non-reinit comment to function description

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Switch to using aliases and modern type names

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Use size_type instead of int for return

Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>

* Separate out DeviceGuard and clean up API

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Mark Harris <783069+harrism@users.noreply.github.com>
2025-01-15 13:41:11 -08:00
Mark HarrisandJonathan Swartz d9b35645a3 Add CMake support for unit tests (#133)
* Add basic cmake and an example gbenchmark

* Modify setup.py to exclude benchmarks directory

* gitignore benchmarks build dir

* Make CMake work with conda-forge Torch, and make simple benchmark use Torch.

* Add working C++11 ABI Torch conda environment

* Modularize the cmake.

* Whitespace cleanup

* empty

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Add comment about excluding benchmarks directory

* Modularize python, torch and fvdb dependencies, and add better error checking

* Empty commit to test signing

* Empty commit to test signing

* Add cmake and example for gtest-based C++ unit tests

* remove whitespace change.

* set `files.insertFinalNewLine` to true in workspace settings, fix EOF newlines

* newline at EOF

* Rename ExampleTest

* Add CTest support.

* "benchmarks" --> "tests"

* Fix typo

* Ignore tests directory (oops)

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-15 11:58:10 -05:00
Matthew CongandFrancis Williams da04f647be Create blank issue template (#136)
* Create issue.md

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update and rename issue.md to task--or--work--item.md

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update task--or--work--item.md

rm trailing whitespace

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Update and rename task--or--work--item.md to blank--issue

Signed-off-by: Matthew Cong <mcong@nvidia.com>

* Rename blank--issue to blank--issue.md

Signed-off-by: Matthew Cong <mcong@nvidia.com>

---------

Signed-off-by: Matthew Cong <mcong@nvidia.com>
Co-authored-by: Francis Williams <fwilliams@users.noreply.github.com>
2025-01-14 14:38:34 -08:00
64f47dec27 Add basic CMake infrastructure for benchmarks (#75)
* Add basic cmake and an example gbenchmark

* Modify setup.py to exclude benchmarks directory

* gitignore benchmarks build dir

* Make CMake work with conda-forge Torch, and make simple benchmark use Torch.

* Add working C++11 ABI Torch conda environment

* Modularize the cmake.

* Whitespace cleanup

* empty

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Add comment about excluding benchmarks directory

* Modularize python, torch and fvdb dependencies, and add better error checking

* Empty commit to test signing

* Empty commit to test signing

* Use `find_library` to find libfvdb.so

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Francis Williams <fwilliams@users.noreply.github.com>
2025-01-14 16:34:27 -05:00
Francis Williams 8f3eaa471a Fw/3dgs lifestyle (#127)
* fix spelling mistake and add log

* quality of life helper
2025-01-14 03:01:13 +00:00
Francis Williams dc887b6509 vscode path settings (#126) 2025-01-13 16:16:57 -05:00
Jonathan Swartz 95166cf5cc Fix docs copyright notice to be OpenVDB contributors (#124)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-10 20:03:53 +00:00
Mark HarrisandJonathan Swartz 1acb6477ed Make setup.py handle case where cudnn directory is created but empty (#50)
Co-authored-by: Jonathan Swartz <2375296+swahtz@users.noreply.github.com>
2025-01-11 08:32:36 +13:00
Jonathan Swartz a4a92bc3fa Wait for status checks also triggered on pushes to pull-request branches (#123)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-11 08:31:13 +13:00
Jonathan SwartzandKen Museth 36f3e0921b CI: Update feature/fvdb from develop (#118)
Updating feature/fvdb branch from current develop branch to pickup the 'enforce-all-checks' action as well as disabled Windows tests setup.

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Co-authored-by: Ken Museth <1495380+kmuseth@users.noreply.github.com>
2025-01-10 17:15:25 +13:00
Jonathan Swartz d2550dba8d Disabling Windows build & nanovdb tests; disabling all tests except for Windows tests in weekly (#120)
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-10 15:43:36 +13:00
Jonathan Swartz 7fdb6283ff black formatting fix for garfield download_example_data (#119)
* black formatting fix for garfield download_example_data
* Removing cv2 import that is only valid for pip opencv package
---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-10 15:09:48 +13:00
Jonathan Swartz d9e5b261e1 Fix status_check directory
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 10:49:39 +13:00
Jonathan Swartz e7d5b0c556 Add status check that checks for the pass/fail of only the triggered status checks
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 10:49:39 +13:00
Jonathan Swartz 527bf5eae8 Updated README
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz 7b542ae021 Garfield download_example_data now also downloads colmap data.
dozer_nerfgun_waldo changed to the default dataset

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz b4ba1cbeab Fix colmap dataset distortion parameters; wrong number of params for simple radial distortion
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz 99630eb403 Make 3dgs download_example_data executable
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz 6abaae22dd Add download_example_data script for downloading example colmap data from LERF project used by GARField paper.
Updated README

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz 8be8734a12 Fix trailing whitespace
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz d560caea5c Fixing garfield black formatting; adding garfield to SPDX ignore-paths
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz d2d4e13971 Add a garfield CUDA 12.1 environment
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Jonathan Swartz afbd5a9fcc Adding garfield source from research repo
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-09 04:55:45 +13:00
Ken Museth 89979f93f7 Minor fix to unit-test of NanoVDB (#111)
* Minor fix to unit-test of NanoVDB

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* minor change

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
2025-01-07 13:24:51 -08:00
Jonathan Swartz 3f9b956418 Fix BuildDeviceGrid's calls to NanoVDB voxelsToGrid which removed an allocator type as an optional template argument.
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-08 10:04:28 +13:00
Jonathan Swartz 07b3ee731d Attemping to fix fvdb action memory issue
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 17:50:43 +13:00
Jonathan Swartz 615a0f1ab9 Fix carriage return typo
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 17:50:43 +13:00
Jonathan Swartz c84d4e2848 Uncomment paths-ignore in fvdb action
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 17:50:43 +13:00
Jonathan Swartz 182a9e584e Commenting out fvdb paths-ignore
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 17:50:43 +13:00
Jonathan Swartz 8d2894cd5d Updating fvdb and whitespace actions for PR bot workflow
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 17:50:43 +13:00
Jonathan Swartz f655251b2b Merge branch 'develop' into feature/fvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2025-01-07 09:59:12 +13:00
Matthew Cong 59d2a5c7e3 Fix ODR violation due to anonymous namespace in SignedFloodFill (#97)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-06 12:09:18 -08:00
Matthew Cong 5ecb9c3ead Fix format strings and Windows conversion warning (#101)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-06 11:15:25 -08:00
Ken Museth 23ded25be2 improved nanovdb_convert (#98)
* improved nanovdb_convert

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* fixed typo

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* added unit tests

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* review feedback

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
2025-01-06 11:09:50 -08:00
Matthew Cong fa1ac5feef Add missing iomanip include for latest GTest
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-03 16:59:30 +13:00
Matthew Cong a004afbb05 Separate PointsToGrid kernel lambdas into functors (#94)
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2025-01-02 11:57:39 -06:00
Ken Museth adfd4cd1ef improved change notes and updated version number (#95)
* improved change notes and updated version number

Signed-off-by: Ken Museth <ken.museth@gmail.com>

* improved documentation

Signed-off-by: Ken Museth <ken.museth@gmail.com>

---------

Signed-off-by: Ken Museth <ken.museth@gmail.com>
2024-12-31 12:48:56 -08:00
Matthew Cong 1251b0e016 Fix missing OpenVDB dependency for NanoVDB-only build
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2024-12-31 12:03:58 +13:00
Jonathan Swartz 8c92ec47a6 Pull Request Testing Setup (#86)
* Added copy-pr-bot. Updated triggers to branch pushes per instructions:
https://docs.gha-runners.nvidia.com/apps/copy-pr-bot/

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

* Add NV CPU runners to tasks requiring larger instances
Turning off USE_EXPLICIT_INSTANTIATION, now unblocked by larger runner

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>

---------

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-30 15:04:03 +13:00
Jonathan Swartz 6f10bf3b15 Merge pull request #84 from swahtz/js/voxel-foundation-migration
Migrating last PR changes from private repo over to this repo
2024-12-23 12:02:12 +13:00
Jonathan Swartz 9d691a88d9 Removing GaussianRasterize.cu which was split into two source files
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-22 16:38:38 +13:00
Jonathan Swartz 06957104f9 Merge branch 'feature/fvdb' into js/voxel-foundation-migration 2024-12-22 16:33:38 +13:00
Jonathan Swartz 2d4f3e1bfe Migrating last PR changes from private repo over to this repo including:
Changes to .clang-format for better include sorting
Gsplat rasterization code cleanup and add unused arguments for pixel mask

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-22 16:30:45 +13:00
Jonathan Swartz 548b52e97e Merge pull request #46 from NVIDIA-Omniverse/js/fvdb_codestyle
Add fVDB code style check actions
2024-12-21 13:56:06 +13:00
Matthew Cong 47c5a29be4 Merge pull request #76 from NVIDIA-Omniverse/nanovdb_merge
Merge changes from latest NanoVDB
2024-12-20 15:59:12 -08:00
Matthew Cong faa644ab3d Merge changes from latest NanoVDB
Signed-off-by: Matthew Cong <mcong@nvidia.com>
2024-12-20 15:58:30 -08:00
Jonathan Swartz ce544bd2ff fix clang-format issue with JCat0.cu
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-21 11:26:13 +13:00
Jonathan Swartz 1f4a9d5617 Merge branch 'feature/fvdb' into js/fvdb_codestyle
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-21 11:22:35 +13:00
Jonathan Swartz 263e0e069e Merge pull request #81 from NVIDIA-Omniverse/fw/fix_jcat0
Fix jagged concatenation when concatenating a JaggedTensor with only one element in it
2024-12-20 11:55:11 +13:00
Francis Williams 200cf246ee Enhance JCat0 kernel to handle empty JIdx tensor case and add unit test for concatenation of JaggedTensors 2024-12-19 16:40:46 -05:00
Jonathan Swartz 6ccc92f0c6 newline
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-19 09:41:24 +13:00
Jonathan Swartz 29606d6a74 Update SPDX identifier action with ignore-paths for source files/dirs that have different licenses
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-18 16:48:33 +13:00
Jonathan Swartz 18fc7dc65d Merge pull request #66 from swahtz/disable_docs_for_fvdb
Disable docs Workflow for fVDB changes
2024-12-18 16:43:42 +13:00
Jonathan Swartz 3b5458baad Merge pull request #62 from NVIDIA-Omniverse/master
Updating `feature/fvdb` from `master`
2024-12-18 16:39:25 +13:00
Jonathan Swartz 5ac52485b1 Disabling docs action for fvdb changes
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-18 14:09:10 +13:00
Jonathan Swartz 1d9c7345b6 Addressing review notes
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-17 17:56:40 +13:00
Jonathan Swartz 7053bfd0d2 Fix codestyle source paths
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-17 14:31:07 +13:00
Jonathan Swartz a035c14b90 Add fVDB code style check actions
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-17 09:04:33 +13:00
Jonathan Swartz 70566d7fb2 Merge pull request #45 from NVIDIA-Omniverse/js/fvdb_actions
Add fVDB CI
2024-12-17 08:36:57 +13:00
Jonathan Swartz f70b1a570f Turn off explicit instantiation for debug linux build
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-16 21:56:45 +13:00
Jonathan Swartz 128be93972 fVDB continuous benchmaring results path fix
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-16 13:46:57 +13:00
Jonathan Swartz f088f173d1 Fixing fvdb wheel upload path
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-16 13:07:12 +13:00
Jonathan Swartz 43a5220700 Adding fvdb CI unit tests to github workflows
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-13 12:26:18 +13:00
Jonathan Swartz 38adbab1bc Updating the versions of checkout action; add .gitmodules to ignore list
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-13 11:40:50 +13:00
Jonathan Swartz 093a6382ae fVDB: Added 'projects' directory to include more fully-featured example 'batteries included' projects
Added panoptic segmentation project with MaskPLS implementation
Fixed install issue not including `fvdb.optim`
Re-introduced support for Volta&Turing but added errors for use of certain conv backends
Added interpolation functions to VDBTensor

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-11 15:47:23 +13:00
Jonathan Swartz 11836adebd Merge branch 'master' into feature/fvdb
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-06 12:35:18 +13:00
Jonathan Swartz f7b18d9d7b fVDB: Fix missing fvdb.utils.data modules
Expose various 'ELU non-linearities
Integer JaggedReduce
Updated build TORCH_CUDA_ARCH_LIST for supported CUDA compute architectures, fixed Docker dev and CI images
Updated REAME's env and build instructions

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-12-03 20:11:34 +13:00
Jonathan Swartz f1d9e2bc08 Version 0.2.0 release:
• Significant refactor of gaussian splatting pipeline
• Refactor of examples/3dgs using the new 3dgs pipeline (see README for a starting point to the example)
• License identifiers changed to Apache 2.0 to be in line with OpenVDB
• A `dev_environment.yml` is now included to help construct a reccommended development environment
• A bug was fixed when using `GridBatch.ijk_to_inv_index(cumulative=False)` when the ijk argument has repeated elements
• GLM is being vendored in and is no longer a runtime dependency
• The utility functions needed in the examples and unit tests to download and read the relevant data files has been refactored into `fvdb.utils.tests` and `fvdb.utils.examples` respectively

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-11-12 17:44:24 +13:00
Jonathan Swartz 7496bfa45c Merge pull request #1934 from JamesPerlman/patch-1
fVDB: Fix typo in 01_api_basics.ipynb
2024-10-23 07:35:27 +13:00
James Perlman 3d4a21b185 Update 01_api_basics.ipynb
There are 5 random features per voxel, and 8 grids.  Not 8 random features per voxel.

Signed-off-by: James Perlman <jam.e.perl@gmail.com>
2024-10-11 13:07:59 -07:00
Jonathan Swartz 6faf27c7cb Merge pull request #1915 from swahtz/feature/fvdb
Merge new commits from fVDB repository
2024-09-26 21:01:05 +12:00
Jonathan Swartz b5922af1cb Merge commits from fVDB repository including:
Version v0.1.0 release
Added gaussian splatting support
Significant VDBTensor API rewrite as well as various GridBatch function name changes to make them more consistent

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-09-26 20:47:01 +12:00
Jonathan Swartz f0324e6fca Merge pull request #1907 from AcademySoftwareFoundation/master
Merge master to feature/fvdb
2024-09-18 20:31:54 +12:00
Jonathan Swartz 9accf19836 Merge pull request #1891 from swahtz/feature/fvdb
fVDB improved test setup and PyTorch 2.4 update
2024-09-17 13:32:09 +12:00
Jonathan Swartz 4592f6c887 Updated fVDB requirements and documentation to PyTorch 2.4
Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-09-16 21:04:12 +12:00
Jonathan Swartz 5de7ee4da9 Moved all test data to an external repository and updated tests
Updated Github test actions to split apart build and test steps
Added negative operator to JaggedTensor; to operators to SparseConvPackInfo

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-09-06 21:25:33 +12:00
apradhana 70e0264ed1 Merge pull request #1886 from swahtz/feature/fvdb
fVDB Updates: Bugs fixed for multi-GPU support, JaggedTensor slicing/indexing CUDA kernels
2024-09-04 12:09:21 -07:00
Jonathan Swartz 52ba85af93 Bugs fixed for multi-GPU support
JaggedTensor slicing and indexing moved to CUDA kernels
Small updates to basic_concepts docs and README

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-09-02 18:17:30 +12:00
apradhana 975beecdb6 Merge pull request #1876 from swahtz/feature/fvdb
fVDB code format updates
2024-08-20 20:33:09 -07:00
Jonathan Swartz c9aee5964a Formatting changes to match OpenVDB guidelines
Added examples
Updated README and environment/docker updates

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
2024-08-21 10:47:20 +12:00
apradhana c99b17c85c Merge pull request #1869 from swahtz/feature/fvdb
Updates to fVDB
2024-08-13 17:24:05 -07:00
Jonathan Swartz 9357034f9a fVDB changes including:
•Reintroduced missing src/build/* files that were accidentally ommitted
•JaggedTensor concatentation moved to a cuda kernel
•Non-cumulative indices for ijk mappings is now the default return style (makes indexing into JaggedTensors of data more natural)
•cuDNN disabled for CUDA versions <12
•Updated notebook files to new API and now included
•Removed deprecated usage of `python setup.py test` and running pytest directly

Signed-off-by: Jonathan Swartz <jonathan@swartzfx.com>
2024-08-14 11:54:20 +12:00
apradhana 63f7ab0da4 Merge pull request #1862 from fwilliams/fw/fvdb
Commit fVDB to OpenVDB
2024-07-23 12:01:25 -07:00
Francis Williams 9b178ba16c Commit fVDB to OpenVDB
Signed-off-by: Francis Williams <francis@fwilliams.info>
2024-07-23 14:40:41 -04:00
1444 changed files with 43 additions and 528848 deletions
-28
View File
@@ -1,28 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
### Environment
**Operating System:** (e.g. Windows 2019, macOS-10.15, Linux CentOS 7.4)
**Version / Commit SHA:** (e.g VDB 7.2, SHA: 1a2b3c4d5e...)
**Other:** (e.g compiler, C++ standard etc.)
### Describe the bug
(A clear and concise description of what the bug is.)
### To Reproduce
Steps to reproduce the behavior:
1. Build with '...'
2. Run function '....'
3. See error
### Expected behavior
(A clear and concise description of what you expected to happen.)
### Additional context
(Add any other context about the problem here.)
@@ -1,27 +0,0 @@
---
name: Build / Installation
about: Describe a problem with installation
title: "[BUILD]"
labels: ''
assignees: ''
---
### Environment
**Operating System:** (e.g. Windows 2019, macOS-10.15, Linux CentOS 7.4)
**Version / Commit SHA:** (e.g VDB 7.2, SHA: 1a2b3c4d5e...)
**CMake Version:** (e.g. 3.18)
**Compiler:** (e.g. gcc 10, msvc 2019)
### Describe the problem
(A clear and concise description of the encountered issue.)
### To Reproduce
Steps to reproduce the behavior:
1. Checkout repo '...'
2. Run CMake '....'
3. Build with '....'
4. See error
### Additional context
(Add any other context about the problem here.)
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[REQUEST]"
labels: enhancement
assignees: ''
---
### Is your feature request related to a problem? Please describe.
(A clear and concise description of what the problem is)
### Describe the solution you'd like
(A clear and concise description of what you want to happen.)
### Describe alternatives you've considered
(A clear and concise description of any alternative solutions or features you've considered.)
### Additional context
(Add any other context or screenshots about the feature request here.)
-167
View File
@@ -1,167 +0,0 @@
name: AX
on:
push:
branches:
- 'master'
- 'feature/**'
- 'pr/**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'nanovdb/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
pull_request:
branches:
- '**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'nanovdb/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
schedule:
# run this workflow every day 7am UTC
- cron: '0 7 * * *'
workflow_dispatch:
inputs:
type:
description: 'The type of CI to run (all, mac, linux, grammar)'
required: true
default: 'all'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
linux-ax:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'linux'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: >
linux-ax:${{ matrix.config.image }}-cxx:${{ matrix.config.cxx }}-${{ matrix.config.build }}
container:
image: aswf/ci-openvdb:${{ matrix.config.image }}
env:
CXX: ${{ matrix.config.cxx }}
CCACHE_DIR: /tmp/ccache
strategy:
matrix:
# Only test unified builds (core+ax). weekly CI should test standalone
config:
- { image: '2023-clang15', cxx: 'clang++', build: 'Release', cmake: '' }
- { image: '2023-clang15', cxx: 'g++', build: 'Release', cmake: '' }
- { image: '2023-clang15', cxx: 'clang++', build: 'Debug', cmake: '' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: nanobind
#if: contains(matrix.config.image, '2023') == false
run: ./ci/install_nanobind.sh 2.0.0
- name: install_gtest
run: ./ci/install_gtest.sh 1.15.2
- name: timestamp
id: timestamp
run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: ccache
# don't use ccache for debug builds
if: matrix.config.build == 'Release'
id: ccache
uses: actions/cache@v3
with:
path: /tmp/ccache
key: linux-ax${{ matrix.config.image }}-${{ matrix.config.cxx }}-${{ steps.timestamp.outputs.timestamp }}
restore-keys: linux-ax${{ matrix.config.image }}-${{ matrix.config.cxx }}-
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components='core,python,bin,axcore,axbin,axtest'
--cargs=\"
${{ matrix.config.cmake }}
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DOPENVDB_CXX_STRICT=ON
\"
- name: test
run: cd build && ctest -V
- name: test_doxygen_examples
run: ./ci/extract_test_examples.sh
# Keep ccache light by stripping out any caches not accessed in the last day
- name: ccache_clean
if: matrix.config.build == 'Release'
run: ccache --evict-older-than 1d
macos-ax:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'mac'
runs-on: ${{ matrix.config.runner }}
name: macos-cxx:${{ matrix.config.cxx }}-llvm:${{ matrix.config.llvm }}-${{ matrix.config.build }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
# Last macos runner before M1 (macos-14)
- { runner: 'macos-13', cxx: 'clang++', build: 'Release', llvm: '15' }
- { runner: 'macos-13', cxx: 'clang++', build: 'Release', llvm: '13' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install_deps
run: |
./ci/install_macos.sh ${{ matrix.config.llvm }}
./ci/install_tbb_macos.sh
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components="core,python,bin,axcore,axbin,axtest"
--cargs=\"
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install
-DLLVM_DIR=/opt/homebrew/opt/llvm@${{ matrix.config.llvm }}/lib/cmake/llvm
\"
- name: test
run: cd build && ctest -V
- name: test_doxygen_examples
run: ./ci/extract_test_examples.sh
gen-grammar:
if: |
github.event_name == 'workflow_dispatch' &&
github.event.inputs.type == 'grammar'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
container:
image: aswf/ci-openvdb:2023-clang15
steps:
- uses: actions/checkout@v3
- name: build
run: ./ci/build.sh -v --components=axgr --target=openvdb_ax_grammar --cargs=\"-DOPENVDB_AX_GRAMMAR_NO_LINES=ON\"
- name: upload grammar
uses: actions/upload-artifact@v4
with:
name: ax_grammar
path: ./build/openvdb_ax/openvdb_ax/openvdb_ax/grammar
retention-days: 5
-193
View File
@@ -1,193 +0,0 @@
name: Build
on:
push:
branches:
- 'master'
- 'feature/**'
- 'pr/**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'openvdb_ax/**'
- 'nanovdb/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
pull_request:
branches:
- '**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'openvdb_ax/**'
- 'nanovdb/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
schedule:
# run this workflow every day at 7am UTC except Monday
- cron: '0 7 * * 0,2-6'
# run this workflow Monday 7am UTC
# warning: This pattern is checked in various places below
- cron: '0 7 * * 1'
workflow_dispatch:
inputs:
type:
description: 'The type of CI to run (all, linux, win, mac)'
required: true
default: 'all'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
linux-vfx:
# VFX platform jobs. These are run on the appropriate CentOS images from
# the provided ASWF docker containers
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'linux'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: >
linux-vfx:${{ matrix.config.image }}-
abi:${{ matrix.config.abi }}-
cxx:${{ matrix.config.cxx }}-
type:${{ matrix.config.build }}
container:
image: aswf/ci-openvdb:${{ matrix.config.image }}
env:
CXX: ${{ matrix.config.cxx }}
CCACHE_DIR: /tmp/ccache
strategy:
matrix:
config:
- { cxx: clang++, image: '2024', abi: '12', build: 'Release', cmake: '' }
- { cxx: g++, image: '2024', abi: '12', build: 'Release', cmake: '' }
- { cxx: clang++, image: '2024', abi: '12', build: 'Debug', cmake: '' }
- { cxx: clang++, image: '2023', abi: '11', build: 'Release', cmake: '-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON' }
- { cxx: g++, image: '2023', abi: '11', build: 'Release', cmake: '-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: nanobind
run: ./ci/install_nanobind.sh 2.0.0
- name: glfw
if: contains(matrix.config.image, '2023') == true
run: ./ci/install_glfw.sh 3.3.10
- name: install_gtest
run: ./ci/install_gtest.sh 1.15.2
- name: timestamp
id: timestamp
run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: ccache
# don't use ccache for debug builds
if: matrix.config.build == 'Release'
id: ccache
uses: actions/cache@v3
with:
path: /tmp/ccache
key: linux-vfx${{ matrix.config.image }}-abi${{ matrix.config.abi }}-${{ matrix.config.cxx }}-${{ steps.timestamp.outputs.timestamp }}
restore-keys: linux-vfx${{ matrix.config.image }}-abi${{ matrix.config.abi }}-${{ matrix.config.cxx }}-
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components=\"core,python,bin,view,render,test\"
--cargs=\"
${{ matrix.config.cmake }}
-DOPENVDB_CXX_STRICT=ON
-DOPENVDB_ABI_VERSION_NUMBER=${{ matrix.config.abi }}
\"
- name: test
# Always run tests on weekly builds but skip Debug on commits as they take a while.
# https://github.community/t/distinct-job-for-each-schedule/17811/2
if: contains(github.event.schedule, '0 7 * * 1') || matrix.config.build == 'Release'
run: |
cd build && ctest -V
cd - && ./ci/test_install.sh
# Keep ccache light by stripping out any caches not accessed in the last day
- name: ccache_clean
if: matrix.config.build == 'Release'
run: ccache --evict-older-than 1d
windows:
# Windows CI. Tests a dynamic build with MD.
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'win'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'windows-2022-8c-32g-300h') || 'windows-latest' }}
name: windows
env:
VCPKG_DEFAULT_TRIPLET: x64-windows
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: path
shell: pwsh
run: |
# note: system path must be modified in a previous step to it's use
echo "$Env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{github.workspace}}\build\openvdb\openvdb\Release" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: build
run: >
./ci/build.sh -v
--config='Release'
--components='core,bin,view,render,python,test'
--cargs=\'
-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF
-DMSVC_COMPRESS_PDB=ON
-DUSE_EXR=ON
-DUSE_PNG=ON
-DVCPKG_TARGET_TRIPLET=${VCPKG_DEFAULT_TRIPLET}
-DCMAKE_TOOLCHAIN_FILE=\"${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake\"
\'
- name: size
# Print the build directy size (monitor if we're hitting runner limits)
run: du -h build
- name: test
run: cd build && ctest -V -C Release
macos:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'mac'
runs-on: macos-13 # Last macos runner befor M1 (macos-14)
env:
CXX: clang++
steps:
- uses: actions/checkout@v3
- name: install
run: |
./ci/install_macos.sh
./ci/install_tbb_macos.sh
- name: build
run: >
./ci/build.sh -v
--build-type=Release
--components=\"core,python,bin,view,render,test\"
--cargs=\'
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install
\'
- name: test
run: cd build && ctest -V
-159
View File
@@ -1,159 +0,0 @@
name: Docs
on:
push:
branches:
- 'master'
- 'feature/**'
- 'pr/**'
paths-ignore:
- 'CHANGES'
- 'openvdb_maya/**'
- 'pendingchanges/**'
- '**.md'
pull_request:
branches:
- '**'
paths-ignore:
- 'CHANGES'
- 'openvdb_maya/**'
- 'pendingchanges/**'
- '**.md'
workflow_dispatch:
inputs:
deploy:
description: 'Deploy to openvdb-website (docs/coverage)?'
required: true
default: 'none'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
doxygen:
runs-on: ubuntu-latest
env:
CXX: g++
container:
# @note We can't update this as epydoc doesn't support python3. We'll
# need to re-write the python docs to use sphinx
image: aswf/ci-openvdb:2024
steps:
- uses: actions/checkout@v4
- name: install_doxygen
run: ./ci/install_doxygen.sh 1_8_11
- name: nanobind
#if: contains(matrix.config.image, '2023') == false
run: ./ci/install_nanobind.sh 2.0.0
# - name: install_epydoc
# run: pip install epydoc
- name: install_latex
run: |
yum -y install texlive-latex-bin texlive-dvips texlive-collection-fontsrecommended texlive-collection-latexrecommended
- name: build
run: >
./ci/build.sh -v
--build-type=Release
--components="core,python,doc"
--cargs=\"
-DUSE_BLOSC=OFF
-DOPENVDB_CORE_STATIC=OFF
-DOPENVDB_PYTHON_WRAP_ALL_GRID_TYPES=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON
\"
# - name: epydoc
# run: |
# epydoc --html -o /usr/local/share/doc/OpenVDB/html/python pyopenvdb
- name: pre_deploy
# Overwrite global SSH configuration
# https://github.com/peaceiris/actions-gh-pages/issues/719
# https://linuxhint.com/ssh-stricthostkeychecking/
run: >
echo "Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
" > /etc/ssh/ssh_config
- name: deploy
# only deploy documentation on a manual workflow dispatch
if: |
github.repository_owner == 'AcademySoftwareFoundation' &&
github.event_name == 'workflow_dispatch' &&
github.event.inputs.deploy == 'docs'
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.PRIVATE_KEY }}
publish_dir: /usr/local/share/doc/OpenVDB/html
destination_dir: documentation/doxygen
external_repository: AcademySoftwareFoundation/openvdb-website
publish_branch: master
full_commit_message: "Automatic doxygen documentation update
- Deployed from: AcademySoftwareFoundation/openvdb ${{ github.sha }}
Signed-off-by: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
#############################################################################
################################ Coverage ###################################
#############################################################################
linux-coverage:
if: |
github.repository_owner == 'AcademySoftwareFoundation' &&
github.event_name == 'workflow_dispatch' &&
github.event.inputs.deploy == 'coverage'
runs-on: ubuntu-latest
container:
image: aswf/ci-openvdb:2023
env:
CXX: g++
steps:
- uses: actions/checkout@v3
- name: install_gcovr
run: pip install gcovr
- name: build
run: >
./ci/build.sh -v
--build-type=coverage
--components="core,axcore,test,axtest"
--cargs=\"-DOPENVDB_CORE_STATIC=OFF -DOPENVDB_AX_STATIC=OFF\"
- name: test_and_gcov
run: |
cd build
ctest -V
make gcov_html
cd -
- name: zip_large_html
# The index.function list is > 100mb. Just zip it and provide it as a
# download (could instead use LFS to host but not really worth it).
run: |
cd build/gcov_html
tar -czvf index.functions.html.tar.gz index.functions.html
sed -i -e 's/index.functions.html/index.functions.html.tar.gz/g' index.html
sed -i -e 's/List of functions/Download function index/g' index.html
rm index.functions.html
cd -
- name: pre_deploy
# Overwrite global SSH configuration
# https://github.com/peaceiris/actions-gh-pages/issues/719
# https://linuxhint.com/ssh-stricthostkeychecking/
run: >
echo "Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
" > /etc/ssh/ssh_config
- name: deploy
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
publish_dir: ./build/gcov_html
destination_dir: documentation/code_coverage
external_repository: AcademySoftwareFoundation/openvdb-website
publish_branch: master
full_commit_message: "Automatic code coverage update
- Deployed from: AcademySoftwareFoundation/openvdb ${{ github.sha }}
Signed-off-by: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
-186
View File
@@ -1,186 +0,0 @@
name: Houdini
on:
push:
branches:
- 'master'
- 'feature/**'
- 'pr/**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'nanovdb/**'
- 'openvdb_maya/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
pull_request:
branches:
- '**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'nanovdb/**'
- 'openvdb_maya/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
schedule:
# run this workflow every day 7am UTC
- cron: '0 7 * * *'
workflow_dispatch:
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
checksecret:
# Check that valid github secrets have been set. This isn't needed to retrieve
# the cache, but ensures that the job doens't start with an empty cache
name: Verify Houdini Secrets
runs-on: ubuntu-latest
outputs:
HOUDINI_SECRETS: ${{ steps.check.outputs.HOUDINI_SECRETS }}
steps:
- id: check
env:
HOUDINI_CLIENT_ID: ${{ secrets.HOUDINI_CLIENT_ID }}
HOUDINI_SECRET_KEY: ${{ secrets.HOUDINI_SECRET_KEY }}
run: echo "HOUDINI_SECRETS=${{ env.HOUDINI_CLIENT_ID != '' && env.HOUDINI_SECRET_KEY != '' }}" >> $GITHUB_OUTPUT
- name: Skip Next Jobs
if: steps.check.outputs.HOUDINI_SECRETS != 'true'
run: echo "HOUDINI_CLIENT_ID and HOUDINI_SECRET_KEY GitHub Action Secrets needs to be set to install Houdini builds"
linux-vfx-houdini:
needs: [checksecret]
if: >
${{ needs.checksecret.outputs.HOUDINI_SECRETS == 'true' ||
github.repository_owner == 'AcademySoftwareFoundation' }}
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: hou:${{ matrix.config.hou_hash }}-vfx:${{ matrix.config.image }}-cxx:${{ matrix.config.cxx }}
container:
image: aswf/ci-base:${{ matrix.config.image }}
env:
CXX: ${{ matrix.config.cxx }}
CCACHE_DIR: /tmp/ccache
strategy:
matrix:
config:
- { cxx: clang++, image: '2024', hou_hash: '20_5', build: 'Release', components: 'core,hou,bin,view,render,python,test' }
- { cxx: clang++, image: '2023', hou_hash: '20_5', build: 'Debug', components: 'core,hou,bin,view,render,python,test,axcore,axbin,axtest' }
- { cxx: g++, image: '2023', hou_hash: '20_5', build: 'Release', components: 'core,hou,bin,view,render,python,test,axcore,axbin,axtest' }
- { cxx: clang++, image: '2023', hou_hash: '20_0-newabi', build: 'Release', components: 'core,hou,bin,view,render,python,test,axcore,axbin,axtest' }
- { cxx: g++, image: '2023', hou_hash: '20_0-newabi', build: 'Release', components: 'core,hou,bin,view,render,python,test,axcore,axbin,axtest' }
fail-fast: false
steps:
- name: remove zstd
run: yum -y remove zstd
- uses: actions/checkout@v3
- name: nanobind
#if: contains(matrix.config.image, '2023') == false
run: ./ci/install_nanobind.sh 2.0.0
- name: glfw
if: contains(matrix.config.image, '2023') == true
run: ./ci/install_glfw.sh 3.3.10
- name: cppunit
run: ./ci/install_cppunit.sh 1.15.1
- name: install_gtest
run: ./ci/install_gtest.sh 1.15.2
- name: timestamp
id: timestamp
run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: ccache
# don't use ccache for debug builds
if: matrix.config.build == 'Release'
id: ccache
uses: actions/cache@v3
with:
path: /tmp/ccache
key: linux-vfx-hou${{ matrix.config.hou_hash }}-${{ matrix.config.image }}-${{ matrix.config.cxx }}-${{ steps.timestamp.outputs.timestamp }}
restore-keys: linux-vfx-hou${{ matrix.config.hou_hash }}-${{ matrix.config.image }}-${{ matrix.config.cxx }}-
- name: fetch_houdini
uses: actions/cache/restore@v3
with:
path: hou
key: dummy-houdini${{ matrix.config.hou_hash }}-${{ steps.timestamp.outputs.timestamp }}
restore-keys: vdb-v5-houdini${{ matrix.config.hou_hash }}-
- name: validate_houdini
run: test -f "hou/hou.tar.gz"
# Make sure that the unpacked install is NOT in the root of the OpenVDB checkout
# otherwise CMake's install RPATHs wil not work correctly.
- name: install_houdini
run: |
mkdir $HOME/houdini_install
cp hou/hou.tar.gz $HOME/houdini_install/hou.tar.gz
cd $HOME/houdini_install && tar -xzf hou.tar.gz && cd -
- name: build
run: |
./ci/build.sh -v \
--build-type=Release \
--components="${{ matrix.config.components }}" \
--cargs=\" \
-DHOUDINI_ROOT=$HOME/houdini_install/hou \
-DOPENVDB_BUILD_HOUDINI_ABITESTS=OFF \
-DOPENVDB_HOUDINI_INSTALL_PREFIX=/tmp \
-DDISABLE_CMAKE_SEARCH_PATHS=ON \
-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON \
\"
- name: test
run: cd build && ctest -V
# Keep ccache light by stripping out any caches not accessed in the last day
- name: ccache_clean
if: matrix.config.build == 'Release'
run: ccache --evict-older-than 1d
macos-houdini:
needs: [checksecret]
if: >
${{ needs.checksecret.outputs.HOUDINI_SECRETS == 'true' ||
github.repository_owner == 'AcademySoftwareFoundation' }}
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: fetch_houdini
uses: actions/cache/restore@v3
with:
path: hou
key: dummy-houdini
restore-keys: vdb-v5-houdini-macos-
- name: validate_houdini
run: test -f "hou/hou.tar.gz"
# Make sure that the unpacked install is NOT in the root of the OpenVDB checkout
# otherwise CMake's install RPATHs wil not work correctly.
- name: install_houdini
run: |
mkdir $HOME/houdini_install
cp hou/hou.tar.gz $HOME/houdini_install/hou.tar.gz
cd $HOME/houdini_install && tar -xzf hou.tar.gz && cd -
- name: install_deps
run: ./ci/install_macos.sh 15
- name: build
run: |
./ci/build.sh -v \
--build-type=Release \
--components="core,hou,bin,view,render,python,test,axcore,axbin" \
--cargs=\" \
-DHOUDINI_ROOT=$HOME/houdini_install/hou \
-DOPENVDB_BUILD_HOUDINI_ABITESTS=OFF \
-DOPENVDB_HOUDINI_INSTALL_PREFIX=/tmp \
-DDISABLE_CMAKE_SEARCH_PATHS=ON \
-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON \
-DUSE_EXPLICIT_INSTANTIATION=OFF \
-DTbb_INCLUDE_DIR=$HOME/houdini_install/hou/Frameworks/Houdini.framework/Versions/Current/Resources/toolkit/include/tbb \
-DLLVM_DIR=/opt/homebrew/opt/llvm@15/lib/cmake/llvm \
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install \
\"
- name: test
run: cd build && ctest -V
-188
View File
@@ -1,188 +0,0 @@
name: NanoVDB
on:
push:
branches:
- 'master'
- 'feature/**'
- 'pr/**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'openvdb_ax/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
pull_request:
branches:
- '**'
paths-ignore:
- 'CHANGES'
- 'CODEOWNERS'
- 'doc/**'
- 'openvdb_ax/**'
- 'openvdb_maya/**'
- 'openvdb_houdini/**'
- 'fvdb/**'
- 'pendingchanges/**'
- '**.md'
schedule:
# run this workflow every day 7am UTC
- cron: '0 7 * * *'
workflow_dispatch:
inputs:
type:
description: 'The type of CI to run (all, linux, win, mac)'
required: true
default: 'all'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
linux-nanovdb:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'linux'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: >
linux-nanovdb:cxx:${{ matrix.config.cxx }}-${{ matrix.config.build }}
container:
image: aswf/ci-openvdb:${{ matrix.config.image }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
- { cxx: g++, image: '2024', build: 'Release' }
- { cxx: g++, image: '2024', build: 'Debug' }
- { cxx: clang++, image: '2024', build: 'Release' }
- { cxx: clang++, image: '2024', build: 'Debug' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: setup_cuda_12
run: |
yum -y install yum-utils
echo "/usr/local/cuda-12/bin" >> $GITHUB_PATH
echo "LD_LIBRARY_PATH=/usr/local/cuda-12/lib64:$LD_LIBRARY_PATH" >> $GITHUB_ENV
- name: build
# NOTE: CMAKE_POSITION_INDEPENDENT_CODE set to fix default behaviour change in clang 14
# https://github.com/AcademySoftwareFoundation/aswf-docker/issues/228
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components=core,nano,nanotest,nanoexam,nanobench,nanotool
--cargs=\'
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DNANOVDB_USE_CUDA=ON
-DCMAKE_CUDA_ARCHITECTURES="80"
-DNANOVDB_USE_OPENVDB=ON
-DCMAKE_INSTALL_PREFIX=`pwd`
-DUSE_BLOSC=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
\'
- name: test
run: cd build && sudo ctest -V -E ".*cuda.*"
windows-nanovdb:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'win'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'windows-2022-8c-32g-300h') || 'windows-latest' }}
env:
VCPKG_DEFAULT_TRIPLET: 'x64-windows'
visual_studio: "Visual Studio 17 2022"
cuda: "12.4.0"
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: path
run: |
# note: system path must be modified in a previous step to it's use
echo "$Env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{github.workspace}}\build\openvdb\openvdb\Release" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: install_cuda
shell: powershell
run: .\ci\install_windows_cuda.ps1
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: build
shell: bash
run: >
./ci/build.sh -v
--config=Release
--components=core,nano,nanotest,nanoexam,nanobench,nanotool
--cargs=\'
-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF
-DMSVC_COMPRESS_PDB=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DNANOVDB_USE_CUDA=ON
-DCMAKE_CUDA_ARCHITECTURES="80"
-DNANOVDB_USE_OPENVDB=ON
-DVCPKG_TARGET_TRIPLET=${VCPKG_DEFAULT_TRIPLET}
-DCMAKE_TOOLCHAIN_FILE=\"${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake\"
\'
- name: test
shell: bash
run: cd build && ctest -V -E ".*cuda.*"
macos-nanovdb:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'mac'
runs-on: ${{ matrix.config.runner }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
- { runner: 'macos-13', cxx: 'clang++', build: 'Release' }
- { runner: 'macos-13', cxx: 'clang++', build: 'Debug' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install_deps
run: |
./ci/install_macos.sh
./ci/install_tbb_macos.sh
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components=core,nano,nanotest,nanoexam,nanobench,nanotool
--cargs=\'-DUSE_EXPLICIT_INSTANTIATION=OFF -DNANOVDB_USE_CUDA=OFF -DNANOVDB_USE_OPENVDB=ON\'
- name: test
run: cd build && ctest -V -E ".*cuda.*"
nanovdb-lite:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'linux'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
container:
image: aswf/ci-openvdb:2024
steps:
- uses: actions/checkout@v3
- name: install_gtest
run: ./ci/install_gtest.sh 1.15.2
- name: build_and_test
run: |
cd nanovdb/nanovdb
sudo mkdir .build
cd .build
sudo cmake -DUSE_EXPLICIT_INSTANTIATION=OFF -DNANOVDB_BUILD_UNITTESTS=ON -DNANOVDB_USE_OPENVDB=OFF -DNANOVDB_USE_CUDA=OFF ../
sudo make -j8 install
sudo ctest -V
-600
View File
@@ -1,600 +0,0 @@
# This workflow runs once a week and tests a variety of configurations,
# dependencies and other specific or expensive checkes (sanitizers).
# It also contains the Houdini Cache jobs which update the CI cache
# with new Houdini releases.
name: Weekly
on:
schedule:
# run this workflow Sunday 00:00 UTC
- cron: '0 0 * * 0'
workflow_dispatch:
inputs:
type:
description: 'The type of CI to run (all, houdini, latest, extra, ax, blosc, abi)'
required: true
default: 'all'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
#############################################################################
################################## Houdini ##################################
#############################################################################
# Check that valid github secrets have been set for the ability to
# download Houdini and cache it. The secrets are used in download_houdini.py
checksecret:
name: Verify Houdini Secrets
runs-on: ubuntu-latest
outputs:
HOUDINI_SECRETS: ${{ steps.check.outputs.HOUDINI_SECRETS }}
steps:
- id: check
env:
HOUDINI_CLIENT_ID: ${{ secrets.HOUDINI_CLIENT_ID }}
HOUDINI_SECRET_KEY: ${{ secrets.HOUDINI_SECRET_KEY }}
run: echo "HOUDINI_SECRETS=${{ env.HOUDINI_CLIENT_ID != '' && env.HOUDINI_SECRET_KEY != '' }}" >> $GITHUB_OUTPUT
- name: Skip Next Jobs
if: steps.check.outputs.HOUDINI_SECRETS != 'true'
run: echo "HOUDINI_CLIENT_ID and HOUDINI_SECRET_KEY GitHub Action Secrets needs to be set to install Houdini builds"
# Explicitly error on the ASWF repo, we expect this secret to always exist
- name: Error ASWF
if: steps.check.outputs.HOUDINI_SECRETS != 'true' && github.repository_owner == 'AcademySoftwareFoundation'
run: exit 1
# download the latest production version of Houdini X, strip out headers,
# libraries and binaries required for building OpenVDB and put it into
# the GitHub Actions cache
linux_houdini:
needs: [checksecret]
if: |
(needs.checksecret.outputs.HOUDINI_SECRETS == 'true') &&
(github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'houdini')
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: linux-houdini:${{ matrix.config.hou_hash }}
env:
CXX: clang++
HOUDINI_CLIENT_ID: ${{ secrets.HOUDINI_CLIENT_ID }}
HOUDINI_SECRET_KEY: ${{ secrets.HOUDINI_SECRET_KEY }}
strategy:
matrix:
config:
- { houdini_version: '20.0', platform: 'linux_x86_64_gcc11.2', hou_hash: '20_0-newabi' }
- { houdini_version: '20.5', platform: 'linux_x86_64_gcc11.2', hou_hash: '20_5' }
fail-fast: false
container:
image: aswf/ci-base:2024
steps:
- uses: actions/checkout@v3
# We bumped from the 2021 CI image to 2023 here to fix some OpenSSL issues
# with the Houdini download script. In so doing we broke some of the caching
# between this job and the jobs in houdini.yml which _don't_ use the 2023
# image yet. The issue is that the cache action will use zstd if it's
# available to zip the cache and this causes it to be inserted with a unique
# hash which images without zstd (i.e. the 2021/2022 images don't have
# access to). For now, uninstall zstd here instead of installing it
# everywhere and ask the LF to add zstd to the older base images.
- name: remove zstd
run: yum -y remove zstd
- name: timestamp
id: timestamp
run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: download_houdini
run: ./ci/download_houdini.sh ${{ matrix.config.houdini_version }} ${{ matrix.config.platform }} --prod
- name: install_houdini
run: |
mkdir $HOME/houdini_install
cp hou/hou.tar.gz $HOME/houdini_install/hou.tar.gz
cd $HOME/houdini_install && tar -xzf hou.tar.gz && cd -
- name: write_houdini_cache
uses: actions/cache/save@v3
with:
path: hou
key: vdb-v5-houdini${{ matrix.config.hou_hash }}-${{ steps.timestamp.outputs.timestamp }}
macos_houdini:
needs: [checksecret]
if: |
(needs.checksecret.outputs.HOUDINI_SECRETS == 'true') &&
(github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'houdini')
# Note that macos-14 (current macos-latest) switches to M1. We could instead test
# the arm build here instead of the x86 one.
runs-on: macos-latest
name: macos-houdini-20
env:
HOUDINI_CLIENT_ID: ${{ secrets.HOUDINI_CLIENT_ID }}
HOUDINI_SECRET_KEY: ${{ secrets.HOUDINI_SECRET_KEY }}
steps:
- uses: actions/checkout@v3
- name: timestamp
id: timestamp
run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: download_houdini
run: ./ci/download_houdini.sh 20.0 macosx_arm64_clang14.0_13 --prod
- name: install_houdini
run: |
mkdir $HOME/houdini_install
cp hou/hou.tar.gz $HOME/houdini_install/hou.tar.gz
cd $HOME/houdini_install && tar -xzf hou.tar.gz && cd -
- name: write_houdini_cache
uses: actions/cache/save@v3
with:
path: hou
key: vdb-v5-houdini-macos-${{ steps.timestamp.outputs.timestamp }}
#############################################################################
########################### Core Library Extras #############################
#############################################################################
# Extra configuration tests for the OpenVDB Core library. These test a
# variety of options with newer compilers.
linux-extra:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'extra'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: linux-extra:${{ matrix.config.name }}
container:
image: aswf/ci-openvdb:2024
env:
CXX: clang++
strategy:
matrix:
config:
- { name: 'all', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=ON -DUSE_ZLIB=ON -DUSE_EXR=ON -DUSE_PNG=ON' }
- { name: 'lite', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=OFF -DUSE_ZLIB=OFF -DUSE_EXR=OFF -DUSE_PNG=OFF -DOPENVDB_USE_DELAYED_LOADING=OFF' }
- { name: 'half', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=OFF -DUSE_IMATH_HALF=ON' }
- { name: 'sse', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DOPENVDB_SIMD=SSE42' }
- { name: 'avx', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DOPENVDB_SIMD=AVX' }
- { name: 'numpy', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_NUMPY=ON -DOPENVDB_PYTHON_WRAP_ALL_GRID_TYPES=ON' }
- { name: 'asan', build: 'asan', components: 'core,test', cmake: '-DNANOVDB_USE_OPENVDB=ON -DOPENVDB_AX_STATIC=OFF -DOPENVDB_CORE_STATIC=OFF -DUSE_BLOSC=OFF' } # We never called blosc_destroy(), so disable blosc to silence these errors
- { name: 'ubsan', build: 'ubsan', components: 'core,test', cmake: '-DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" ' }
- { name: 'c++20', build: 'Release', components: 'core,test', cmake: '-DCMAKE_CXX_STANDARD=20' }
- { name: 'conf', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: nanobind
#if: contains(container.image, '2023') == false
run: ./ci/install_nanobind.sh 2.0.0
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components="${{ matrix.config.components }}"
--cargs=\"-DOPENVDB_CXX_STRICT=ON ${{ matrix.config.cmake }}\"
- name: test
run: cd build && ctest -V
# Test latest dependencies, latest compilers and options
latest:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'latest'
runs-on: ${{ matrix.config.runson }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
- { runson: ubuntu-latest, cxx: g++, cmake: '' }
# Disable the clang job for now. See https://github.com/actions/runner-images/issues/8659
# - { runson: ubuntu-latest, cxx: clang++, cmake: '' }
# @todo gcc on macos
- { runson: macos-latest, cxx: '', cmake: '-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm@15/bin/clang++ -DLLVM_DIR=/opt/homebrew/opt/llvm@15/lib/cmake/llvm' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install_deps
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get -q install -y libboost-dev libboost-iostreams-dev libtbb-dev libblosc-dev llvm-15-dev libgtest-dev libgmock-dev libcppunit-dev
./ci/install_nanobind.sh 2.0.0
elif [ "$RUNNER_OS" == "macOS" ]; then
./ci/install_macos.sh 15
./ci/install_tbb_macos.sh
else
echo "$RUNNER_OS not supported"; exit 1
fi
- name: build
run: >
./ci/build.sh -v
--build-type=Release
--components=\"core,axcore,python,bin,render,test,axbin\"
--cargs=\"-DCMAKE_CXX_STANDARD=20 -DOPENVDB_USE_DELAYED_LOADING=OFF -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install ${{ matrix.config.cmake }}\"
- name: test
run: cd build && ctest -V
windows:
# Windows CI. Tests static and dynamic builds with MT and MD respectively.
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'win'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'windows-2022-8c-32g-300h') || 'windows-latest' }}
name: windows-vc:${{ matrix.config.vc }}-type:${{ matrix.config.build }}
env:
VCPKG_DEFAULT_TRIPLET: ${{ matrix.config.vc }}
strategy:
matrix:
config:
# static build of blosc from vcpkg does not build internal sources.
# USE_STATIC_DEPENDENCIES is required for IlmBase/OpenEXR defines and
# Boost as both shared and static libs are installed.
# USE_EXPLICIT_INSTANTIATION is disabled for debug static libraries
# due to disk space constraints
- { vc: 'x64-windows-static', components: 'core,bin,view,render,test', build: 'Release', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_SHARED=OFF -DUSE_STATIC_DEPENDENCIES=ON -DBLOSC_USE_EXTERNAL_SOURCES=ON' }
- { vc: 'x64-windows', components: 'core,bin,view,render,python,test', build: 'Release', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF' }
- { vc: 'x64-windows', components: 'core,bin,view,render,python,test', build: 'Debug', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: path
shell: pwsh
run: |
# note: system path must be modified in a previous step to it's use
echo "$Env:VCPKG_INSTALLATION_ROOT\installed\${{ matrix.config.vc }}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{github.workspace}}\build\openvdb\openvdb\${{ matrix.config.build }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: build
run: >
./ci/build.sh -v
--config=${{ matrix.config.build }}
--components=${{ matrix.config.components }}
--cargs=\'
${{ matrix.config.cmake }}
-DMSVC_COMPRESS_PDB=ON
-DUSE_EXR=ON
-DUSE_PNG=ON
-DVCPKG_TARGET_TRIPLET=${VCPKG_DEFAULT_TRIPLET}
-DCMAKE_TOOLCHAIN_FILE=\"${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake\"
\'
- name: size
# Print the build directy size (monitor if we're hitting runner limits)
run: du -h build
- name: test
# Always run tests on weekly builds but skip Debug on commits as they take a while.
# https://github.community/t/distinct-job-for-each-schedule/17811/2
if: contains(github.event.schedule, '0 7 * * 1') || matrix.config.build == 'Release'
run: cd build && ctest -V -C ${{ matrix.config.build }}
#############################################################################
############################ AX Library Extras ##############################
#############################################################################
linux-ax:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'ax'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: >
linux-ax:${{ matrix.config.image }}-cxx:${{ matrix.config.cxx }}-${{ matrix.config.build }}
container:
image: aswf/ci-openvdb:${{ matrix.config.image }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
# Unified
- { image: '2023-clang15', cxx: 'clang++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' }
- { image: '2023-clang15', cxx: 'g++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: nanobind
#f: contains(matrix.config.image, '2023') == false
run: ./ci/install_nanobind.sh 2.0.0
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components=${{ matrix.config.components }}
--cargs=\"
${{ matrix.config.cmake }}
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DOPENVDB_CXX_STRICT=ON
-DOPENVDB_BUILD_VDB_TOOL=OFF
\"
- name: clean
if: matrix.config.components == 'core'
run: rm -rf build
- name: build
if: matrix.config.components == 'core'
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components="bin,axcore,axbin,axtest,python"
--cargs=\"
${{ matrix.config.cmake }}
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DOPENVDB_CXX_STRICT=ON
-DOPENVDB_BUILD_VDB_TOOL=OFF
\"
- name: test
run: cd build && ctest -V
- name: test_doxygen_examples
run: ./ci/extract_test_examples.sh
macos-ax:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'ax'
runs-on: macos-13
name: macos-cxx:${{ matrix.config.cxx }}-llvm:${{ matrix.config.llvm }}-${{ matrix.config.build }}
env:
CXX: ${{ matrix.config.cxx }}
strategy:
matrix:
config:
- { cxx: 'clang++', build: 'Release', llvm: '15' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install_deps
run: |
./ci/install_macos.sh ${{ matrix.config.llvm }}
./ci/install_tbb_macos.sh
- name: build
run: >
./ci/build.sh -v
--build-type=${{ matrix.config.build }}
--components="core,python,bin,axcore,axbin,axtest"
--cargs=\"
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install
-DLLVM_DIR=/opt/homebrew/opt/llvm@${{ matrix.config.llvm }}/lib/cmake/llvm
\"
- name: test
run: cd build && ctest -V
- name: test_doxygen_examples
run: ./ci/extract_test_examples.sh
windows-ax:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'ax'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'windows-2022-8c-32g-300h') || 'windows-latest' }}
name: windows-vc:${{ matrix.config.vc }}-type:${{ matrix.config.build }}
env:
VCPKG_DEFAULT_TRIPLET: ${{ matrix.config.vc }}
# Export this with '' avoid bash treating \ as escape
VDB_INSTALL_PREFIX: '${{ github.workspace }}\\install'
strategy:
matrix:
config:
# static build of blosc from vcpkg does not build internal sources.
# USE_STATIC_DEPENDENCIES is required for IlmBase/OpenEXR defines and
# Boost as both shared and static libs are installed.
# @todo We don't currently run the axtests with shared builds of ax
# due to symbol issues using LLVM as a static lib (which is the only
# option on Windows).
- { vc: 'x64-windows', crt: 'MD', components: 'core,bin,axcore,axbin,python', build: 'Release', cmake: '-DOPENVDB_CORE_STATIC=OFF -DOPENVDB_AX_STATIC=OFF' }
- { vc: 'x64-windows-static', crt: 'MT', components: 'core,bin,axcore,axbin,axtest', build: 'Release', cmake: '-DOPENVDB_CORE_SHARED=OFF -DOPENVDB_AX_SHARED=OFF -DUSE_STATIC_DEPENDENCIES=ON -DBLOSC_USE_EXTERNAL_SOURCES=ON' }
- { vc: 'x64-windows-static', crt: 'MTd', components: 'core,bin,axcore,axbin,axtest', build: 'Debug', cmake: '-DOPENVDB_CORE_SHARED=OFF -DOPENVDB_AX_SHARED=OFF -DUSE_STATIC_DEPENDENCIES=ON -DBLOSC_USE_EXTERNAL_SOURCES=ON' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: llvm
run: ./ci/install_llvm_windows.sh ${{ matrix.config.crt }}
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: build
run: >
./ci/build.sh -v
--config=${{ matrix.config.build }}
--components="${{ matrix.config.components }}"
--cargs=\'
-A x64 -G \"Visual Studio 17 2022\"
-DVCPKG_TARGET_TRIPLET=${VCPKG_DEFAULT_TRIPLET}
-DCMAKE_TOOLCHAIN_FILE=\"${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake\"
-DMSVC_COMPRESS_PDB=ON
-DOPENVDB_AX_TEST_CMD_DOWNLOADS=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DLLVM_DIR=\"${HOME}\\llvm_install\\lib\\cmake\\llvm\"
-DCMAKE_INSTALL_PREFIX=\"${VDB_INSTALL_PREFIX}\"
${{ matrix.config.cmake }}
\'
- name: runtime_path
shell: pwsh
run: |
# note: system path must be modified in a previous step to it's use
echo "$Env:VCPKG_INSTALLATION_ROOT\installed\${{ matrix.config.vc }}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "$Env:VDB_INSTALL_PREFIX\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: test
run: cd build && ctest -V -C ${{ matrix.config.build }}
#############################################################################
################################## Blosc ####################################
#############################################################################
windows-nanovdb:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'win'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'windows-2022-8c-32g-300h') || 'windows-latest' }}
env:
VCPKG_DEFAULT_TRIPLET: ${{ matrix.config.vc }}
visual_studio: "Visual Studio 17 2022"
cuda: "12.4.0"
strategy:
matrix:
config:
# static build of blosc from vcpkg does not build internal sources.
# USE_STATIC_DEPENDENCIES is required for IlmBase/OpenEXR defines and
# Boost as both shared and static libs are installed.
- { vc: 'x64-windows-static', build: 'Release', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_SHARED=OFF -DUSE_STATIC_DEPENDENCIES=ON -DBLOSC_USE_EXTERNAL_SOURCES=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded' }
- { vc: 'x64-windows-static', build: 'Debug', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_SHARED=OFF -DUSE_STATIC_DEPENDENCIES=ON -DBLOSC_USE_EXTERNAL_SOURCES=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug' }
- { vc: 'x64-windows', build: 'Release', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF' }
- { vc: 'x64-windows', build: 'Debug', cmake: '-A x64 -G \"Visual Studio 17 2022\" -DOPENVDB_CORE_STATIC=OFF' }
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: path
shell: powershell
run: |
# note: system path must be modified in a previous step to it's use
echo "$Env:VCPKG_INSTALLATION_ROOT\installed\${{ matrix.config.vc }}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{github.workspace}}\build\openvdb\openvdb\${{ matrix.config.build }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: install_cuda
shell: powershell
run: .\ci\install_windows_cuda.ps1
- name: install
shell: powershell
run: .\ci\install_windows.ps1
- name: build
shell: bash
run: >
./ci/build.sh -v
--config=${{ matrix.config.build }}
--components=core,nano,nanotest,nanoexam,nanobench,nanotool
--cargs=\'
${{ matrix.config.cmake }}
-DMSVC_COMPRESS_PDB=ON
-DUSE_EXPLICIT_INSTANTIATION=OFF
-DNANOVDB_USE_CUDA=ON
-DCMAKE_CUDA_ARCHITECTURES="80"
-DNANOVDB_USE_OPENVDB=ON
-DVCPKG_TARGET_TRIPLET=${VCPKG_DEFAULT_TRIPLET}
-DCMAKE_TOOLCHAIN_FILE=\"${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake\"
\'
- name: test
shell: bash
run: cd build && ctest -V -E ".*cuda.*"
#############################################################################
################################## Blosc ####################################
#############################################################################
linux-blosc:
if: |
github.event_name != 'workflow_dispatch' ||
github.event.inputs.type == 'all' ||
github.event.inputs.type == 'blosc'
runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-22.04-8c-32g-300h') || 'ubuntu-latest' }}
name: linux-blosc:${{ matrix.blosc }}
container:
image: aswf/ci-base:2023
strategy:
matrix:
blosc: ['1.18.0','1.19.0','1.20.0','1.21.0']
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install_blosc
run: sudo ./ci/install_blosc.sh ${{ matrix.blosc }}
- name: build
run: >
sudo ./ci/build.sh -v
--build-type=Release
--components=\"core,test\"
- name: test
run: cd build && sudo ctest -V
#############################################################################
################################## ABI ######################################
#############################################################################
linux-abi-checker:
if: |
github.event_name == 'workflow_dispatch' &&
(github.event.inputs.type == 'all' ||
github.event.inputs.type == 'abi')
runs-on: ubuntu-22.04
env:
# The 'abicheck' build type sets these, but older versions of the library
# may not have this build type. See OpenVDBCXX.cmake
CXXFLAGS: "-gdwarf-4 -g3 -ggdb -Og"
steps:
- name: Enable Node 16
run: |
echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV
- uses: actions/checkout@v3
with:
fetch-depth: 0
fetch-tags: true
# Compute the latest major version - that is used as our baseline
# note: For CI forks, make sure you have your tags synced
- name: get_major_version
run: |
LATEST_VERSION_TAG=$(git tag --merged | sort --version-sort | tail -n1)
echo "Computed latest VDB tag: ${LATEST_VERSION_TAG}"
VDB_MAJOR_VERSION=$(echo ${LATEST_VERSION_TAG} | cut -f1 -d '.' | tr -d -c 0-9)
echo "Using major version: ${VDB_MAJOR_VERSION}"
echo "VDB_MAJOR_VERSION=${VDB_MAJOR_VERSION}" >> "$GITHUB_ENV"
- name: install_deps
run: sudo apt-get -q install -y libboost-iostreams-dev libtbb-dev libblosc-dev elfutils
- name: install_abi_checker
run: sudo apt-get -q install -y abi-dumper abi-compliance-checker
- name: build_new
run: >
./ci/build.sh -v
--build-dir=build_new
--build-type=abicheck
--target=openvdb_shared
--components=\"core\"
--cargs=\'-DUSE_EXPLICIT_INSTANTIATION=OFF -DDISABLE_DEPENDENCY_VERSION_CHECKS=ON\'
- name: checkout_baseline
run: git checkout v${VDB_MAJOR_VERSION}.0.0
- name: build_old
run: >
./ci/build.sh -v
--build-dir=build_old
--build-type=abicheck
--target=openvdb_shared
--components=\"core\"
--cargs=\'-DUSE_EXPLICIT_INSTANTIATION=OFF -DDISABLE_DEPENDENCY_VERSION_CHECKS=ON\'
- name: abi_dump
run: |
abi-dumper build_new/openvdb/openvdb/libopenvdb.so -o ABI-NEW.dump -lver 1
abi-dumper build_old/openvdb/openvdb/libopenvdb.so -o ABI-OLD.dump -lver 2
# Replace the version namespace in the latest ABI dump with the baseline
# version we're comparing against. We should probably instead build the
# latest with the baseline version number but no CMake/defines allow us to
# do this.
- name: replace_symbols
run: sed -i -E 's/openvdb([^v]*)v[0-9]*_[0-9]/openvdb\1v'${VDB_MAJOR_VERSION}'_0/g' ABI-NEW.dump
- name: abi_check
# -strict treats warnings as errors
# -extended checks all member data
# we check everything _not_ in openvdb::**::internal namespace
run: >
abi-compliance-checker -l OPENVDB
-old ABI-OLD.dump
-new ABI-NEW.dump
-skip-internal-symbols "\d(openvdb.*internal)"
-skip-internal-types "(openvdb.*internal)::"
-strict
-extended
- name: upload_report
uses: actions/upload-artifact@v4
if: always()
with:
name: abi_report
path: ./compat_reports/OPENVDB/2_to_1/compat_report.html
retention-days: 5
-40
View File
@@ -1,40 +0,0 @@
name: Whitespace
on:
push:
paths-ignore:
- 'pendingchanges/**'
- 'tsc/meetings/**'
pull_request:
paths-ignore:
- 'pendingchanges/**'
- 'tsc/meetings/**'
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Search the git repository for any trailing spaces excluding meeting notes and auto-generated wlt files
trailingspaces:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: test
run: |
set +e
git grep -n -I -E '^.+[ ]+$' -- ':!tsc/meetings/*' ':!pendingchanges/*' ':!*.wlt'
test $? -eq 1
# Search for any tabs excluding meeting notes, image files and a few others
spacesnottabs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: test
run: |
set +e
git grep -n " " -- ':!*/whitespace.yml' ':!tsc/meetings/*' ':!*.svg' ':!*.cmd' ':!*.png' ':!pendingchanges/*' ':!*.wlt' ':!*.jpg' ':!*.gif' ':!*.mp4' ':!*.pt' ':!*.pth' ':!*.nvdb' ':!*.npz'
test $? -eq 1
+2
View File
@@ -1,2 +1,4 @@
/build/*
**/src/benchmarks/build/*
nanovdb/nanovdb/build/*
.DS_Store
-3676
View File
File diff suppressed because it is too large Load Diff
-618
View File
@@ -1,618 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
CMake Configuration for OpenVDB
The OpenVDB CMake build system generates targets depending on the
enabled components. It is designed for out of source CMake generation
(a build location for CMake to write to will be required). For example,
from the root of the repository:
mkdir build
cd build
cmake ../
Depending on the components you choose to build, a number of optional
and required dependencies are expected. See the dependency documentation
for more information:
https://www.openvdb.org/documentation/doxygen/dependencies.html
And the documentation on building OpenVDB for more in depth installation
instructions:
https://www.openvdb.org/documentation/doxygen/build.html
This CMakeLists file provides most available options for configuring the
build and installation of all OpenVDB components. By default the core
library and the vdb_print binary are enabled.
Note that various packages have inbuilt CMake module support. See the
CMake documentation for more ZLib, Doxygen, OpenGL, Boost and Python
controls:
https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html
OpenVDB's CMake supports building the various components of against a
prior installation of OpenVDB.
#]=======================================================================]
# note: cmake_minimum_required must be called before project commands to
# ensure policy scope is set up correctly
cmake_minimum_required(VERSION 3.20)
# CMP0091 allows for MSVC ABI targetting via CMAKE_MSVC_RUNTIME_LIBRARY
# from CMake 3.15 and above. Must come before project().
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
###### Version
set(OpenVDB_MAJOR_VERSION 12)
set(OpenVDB_MINOR_VERSION 0)
set(OpenVDB_PATCH_VERSION 2)
set(OpenVDB_VERSION "${OpenVDB_MAJOR_VERSION}.${OpenVDB_MINOR_VERSION}.${OpenVDB_PATCH_VERSION}")
project(OpenVDB LANGUAGES CXX VERSION ${OpenVDB_VERSION})
###### OpenVDB Build/Component Options
include(CMakeDependentOption)
include(GNUInstallDirs)
# Components
option(OPENVDB_BUILD_CORE "Enable the core OpenVDB library. Both static and shared versions are enabled by default" ON)
option(OPENVDB_BUILD_BINARIES "Enable the vdb binaries. Only vdb_print is enabled by default" ON)
option(OPENVDB_BUILD_PYTHON_MODULE "Build the pyopenvdb Python module" OFF)
option(OPENVDB_BUILD_UNITTESTS "Build the OpenVDB unit tests" OFF)
option(OPENVDB_BUILD_DOCS "Build the OpenVDB documentation" OFF)
option(OPENVDB_BUILD_HOUDINI_PLUGIN "Build the Houdini plugin" OFF)
option(OPENVDB_BUILD_HOUDINI_ABITESTS "Build the Houdini ABI tests" OFF)
option(OPENVDB_BUILD_MAYA_PLUGIN "Build the Maya plugin" OFF)
option(OPENVDB_BUILD_AX "Build the OpenVDB AX library. Turns ON if USE_AX is ON." ${USE_AX})
option(OPENVDB_BUILD_AX_UNITTESTS "Build the OpenVDB AX unit tests" OFF)
option(OPENVDB_BUILD_NANOVDB "Build the NanoVDB library. Turns ON if USE_NANOVDB is ON." ${USE_NANOVDB})
# Global options
option(OPENVDB_ENABLE_RPATH "Build with RPATH information" ON)
option(OPENVDB_ENABLE_ASSERTS "Build with asserts in OpenVDB code enabled" OFF)
option(OPENVDB_USE_DELAYED_LOADING "Build the core OpenVDB library with delayed-loading." ON)
option(OPENVDB_CXX_STRICT "Enable or disable pre-defined compiler warnings" OFF)
cmake_dependent_option(OPENVDB_INSTALL_CMAKE_MODULES
"Install the provided OpenVDB CMake modules when building the core library"
ON "OPENVDB_BUILD_CORE" OFF)
option(USE_CCACHE "Build using Ccache if found on the path" ON)
# Disable this on Windows due to linker OOM issues:
# LNK1248: image size (XXX) exceeds maximum allowable size (FFFFFFFF)
# https://github.com/AcademySoftwareFoundation/openvdb/issues/1718
# https://github.com/AcademySoftwareFoundation/openvdb/issues/1624
cmake_dependent_option(USE_EXPLICIT_INSTANTIATION "Use explicit instantiation for all supported classes
and methods against a pre-defined list of OpenVDB trees. This makes the core library larger and slower
to compile, but speeds up the compilation of all dependent code by bypassing the expensive template
instantation." ON "NOT WIN32" OFF)
option(OPENVDB_FUTURE_DEPRECATION "Generate messages for upcoming deprecation" ON)
option(OPENVDB_ENABLE_UNINSTALL "Adds a CMake uninstall target." ON)
option(USE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF)
# Component dependency options
cmake_dependent_option(USE_PKGCONFIG "Use pkg-config to search for dependent libraries." ON "NOT WIN32" OFF)
option(USE_HOUDINI [=[
Build the library against a Houdini installation. Turns on automatically if OPENVDB_BUILD_HOUDINI_PLUGIN is enabled.
When enabled, you do not need to provide dependency locations for TBB, Blosc, Imath and OpenEXR. Boost must be
provided. Imath/OpenEXR can optionally be provided.]=] OFF)
option(USE_MAYA [=[
Build the library against a Maya installation. Turns on automatically if OPENVDB_BUILD_MAYA_PLUGIN is enabled.
When enabled, you do not need to provide dependency locations for TBB. All other dependencies must be provided.]=] OFF)
option(USE_TBB [=[
Use TBB in building the NanoVDB library.]=] ON)
option(USE_BLOSC [=[
Use blosc while building openvdb components. If OPENVDB_BUILD_CORE is OFF, CMake attempts to query the located
openvdb build configuration to decide on blosc support. You may set this to on to force blosc to be used if you
know it to be required.]=] ON)
option(USE_ZLIB [=[
Use zlib while building openvdb components. If OPENVDB_BUILD_CORE is OFF, CMake attempts to query the located
openvdb build configuration to decide on zlib support. ZLib can only be disabled if Blosc is also disabled. ]=] ON)
option(USE_LOG4CPLUS [=[
Use log4cplus while building openvdb components. If OPENVDB_BUILD_CORE is OFF, CMake attempts to query the
located openvdb build configuration to decide on log4cplus support. You may set this to on to force log4cplus
to be used if you know it to be required.]=] OFF)
option(USE_EXR [=[
Use OpenEXR while building openvdb components. If enabled, this also switches USE_IMATH_HALF to ON unless
it too was provided and set to OFF.]=] OFF)
option(USE_IMATH_HALF [=[
Use the definiton of half floating point types from the Imath library. If OFF, the embedded definition provided
by OpenVDB is used. If OPENVDB_BUILD_CORE is OFF, CMake attempts to query the located openvdb build configuration
to select the correct half support. You may set this to on to force Imath half to be used if you know it to be
required.]=] ${USE_EXR})
option(USE_PNG "Use PNG while building openvdb components." OFF)
option(USE_AX "Use OpenVDB AX while building openvdb components." ${OPENVDB_BUILD_AX})
option(USE_NANOVDB "Use NanoVDB while building openvdb components." ${OPENVDB_BUILD_NANOVDB})
cmake_dependent_option(OPENVDB_DISABLE_BOOST_IMPLICIT_LINKING
"Disable the implicit linking of Boost libraries on Windows" ON "WIN32" OFF)
option(USE_STATIC_DEPENDENCIES [=[
Only search for and use static libraries. If OFF the shared versions of requried libraries are prioritised, falling
back to static libraries. Forcing individual static dependencies can be enabled by setting XXX_USE_STATIC_LIBS
to ON, where XXX is the package name. On Windows this behaviour is less strict, with any located libraries assumed
to be static. This has no effect for any packages found with Xxx_DIR (i.e. CMake CONFIG mode).]=] OFF)
option(DISABLE_DEPENDENCY_VERSION_CHECKS [=[
Disable minimum version checks for OpenVDB dependencies. It is strongly recommended that this remains disabled.
Consider updating your dependencies where possible if encountering minimum requirement CMake errors.]=] OFF)
option(DISABLE_CMAKE_SEARCH_PATHS [=[
Disable CMakes default system search paths when locating dependencies. When enabled, CMake will fall back to
its default system search routine if it cannot find a dependency with the provided settings. When disabled, only
paths provided through the Xxx_ROOT, supported XXX_INCLUDEDIR/XXX_LIBRARYDIR variables or the SYSTEM_LIBRARY_PATHS
list will be searched.]=] OFF)
set(SYSTEM_LIBRARY_PATHS "" CACHE STRING [=[
A global list of library paths to additionally use into when searching for dependencies.]=])
set(MSVC_MP_THREAD_COUNT "" CACHE STRING [=[
The number of threads to use when invoking MSVC builds with cmake --build. CMake defaults to 1. Note that
cmake --parallel and CMAKE_BUILD_PARALLEL_LEVEL only change the number of PROJECTS that are built in parallel,
NOT the number of TU's ]=])
option(MSVC_COMPRESS_PDB "Whether to attempt to compress PDB symbol data in MSVC debug builds." OFF)
set(_CONCURRENT_MALLOC_OPTIONS None Auto Jemalloc Tbbmalloc)
if(NOT CONCURRENT_MALLOC)
set(CONCURRENT_MALLOC Auto CACHE STRING
"Explicitly link the OpenVDB executables against a particular concurrent malloc library.
Options are: None Auto Jemalloc Tbbmalloc. Although not required, it is strongly recommended
to use a concurrent memory allocator. Has no effect if OPENVDB_BUILD_BINARIES and
OPENVDB_BUILD_UNITTESTS are false. Auto is the default and implies Jemalloc, unless USE_MAYA
is ON or Jemalloc is unavailable, in which case Tbbmalloc is used. Note that this is not
linked into library builds and defers this choice to downstream applications via explicit
CMake targets." FORCE
)
elseif(NOT ${CONCURRENT_MALLOC} IN_LIST _CONCURRENT_MALLOC_OPTIONS)
message(WARNING "Unrecognized value for CONCURRENT_MALLOC, using Auto instead.")
set(CONCURRENT_MALLOC Auto CACHE STRING FORCE)
endif()
set(_OPENVDB_SIMD_OPTIONS None SSE42 AVX)
if(NOT OPENVDB_SIMD)
set(OPENVDB_SIMD None CACHE STRING
"Choose whether to enable SIMD compiler flags or not, options are: None SSE42 AVX.
Although not required, it is strongly recommended to enable SIMD. AVX implies SSE42.
None is the default." FORCE
)
elseif(NOT ${OPENVDB_SIMD} IN_LIST _OPENVDB_SIMD_OPTIONS)
message(WARNING "Unrecognized or unsupported value for OPENVDB_SIMD, "
"using None instead.")
set(OPENVDB_SIMD None CACHE STRING FORCE)
endif()
if(USE_BLOSC AND NOT USE_ZLIB)
message(WARNING "ZLib can only be disabled if Blosc is also disabled. Enabling ZLib.")
endif()
if(USE_NANOVDB)
if(OPENVDB_BUILD_CORE AND NOT OPENVDB_BUILD_NANOVDB)
message(FATAL_ERROR "Invalid CMake build configuration:
OPENVDB_BUILD_CORE: [ON]
OPENVDB_BUILD_NANOVDB: [OFF]
USE_NANOVDB: [ON]
If you are rebuilding the core library and using sub components, building
these sub components must also be enabled (i.e. -DOPENVDB_BUILD_NANOVDB=ON).")
endif()
endif()
if(USE_AX)
if(OPENVDB_BUILD_CORE AND NOT OPENVDB_BUILD_AX)
message(FATAL_ERROR "Invalid CMake build configuration:
OPENVDB_BUILD_CORE: [ON]
OPENVDB_BUILD_AX: [OFF]
USE_AX: [ON]
If you are rebuilding the core library and using sub components, building
these sub components must also be enabled (i.e. -DOPENVDB_BUILD_AX=ON).")
endif()
endif()
if(OPENVDB_BUILD_HOUDINI_PLUGIN OR OPENVDB_BUILD_HOUDINI_ABITESTS)
set(USE_HOUDINI ON)
endif()
if(OPENVDB_BUILD_MAYA_PLUGIN)
set(USE_MAYA ON)
endif()
if(USE_MAYA AND USE_HOUDINI)
# @todo technically this is possible so long as library versions match
# exactly but it's difficult to validate and dangerous
message(FATAL_ERROR "Cannot build both Houdini and Maya plugins against "
"the same core dependencies. Plugins must be compiled separately to "
"ensure the required DCC dependencies are met.")
endif()
###### Deprecated options
if(OPENVDB_CODE_COVERAGE)
message(FATAL_ERROR "The OPENVDB_CODE_COVERAGE option has been removed. Choose instead the unique"
"build type -DCMAKE_BUILD_TYPE=coverage")
endif()
if(OPENVDB_BUILD_HOUDINI_SOPS)
message(FATAL_ERROR "The OPENVDB_BUILD_HOUDINI_SOPS option has been removed. Use OPENVDB_BUILD_HOUDINI_PLUGIN.")
endif()
if(DEFINED USE_SYSTEM_LIBRARY_PATHS)
message(FATAL_ERROR "The USE_SYSTEM_LIBRARY_PATHS option has been removed. Use DISABLE_CMAKE_SEARCH_PATHS.")
endif()
# Various root level CMake options which are marked as advanced
mark_as_advanced(
CONCURRENT_MALLOC
DISABLE_CMAKE_SEARCH_PATHS
DISABLE_DEPENDENCY_VERSION_CHECKS
OPENVDB_BUILD_HOUDINI_ABITESTS
OPENVDB_CXX_STRICT
OPENVDB_ENABLE_RPATH
OPENVDB_USE_DELAYED_LOADING
OPENVDB_FUTURE_DEPRECATION
OPENVDB_SIMD
SYSTEM_LIBRARY_PATHS
USE_CCACHE
USE_COLORED_OUTPUT
USE_HOUDINI
USE_IMATH_HALF
USE_LOG4CPLUS
USE_MAYA
MSVC_COMPRESS_PDB
)
#########################################################################
# Configure MINIMUM and FUTURE_MINIMUM version variables
include(cmake/config/OpenVDBVersions.cmake)
foreach(DEPRECATED_ABI ${OPENVDB_DEPRECATED_ABI_LIST})
option(OPENVDB_USE_DEPRECATED_ABI_${DEPRECATED_ABI} "Bypass minimum ABI requirement checks" OFF)
mark_as_advanced(OPENVDB_USE_DEPRECATED_ABI_${DEPRECATED_ABI})
endforeach()
option(OPENVDB_USE_FUTURE_ABI_${FUTURE_OPENVDB_ABI_VERSION} "Bypass future ABI check" OFF)
mark_as_advanced(OPENVDB_USE_FUTURE_ABI_${FUTURE_OPENVDB_ABI_VERSION})
#########################################################################
enable_testing()
# Add our cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# Add cmake modules to installation command
if(SKBUILD)
set(OPENVDB_INSTALL_BINDIR openvdb/${CMAKE_INSTALL_BINDIR})
set(OPENVDB_INSTALL_LIBDIR openvdb/${CMAKE_INSTALL_LIBDIR})
set(OPENVDB_INSTALL_INCLUDEDIR openvdb/${CMAKE_INSTALL_INCLUDEDIR})
if(OPENVDB_BUILD_NANOVDB)
set(NANOVDB_INSTALL_BINDIR nanovdb/${CMAKE_INSTALL_BINDIR})
set(NANOVDB_INSTALL_LIBDIR nanovdb/${CMAKE_INSTALL_LIBDIR})
set(NANOVDB_INSTALL_INCLUDEDIR nanovdb/${CMAKE_INSTALL_INCLUDEDIR})
set(NANOVDB_INSTALL_DOCDIR nanovdb/${CMAKE_INSTALL_DOCDIR})
endif()
else()
set(OPENVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
set(OPENVDB_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(OPENVDB_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
if(OPENVDB_BUILD_NANOVDB)
set(NANOVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
set(NANOVDB_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(NANOVDB_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
set(NANOVDB_INSTALL_DOCDIR ${CMAKE_INSTALL_DOCDIR})
endif()
endif()
if(OPENVDB_INSTALL_CMAKE_MODULES)
set(OPENVDB_CMAKE_MODULES
cmake/FindBlosc.cmake
cmake/FindJemalloc.cmake
cmake/FindLog4cplus.cmake
cmake/FindOpenEXR.cmake
cmake/FindOpenVDB.cmake
cmake/FindTBB.cmake
cmake/OpenVDBGLFW3Setup.cmake
cmake/OpenVDBHoudiniSetup.cmake
cmake/OpenVDBMayaSetup.cmake
cmake/OpenVDBUtils.cmake
)
install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION ${OPENVDB_INSTALL_LIBDIR}/cmake/OpenVDB)
endif()
# Configure component dependencies by loading the Houdini/Maya setup
# scripts. These also find the Houdini/Maya installations
if(USE_HOUDINI)
include(OpenVDBHoudiniSetup)
endif()
if(USE_MAYA)
include(OpenVDBMayaSetup)
endif()
if(OPENVDB_BUILD_DOCS)
add_subdirectory(doc)
endif()
if(NOT OPENVDB_BUILD_AX AND OPENVDB_BUILD_AX_GRAMMAR)
# only re-generate the AX grammar
set(OPENVDB_AX_SHARED OFF CACHE BOOL "" FORCE)
set(OPENVDB_AX_STATIC OFF CACHE BOOL "" FORCE)
add_subdirectory(openvdb_ax/openvdb_ax)
endif()
# Early exit if there's nothing to build
if(NOT (
OPENVDB_BUILD_CORE OR
OPENVDB_BUILD_BINARIES OR
OPENVDB_BUILD_AX OR
OPENVDB_BUILD_AX_UNITTESTS OR
OPENVDB_BUILD_PYTHON_MODULE OR
OPENVDB_BUILD_UNITTESTS OR
OPENVDB_BUILD_HOUDINI_PLUGIN OR
OPENVDB_BUILD_HOUDINI_ABITESTS OR
OPENVDB_BUILD_MAYA_PLUGIN OR
OPENVDB_BUILD_NANOVDB)
)
return()
endif()
#########################################################################
# ccache setup
if(USE_CCACHE)
find_program(CCACHE_PATH ccache)
if(CCACHE_PATH)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PATH})
message(STATUS "Using ccache: ${CCACHE_PATH}")
endif()
endif()
#########################################################################
# Configure general CMake and CXX settings
include(cmake/config/OpenVDBCXX.cmake)
#########################################################################
# Configure malloc library. Use Jemalloc if available, tbbmalloc otherwise
if(CONCURRENT_MALLOC STREQUAL "Auto")
find_package(Jemalloc QUIET)
if(NOT TARGET Jemalloc::jemalloc)
message(WARNING "Unable to find Jemalloc, attempting to fall back to TBB malloc.
It is recommended to use Jemalloc for optimum performance.")
set(CONCURRENT_MALLOC "Tbbmalloc")
else()
set(CONCURRENT_MALLOC "Jemalloc")
endif()
endif()
# Configure SIMD. AVX implies SSE 4.2.
if(OPENVDB_SIMD STREQUAL "AVX")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-mavx>")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-msse4.2>")
endif()
add_compile_definitions("$<$<COMPILE_LANGUAGE:CXX>:OPENVDB_USE_AVX>")
add_compile_definitions("$<$<COMPILE_LANGUAGE:CXX>:OPENVDB_USE_SSE42>")
elseif(OPENVDB_SIMD STREQUAL "SSE42")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-msse4.2>")
endif()
add_compile_definitions("$<$<COMPILE_LANGUAGE:CXX>:OPENVDB_USE_SSE42>")
endif()
#########################################################################
# Configure our cmake modules to only search for static libraries
if(USE_STATIC_DEPENDENCIES)
set(BLOSC_USE_STATIC_LIBS ON)
set(OPENEXR_USE_STATIC_LIBS ON)
set(TBB_USE_STATIC_LIBS ON)
set(LOG4CPLUS_USE_STATIC_LIBS ON)
set(JEMALLOC_USE_STATIC_LIBS ON)
set(GTEST_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_LIBS ON)
# @todo glfw needs custom support.
# set(GLFW_USE_STATIC_LIBS ON)
endif()
# Configure OpenVDB Library and ABI versions
set(NEEDS_OPENVDB OFF)
if(OPENVDB_BUILD_AX OR
OPENVDB_BUILD_BINARIES OR
OPENVDB_BUILD_UNITTESTS OR
OPENVDB_BUILD_HOUDINI_PLUGIN OR
OPENVDB_BUILD_MAYA_PLUGIN OR
OPENVDB_BUILD_PYTHON_MODULE OR
OPENVDB_BUILD_HOUDINI_ABITESTS)
set(NEEDS_OPENVDB ON)
endif()
if(NOT OPENVDB_BUILD_CORE AND NEEDS_OPENVDB)
# Find VDB installation and determine lib/abi versions. This resets the
# version and ABI numbers
find_package(OpenVDB REQUIRED)
# Check ABI version was found and explicitly error if attempting to build against
# an incompatible Houdini version
if(OpenVDB_ABI AND OPENVDB_HOUDINI_ABI)
if(NOT ${OpenVDB_ABI} EQUAL ${OPENVDB_HOUDINI_ABI})
message(FATAL_ERROR "Located OpenVDB installation is not ABI compatible with "
"Houdini Version ${Houdini_VERSION}. Requires ABI ${OPENVDB_HOUDINI_ABI}, found "
"ABI ${OpenVDB_ABI}.")
endif()
endif()
endif()
message(STATUS "Configuring for OpenVDB Version ${OpenVDB_VERSION}")
# Locate openvdb_ax if necessary
if(NOT OPENVDB_BUILD_AX AND
(OPENVDB_BUILD_AX_UNITTESTS OR
USE_AX))
find_package(OpenVDB REQUIRED COMPONENTS openvdb_ax)
endif()
# Locate nanovdb if necessary
if(NOT OPENVDB_BUILD_NANOVDB AND
USE_NANOVDB)
find_package(OpenVDB REQUIRED COMPONENTS nanovdb)
endif()
# Locate Python and nanobind if necessary
if(OPENVDB_BUILD_PYTHON_MODULE OR (OPENVDB_BUILD_NANOVDB AND NANOVDB_BUILD_PYTHON_MODULE))
# Call find_package(Python ...)
find_package(Python ${MINIMUM_PYTHON_VERSION} REQUIRED COMPONENTS Development Interpreter)
find_package(nanobind ${MINIMUM_NANOBIND_VERSION} REQUIRED)
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_PYTHON_VERSION)
if(Python_VERSION VERSION_LESS ${FUTURE_MINIMUM_PYTHON_VERSION})
message(DEPRECATION "Support for Python versions < ${FUTURE_MINIMUM_GLFW_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
if(NOT DEFINED VDB_PYTHON_INSTALL_DIRECTORY)
if(DEFINED Python_SITELIB)
get_filename_component(Python_PACKAGES_DIR ${Python_SITELIB} NAME)
else()
set(Python_PACKAGES_DIR "site-packages")
endif()
set(VDB_PYTHON_INSTALL_DIRECTORY
${CMAKE_INSTALL_LIBDIR}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/${Python_PACKAGES_DIR}
CACHE STRING "The directory to install the openvdb and nanovdb Python modules."
)
endif()
endif()
# Validate the OpenVDB ABI Version. If OpenVDB_ABI is not set, we're either building
# the core library OR the ABI hasn't been deduced from a VDB installation. Use the
# value from OPENVDB_ABI_VERSION_NUMBER, falling back to the lib major version number
if(NOT OpenVDB_ABI)
if(OPENVDB_ABI_VERSION_NUMBER)
set(OpenVDB_ABI ${OPENVDB_ABI_VERSION_NUMBER})
else()
set(OpenVDB_ABI ${OpenVDB_MAJOR_VERSION})
endif()
endif()
# From the deduced ABI, check against the required ABI for Houdini (if set).
# Forcefully set the ABI to the required value if necessary - do this after to
# explicitly warn the user if their chosen value is different.
if(OPENVDB_HOUDINI_ABI AND (NOT "${OpenVDB_ABI}" EQUAL "${OPENVDB_HOUDINI_ABI}"))
message(WARNING "CMake will explicitly set the value of OPENVDB_ABI_VERSION_NUMBER to "
"${OPENVDB_HOUDINI_ABI} to match the ABI of the target Houdini Version.")
set(OpenVDB_ABI ${OPENVDB_HOUDINI_ABI})
endif()
# Validate ABI value if outside supported range
if(OpenVDB_ABI LESS MINIMUM_OPENVDB_ABI_VERSION)
message(FATAL_ERROR "OpenVDB ABI versions earlier than ${MINIMUM_OPENVDB_ABI_VERSION} are "
"no longer supported.")
endif()
if(OpenVDB_ABI IN_LIST OPENVDB_DEPRECATED_ABI_LIST)
if(NOT OPENVDB_USE_DEPRECATED_ABI_${OpenVDB_ABI})
message(FATAL_ERROR "OpenVDB ABI versions earlier than ${OpenVDB_MAJOR_VERSION} "
"are deprecated. Set CMake option OPENVDB_USE_DEPRECATED_ABI_${OpenVDB_ABI} to ON to "
"suppress this error.")
endif()
message(DEPRECATION "OpenVDB ABI versions earlier than ${OpenVDB_MAJOR_VERSION} "
"are deprecated and will soon be removed.")
# global target definition
add_definitions(-DOPENVDB_USE_DEPRECATED_ABI_${OpenVDB_ABI})
endif()
if(OpenVDB_ABI EQUAL FUTURE_OPENVDB_ABI_VERSION)
if(NOT OPENVDB_USE_FUTURE_ABI_${OpenVDB_ABI})
message(FATAL_ERROR "OpenVDB ABI version ${OpenVDB_ABI} contains changes to ABI that are still "
"in active development and have not been finalized. Set CMake option "
"OPENVDB_USE_FUTURE_ABI_${OpenVDB_ABI} to ON to suppress this error.")
endif()
message(WARNING "OpenVDB ABI version ${OpenVDB_ABI} contains changes to ABI that are still "
"in active development and have not been finalized.")
# global target definition
add_definitions(-DOPENVDB_USE_FUTURE_ABI_${OpenVDB_ABI})
endif()
message(STATUS "Configuring for OpenVDB ABI Version ${OpenVDB_ABI}")
# Always force set as we may need to change it if it's incompatible with Houdini
set(OPENVDB_ABI_VERSION_NUMBER ${OpenVDB_ABI} CACHE STRING [=[
Build for compatibility with version N of the OpenVDB Grid ABI, where N is 6, 7, 8 etc. (some newer features
will be disabled). If OPENVDB_BUILD_CORE is OFF, CMake attempts to query the installed vdb_print binary to
determine the ABI number. You may set this to force a given ABI number.]=] FORCE)
##########################################################################
if(OPENVDB_BUILD_CORE)
add_subdirectory(openvdb/openvdb)
endif()
if(OPENVDB_BUILD_AX)
add_subdirectory(openvdb_ax/openvdb_ax)
endif()
if(OPENVDB_BUILD_PYTHON_MODULE)
add_subdirectory(openvdb/openvdb/python)
endif()
if(OPENVDB_BUILD_BINARIES)
add_subdirectory(openvdb_cmd)
endif()
if(OPENVDB_BUILD_UNITTESTS)
add_subdirectory(openvdb/openvdb/unittest)
endif()
# Tests the vdb_ax binary so needs to come after openvdb_cmd
if(OPENVDB_BUILD_AX_UNITTESTS)
add_subdirectory(openvdb_ax/openvdb_ax/test)
endif()
if(OPENVDB_BUILD_HOUDINI_PLUGIN)
add_subdirectory(openvdb_houdini/openvdb_houdini)
endif()
if(OPENVDB_BUILD_HOUDINI_ABITESTS)
add_subdirectory(openvdb_houdini/openvdb_houdini/abitest)
endif()
if(OPENVDB_BUILD_MAYA_PLUGIN)
add_subdirectory(openvdb_maya/openvdb_maya)
endif()
if(OPENVDB_BUILD_NANOVDB)
add_subdirectory(nanovdb/nanovdb)
endif()
##########################################################################
if(OPENVDB_ENABLE_UNINSTALL)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/Uninstall.cmake
)
endif()
-43
View File
@@ -1,43 +0,0 @@
# See https://help.github.com/articles/about-codeowners/
# for more info about CODEOWNERS file
# It uses the same pattern rule for gitignore file
# https://git-scm.com/docs/gitignore#_pattern_format
# Admin/General
/.github/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
/ci/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
/cmake/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
/doc/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
/pendingchanges/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
/tsc/ @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
CODEOWNERS @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
LICENSE @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
CHANGES @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
*.md @kmuseth @apradhana @jmlait @idclip @danrbailey @richhones
# Core OpenVDB Library
/openvdb/ @kmuseth
/openvdb/openvdb/points/ @danrbailey @idclip
# OpenVDB AX
/openvdb_ax/ @idclip @richhones
# NanoVDB
/nanovdb/ @kmuseth
# OpenVDB Houdini - Default
/openvdb_houdini/ @kmuseth
# OpenVDB Houdini - VDB Primitive and SideFX Utils
/openvdb_houdini/openvdb_houdini/GEO_PrimVDB.* @jmlait
/openvdb_houdini/openvdb_houdini/GU_PrimVDB.* @jmlait
/openvdb_houdini/openvdb_houdini/GEO_VDBTranslator.* @jmlait
/openvdb_houdini/openvdb_houdini/GT_GEOPrimCollectVDB.* @jmlait
/openvdb_houdini/openvdb_houdini/SOP_VDBVerbUtils.* @jmlait
/openvdb_houdini/openvdb_houdini/UT_VDBUtils.* @jmlait
# OpenVDB Houdini - VDB Points
/openvdb_houdini/openvdb_houdini/PointUtils.* @danrbailey @idclip
/openvdb_houdini/openvdb_houdini/*_OpenVDB_Points_* @danrbailey @idclip
/openvdb_houdini/openvdb_houdini/GR_PrimVDBPoints.* @danrbailey @idclip
-1
View File
@@ -1 +0,0 @@
All participants agree to abide by LF Projects Code of Conduct (as defined in the [charter](tsc/charter.md)) available at https://lfprojects.org/policies/code-of-conduct/
-124
View File
@@ -1,124 +0,0 @@
# Overview
This project aims to be governed in a transparent, accessible way for the benefit of the community. All participation in this project is open and not bound to corporate affiliation. Participants are all bound to the [Code of Conduct](CODE_OF_CONDUCT.md).
# Project roles
## Contributor
The contributor role is the starting role for anyone participating in the project and wishing to contribute code.
### Process for becoming a contributor
* Review the [coding standards](https://www.openvdb.org/documentation/doxygen/codingStyle.html) to ensure your contribution is in line with the project's coding and styling guidelines.
* Have a signed CLA on file ( see [below](#contributor-license-agreements) )
* Submit your code as a PR with the appropriate [DCO sign-off](#commit-sign-off).
* Have your submission approved by the [committer(s)](#committer) and merged into the codebase.
### Legal Requirements
OpenVDB is a project of the Academy Software Foundation and follows the
open source software best practice policies of the Linux Foundation.
#### License
OpenVDB is licensed under the [Apache License, version 2.0](LICENSE.md)
license. Contributions to OpenVDB should abide by that standard
license.
#### Contributor License Agreements
Developers who wish to contribute code to be considered for inclusion
in OpenVDB must first complete a **Contributor License Agreement**.
OpenVDB uses [EasyCLA](https://lfcla.com/) for managing CLAs, which automatically
checks to ensure CLAs are signed by a contributor before a commit
can be merged.
* If you are an individual writing the code on your own time and
you're SURE you are the sole owner of any intellectual property you
contribute, you can [sign the CLA as an individual contributor](https://docs.linuxfoundation.org/lfx/easycla/contributors/individual-contributor).
* If you are writing the code as part of your job, or if there is any
possibility that your employers might think they own any
intellectual property you create, then you should use the [Corporate
Contributor Licence
Agreement](https://docs.linuxfoundation.org/lfx/easycla/contributors/corporate-contributor).
The OpenVDB CLAs are the standard forms used by Linux Foundation
projects and [recommended by the ASWF TAC](https://github.com/AcademySoftwareFoundation/tac/blob/master/process/contributing.md#contributor-license-agreement-cla). You can review the text of the CLAs in the [TSC directory](tsc/).
#### Commit Sign-Off
Every commit must be signed off. That is, every commit log message
must include a “`Signed-off-by`” line (generated, for example, with
“`git commit --signoff`”), indicating that the committer wrote the
code and has the right to release it under the
[Apache License, version 2.0](LICENSE.md)
license. See the [TAC documentation on contribution sign off](https://github.com/AcademySoftwareFoundation/tac/blob/master/process/contributing.md#contribution-sign-off) for more information on this requirement.
## Maintainer
The maintainer role is the equivalent of the "Committer" role in the charter.
This role enables the participant to commit code directly to the repository, but also comes with the obligation to be a responsible leader in the community.
### Process for becoming a maintainer
* Show your experience with the codebase through contributions and engagement on the community channels.
* Request to become a maintainer.
* Have the majority of maintainers approve you becoming a maintainer.
* Your name and email is added to the MAINTAINERS.md file for the project.
### Maintainer responsibilities
* Monitor email aliases.
* Monitor Slack (delayed response is perfectly acceptable).
* Triage GitHub issues and perform pull request reviews for other committers and the community.
* Make sure that ongoing PRs are moving forward at the right pace or close them.
* Remain an active contributor to the project in general and the code base in particular.
### When does a maintainer lose maintainer status?
If a maintainer is no longer interested or cannot perform the maintainer duties listed above, they
should volunteer to be moved to emeritus status. In extreme cases this can also occur by a vote of
the maintainers per the voting process below.
## Technical Steering Committee (TSC) member
The Technical Steering Committee (TSC) oversees the overall technical direction of OpenVDB, as defined in the [charter](charter.md).
TSC voting members consist of maintainers that have been nominated by the TSC, with a supermajority of voting members required to have a maintainer elected to be a TSC voting member. TSC voting members term and succession is defined in the [charter](charter.md).
All meetings of the TSC are open to participation by any member of the OpenVDB community. Meeting times are listed in the [ASWF technical community calendar](https://lists.aswf.io/g/tac/calendar).
## Current TSC members
* Ken Museth (Chair), Nvidia
* Andre Pradhana, Nvidia
* Jeff Lait, SideFX
* Nick Avramoussis, WETA FX
* Dan Bailey, ILM
* Richard Jones, ILM
* Gregory Hurst, United Therapeutics
# Release Process
Project releases will occur on a scheduled basis as agreed to by the TSC.
# Conflict resolution and voting
In general, we prefer that technical issues and committer status/TSC membership are amicably worked out
between the persons involved. If a dispute cannot be decided independently, the TSC can be
called in to decide an issue. If the TSC themselves cannot decide an issue, the issue will
be resolved by voting. The voting process is a simple majority in which each TSC receives one vote.
# Communication
This project, just like all of open source, is a global community. In addition to the [Code of Conduct](CODE_OF_CONDUCT.md), this project will:
* Keep all communication on open channels ( mailing list, forums, chat ).
* Be respectful of time and language differences between community members ( such as scheduling meetings, email/issue responsiveness, etc ).
* Ensure tools are able to be used by community members regardless of their region.
If you have concerns about communication challenges for this project, please contact the [TSC](mailto:openvdb-tsc-private@lists.aswf.io).
-18
View File
@@ -1,18 +0,0 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
<!-- Copyright Contributors to the OpenVDB project. -->
# OpenVDB Committers
The current OpenVDB maintainers are:
| Name | Email |
| ---------------- | -----------------
| Jeff Lait | jlait@sidefx.com
| Dan Bailey | danbailey@ilm.com
| Nick Avramoussis | navramoussis@wetafx.co.nz
| Ken Museth | ken.museth@gmail.com
| Andre Pradhana | andre.pradhana@gmail.com
| Richard Jones | richardj@ilm.com
| Gregory Hurst | tbd
| Jonathan Swartz | tbd
-33
View File
@@ -1,33 +0,0 @@
The following copyright holders agree that all of their contributions
originally submitted to this project under the Mozilla Public License
Version 2.0, are hereby relicensed to the Apache License, Version 2.0,
and are submitted pursuant to the Developer Certificate of Origin, version 1.1:
Ken Museth
Mehdi Chinoune
DreamWorks Animation
Side Effects Software Inc.
Blender Foundation
NVIDIA Corporation
United Therapeutics Corporation
Digital Domain 3.0, Inc.
Double Negative
Ubisoft Entertainment SA
Adobe Inc.
Mathieu Malaterre
Brecht Sanders
Ignacio Vizzo
Ben FrantzDale
Sebastian Gaida
Alessio Quaglino
Benedikt Mersch
David Aguilar
Brian Sharpe
Kartik Shrivastava
Michael Lackner
Lucas Baraya
Kuba Roth
Tom Cnops
Walt Disney Pictures (Walt Disney Animation Studios)
The Linux Foundation
Industrial Light & Magic (ILM)
+13 -112
View File
@@ -1,127 +1,28 @@
![OpenVDB](doc/img/banner.png)
# *ƒ*(VDB)
| OpenVDB | AX | Nano | Houdini | License | CII |
| :----: | :----: | :----: | :----: | :-----: | :-: |
| [![core](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/build.yml/badge.svg)](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/build.yml) | [![ax](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/ax.yml/badge.svg)](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/ax.yml) | [![nano](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/nanovdb.yml/badge.svg)](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/nanovdb.yml) | [![hou](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/houdini.yml/badge.svg)](https://github.com/AcademySoftwareFoundation/openvdb/actions/workflows/houdini.yml) | [![License](https://img.shields.io/github/license/AcademySoftwareFoundation/openvdb)](LICENSE) | [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2774/badge)](https://bestpractices.coreinfrastructure.org/projects/2774) |
## A New Home for ƒVDB
-------------------------------------------------------------------------------
:warning: The public home for fVDB development is now located in the Academy Software Foundation OpenVDB Github Organization [https://github.com/openvdb](https://github.com/openvdb). :warning:
[Website](https://www.openvdb.org) |
[Discussion Forum](https://github.com/AcademySoftwareFoundation/openvdb/discussions) |
[Documentation](https://www.openvdb.org/documentation/doxygen) |
[Releases](https://github.com/AcademySoftwareFoundation/openvdb/releases) |
[License](https://www.apache.org/licenses/LICENSE-2.0) |
[Slack](https://slack.aswf.io/)
All of the code and history for fVDB on the OpenVDB `feature/fvdb` branch has been moved to repositories in the OpenVDB Github Organization. In order to encourage movement to fVDB's new home in the OpenVDB Github Organization, we have removed the code from the head of this branch but the history remains.
OpenVDB is an open source C++ library comprising a novel hierarchical data
structure and a large suite of tools for the efficient storage and manipulation
of sparse volumetric data discretized on three-dimensional grids. It was
developed by DreamWorks Animation for use in volumetric applications typically
encountered in feature film production.
The components of fVDB have been split into the following repositories:
### Development Repository
### [fvdb-core](https://github.com/openvdb/fvdb-core)
This GitHub repository hosts the trunk of the OpenVDB development. This implies
that it is the newest public version with the latest features and bug fixes.
However, it also means that it has not undergone a lot of testing and is
generally less stable than the [production releases](https://github.com/AcademySoftwareFoundation/openvdb/releases).
The fvdb-core repository houses the core library and PyTorch extension for ƒVDB. ƒVDB is a framework that provides differentiable, sparse volumetric operators built on top of NanoVDB and enables PyTorch users to utilize the NanoVDB data structure to build powerful and scalable spatial intelligence applications.
### License
OpenVDB is released under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0),
which is a free, open source software license developed and maintained by the
Apache Software Foundation.
### [fvdb-examples](https://github.com/openvdb/fvdb-examples)
The trademarks of any contributor to this project may not be used in
association with the project without the contributor's express permission.
The fvdb-examples repository contains examples of how to use the ƒVDB library to build spatial intelligence networks or pipelines. These are provided as reference for how to implement interesting or well-known methods and networks on top of ƒVDB including examples of pipelines that perform panoptic segmentation and depth reconstruction.
NOTE: OpenVDB has completed re-licensing from [Mozilla Public License Version 2.0](https://www.mozilla.org/MPL/2.0/) to [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please see the file RE-LICENSE_NOTE.txt for more details.
### Contributing
### [fvdb-reality-capture](https://github.com/openvdb/fvdb-reality-capture)
OpenVDB welcomes contributions to the OpenVDB project. Please refer to the
[contribution guidelines](CONTRIBUTING.md) for details on how to make a
contribution.
The fvdb-reality-capture repository contains examples of how to use the ƒVDB library to build reality capture pipelines centered on ƒVDB's 3D Gaussian splatting methods. This repository houses utilities and examples that illustrate how to train and render 3D Gaussian splatting models using ƒVDB as well as interesting methods that build upon the 3D Gaussian scene representation such as meshing.
-------------------------------------------------------------------------------
### Developer Quick Start
### [nanovdb-editor](https://github.com/openvdb/nanovdb-editor)
The following provides basic installation examples for the core OpenVDB library.
Other components, such as the python module, OpenVDB AX, NanoVDB and various
executables, may require additional dependencies. See the
[build documentation](https://www.openvdb.org/documentation/doxygen/build.html)
for help with installations.
##### Linux/MacOS
```bash
# Linux
# @note If your distribution does not have required versions, consider using
# apt pinning. See the dependency documentation for more details.
apt-get install -y libboost-iostreams-dev
apt-get install -y libtbb-dev
apt-get install -y libblosc-dev
# MacOS
# @note We are using homebrew in this example to install requried dependencies
# https://brew.sh/
brew install boost
brew install tbb
brew install c-blosc
```
```bash
git clone git@github.com:AcademySoftwareFoundation/openvdb.git
cd openvdb
mkdir build
cd build
cmake ..
make -j4 && make install
```
##### Windows
Note that the following commands have only been tested for 64bit systems/libraries.
It is recommended to set the `VCPKG_DEFAULT_TRIPLET` environment variable to
`x64-windows` to use 64-bit libraries by default. You will also require
[Visual Studio](https://visualstudio.microsoft.com/downloads/) (for the MSVC C++
runtime and compiler toolchains), [CMake](https://cmake.org/download/) and optionally
[vcpkg](https://github.com/microsoft/vcpkg) for the installation of OpenVDB's
dependencies.
```bash
vcpkg install zlib:x64-windows
vcpkg install blosc:x64-windows
vcpkg install tbb:x64-windows
vcpkg install boost-iostreams:x64-windows
vcpkg install boost-any:x64-windows
vcpkg install boost-algorithm:x64-windows
vcpkg install boost-interprocess:x64-windows
```
```bash
git clone git@github.com:AcademySoftwareFoundation/openvdb.git
cd openvdb
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=<PATH_TO_VCPKG>\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows -A x64 ..
cmake --build . --parallel 4 --config Release --target install
```
#### Building OpenVDB AX and NanoVDB
OpenVDB AX depends on the core OpenVDB library. NanoVDB can be built with and
without OpenVDB support. Note that NanoVDB has its own build instructions, see
the [NanoVDB build documentation](https://www.openvdb.org/documentation/doxygen/NanoVDB_HowToBuild.html)
for details.
The following variables can be passed to the `cmake` configure command. There
are more optional VDB components, see the [build documentation](https://www.openvdb.org/documentation/doxygen/build.html)
for a complete list.
| Option | Details |
| :---- | :----- |
| `-D OPENVDB_BUILD_AX=ON` | to enable OpenVDB AX |
| `-D OPENVDB_BUILD_NANOVDB=ON` | to enable NanoVDB |
| `-D NANOVDB_USE_OPENVDB=ON` | to use OpenVDB in NanoVDB |
The nanovdb-editor repository contains a library, python bindings and a standalone GUI application that allows you to view and edit NanoVDB. nanovdb-editor also provides viewer functionality for fVDB.
-201
View File
@@ -1,201 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -e
CI_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
# print versions
bash --version
if [ ! -z "$CXX" ]; then $CXX -v; fi
cmake --version
CMAKE_VERSION=$(cmake --version | head -n1 | cut -d' ' -f3)
################################################
OPTS_ARGS+=("t:") ## See --target
OPTS_ARGS+=("j:") ## Thread usage
OPTS_ARGS+=("c:") ## See --cargs
OPTS_ARGS+=("v") ## See --verbose
OPTL_ARGS+=("components:") ## Specify cmake component(s) to enable
OPTL_ARGS+=("config:") ## Specify cmake configuration during the build step
OPTL_ARGS+=("target:") ## Specify target(s) to build
OPTL_ARGS+=("build-dir:") ## Build directory
OPTL_ARGS+=("cargs:") ## args to pass directly to cmake generation step
OPTL_ARGS+=("build-type:") ## Release, Debug, etc.
OPTL_ARGS+=("verbose") ## Verbose build output
# Defaults
declare -A PARMS
PARMS[--components]=core,bin
PARMS[--target]=install
PARMS[--build-dir]=build
if [[ $RUNNER_NAME == *"8c-32g-300h"* ]]; then
# ASWF github actions runners have 8 threads
PARMS[-j]=8
else
# Github actions runners have 2 threads
# https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
if [[ $CXX == "g++" ]]; then
# GCC hits memory limits on runners, build in serial
PARMS[-j]=1
else
PARMS[-j]=2
fi
fi
# Available options for --components
declare -A COMPONENTS
COMPONENTS['core']='OPENVDB_BUILD_CORE'
COMPONENTS['python']='OPENVDB_BUILD_PYTHON_MODULE'
COMPONENTS['test']='OPENVDB_BUILD_UNITTESTS'
COMPONENTS['bin']='OPENVDB_BUILD_BINARIES'
COMPONENTS['view']='OPENVDB_BUILD_VDB_VIEW'
COMPONENTS['render']='OPENVDB_BUILD_VDB_RENDER'
COMPONENTS['hou']='OPENVDB_BUILD_HOUDINI_PLUGIN'
COMPONENTS['doc']='OPENVDB_BUILD_DOCS'
COMPONENTS['axcore']='OPENVDB_BUILD_AX'
COMPONENTS['axgr']='OPENVDB_BUILD_AX_GRAMMAR'
COMPONENTS['axbin']='OPENVDB_BUILD_AX_BINARIES'
COMPONENTS['axtest']='OPENVDB_BUILD_AX_UNITTESTS'
COMPONENTS['nano']='OPENVDB_BUILD_NANOVDB'
COMPONENTS['nanotest']='NANOVDB_BUILD_UNITTESTS'
COMPONENTS['nanoexam']='NANOVDB_BUILD_EXAMPLES'
COMPONENTS['nanobench']='NANOVDB_BUILD_BENCHMARK'
COMPONENTS['nanotool']='NANOVDB_BUILD_TOOLS'
################################################
HAS_PARM() {
if [ -z "${PARMS[$1]}" ]; then return 1
else return 0; fi
}
# Format to string and replace spaces with commas
LARGS_STR="${OPTL_ARGS[@]}"
LARGS_STR=${LARGS_STR// /,}
SARGS_STR="${OPTS_ARGS[@]}"
SARGS_STR=${SARGS_STR// /,}
# Parse all arguments and store them in an array, split by whitespace. Error if unsupported
ARGS="$(eval getopt --options=$SARGS_STR --longoptions=$LARGS_STR -- "$@")"
eval set -- "$ARGS"
# split into associative array
while true; do
case "$1" in
-v|--verbose) # options which dont take an argument
PARMS["$1"]="ON"; shift
;;
-[a-z]*|--[a-z]*) # all other arguments (key/values)
PARMS["$1"]="$2"; shift 2
;;
--)
shift; break
;;
esac
done
################################################
# extract arguments
if HAS_PARM -t; then TARGET=${PARMS[-t]}; fi
if HAS_PARM --target; then
if [ -z $TARGET ]; then TARGET=${PARMS[--target]}
else TARGET+=","${PARMS[--target]}; fi
fi
if HAS_PARM -c; then CMAKE_EXTRA=${PARMS[-c]}; fi
if HAS_PARM --cargs; then
if [ -z $CMAKE_EXTRA ]; then CMAKE_EXTRA=${PARMS[--cargs]}
else CMAKE_EXTRA+=" "${PARMS[--cargs]}; fi
fi
BUILD_DIR=${PARMS[--build-dir]}
# handle whitespace
eval "CMAKE_EXTRA=($CMAKE_EXTRA)"
if HAS_PARM -v || HAS_PARM --verbose; then
# Using CMAKE_VERBOSE_MAKEFILE as well as `cmake --verbose` to
# support older versions of CMake.
CMAKE_EXTRA+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
fi
if HAS_PARM --build-type; then
CMAKE_EXTRA+=("-DCMAKE_BUILD_TYPE=${PARMS[--build-type]}")
build_type="${PARMS[--build-type]}"
debug="Debug"
# Ignore case - if the build-type is Debug, we enable asserts
if [ "${build_type,,}" = "${debug,,}" ]; then
CMAKE_EXTRA+=("-DOPENVDB_ENABLE_ASSERTS=ON")
fi
fi
# Available components. If a component is not provided it is
# explicitly set to OFF.
IN_COMPONENTS=${PARMS[--components]}
IFS=', ' read -r -a IN_COMPONENTS <<< "$IN_COMPONENTS"
for comp in "${IN_COMPONENTS[@]}"; do
if [ -z ${COMPONENTS[$comp]} ]; then
echo "Invalid component passed to build \"$comp\""; exit -1
fi
done
# Build Components command
for comp in "${!COMPONENTS[@]}"; do
setting="OFF"
for in in "${IN_COMPONENTS[@]}"; do
if [[ $comp == "$in" ]]; then
setting="ON"; break
fi
done
CMAKE_EXTRA+=("-D${COMPONENTS[$comp]}=$setting")
done
################################################
# github actions runners have 8 threads
# https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
export CMAKE_BUILD_PARALLEL_LEVEL=${PARMS[-j]}
echo "Build using ${CMAKE_BUILD_PARALLEL_LEVEL} threads"
# NOTE: --parallel only effects the number of projects build, not t-units.
# We support this with out own MSVC_MP_THREAD_COUNT option for MSVC.
# Alternatively it is mentioned that the following should work:
# cmake --build . -- /p:CL_MPcount=8
# However it does not seem to for our project.
# https://gitlab.kitware.com/cmake/cmake/-/issues/20564
CMAKE_BUILD_CMD="cmake --build . --parallel ${PARMS[-j]} --target $TARGET --verbose"
if HAS_PARM --config; then
CMAKE_BUILD_CMD+=" --config ${PARMS[--config]}"
fi
################################################
mkdir -p ${BUILD_DIR}
cd ${BUILD_DIR}
# Report the cmake commands
set -x
# Note:
# - print and lod binary options are always on and can be toggles with: OPENVDB_BUILD_BINARIES=ON/OFF
# - always enabled the python tests with OPENVDB_BUILD_PYTHON_UNITTESTS if the python module is in use,
# regardless of the 'test' component being enabled or not (see the OPENVDB_BUILD_PYTHON_UNITTESTS option).
cmake \
-DOPENVDB_USE_DEPRECATED_ABI_10=ON \
-DOPENVDB_USE_DEPRECATED_ABI_11=ON \
-DOPENVDB_BUILD_VDB_PRINT=ON \
-DOPENVDB_BUILD_VDB_LOD=ON \
-DOPENVDB_BUILD_VDB_TOOL=ON \
-DOPENVDB_BUILD_VDB_TOOL_UNITTESTS=ON \
-DOPENVDB_TOOL_USE_NANO=OFF \
-DOPENVDB_BUILD_PYTHON_UNITTESTS=ON \
-DMSVC_MP_THREAD_COUNT=${PARMS[-j]} \
"${CMAKE_EXTRA[@]}" \
..
$CMAKE_BUILD_CMD
-24
View File
@@ -1,24 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
wget -q https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
unzip build-wrapper-linux-x86.zip
mkdir build
cd build
cmake \
-DCMAKE_CXX_COMPILER=g++ \
-DOPENVDB_ABI_VERSION_NUMBER=6 \
-DUSE_BLOSC=ON \
-DOPENVDB_CXX_STRICT=ON \
-DOPENVDB_BUILD_UNITTESTS=ON \
-DOPENVDB_BUILD_BINARIES=OFF \
-DOPENVDB_CORE_STATIC=OFF \
-DOPENVDB_BUILD_PYTHON_MODULE=OFF \
-DOPENVDB_CODE_COVERAGE=ON \
..
../build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw_output make -j2
-220
View File
@@ -1,220 +0,0 @@
#!/usr/bin/env python3
#
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
# Python script to download the latest Houdini builds
# using the SideFX download API:
#
# https://www.sidefx.com/docs/api/download/index.html
#
# Authors: Dan Bailey, SideFX
import time
import sys
import re
import shutil
import json
import base64
import requests
import hashlib
import os
import argparse
import copy
# For progress bar printing
try:
from tqdm import tqdm
has_tqdm = True
except:
has_tqdm = False
pass
# Code that provides convenient Python wrappers to call into the API:
def service(
access_token_url, client_id, client_secret_key, endpoint_url,
access_token=None, access_token_expiry_time=None):
if (access_token is None or
access_token_expiry_time is None or
access_token_expiry_time < time.time()):
access_token, access_token_expiry_time = (
get_access_token_and_expiry_time(
access_token_url, client_id, client_secret_key))
return _Service(
endpoint_url, access_token, access_token_expiry_time)
class _Service(object):
def __init__(
self, endpoint_url, access_token, access_token_expiry_time):
self.endpoint_url = endpoint_url
self.access_token = access_token
self.access_token_expiry_time = access_token_expiry_time
def __getattr__(self, attr_name):
return _APIFunction(attr_name, self)
class _APIFunction(object):
def __init__(self, function_name, service):
self.function_name = function_name
self.service = service
def __getattr__(self, attr_name):
# This isn't actually an API function, but a family of them. Append
# the requested function name to our name.
return _APIFunction(
"{0}.{1}".format(self.function_name, attr_name), self.service)
def __call__(self, *args, **kwargs):
return call_api_with_access_token(
self.service.endpoint_url, self.service.access_token,
self.function_name, args, kwargs)
#---------------------------------------------------------------------------
# Code that implements authentication and raw calls into the API:
def get_access_token_and_expiry_time(
access_token_url, client_id, client_secret_key):
"""Given an API client (id and secret key) that is allowed to make API
calls, return an access token that can be used to make calls.
"""
response = requests.post(
access_token_url,
headers={
"Authorization": u"Basic {0}".format(
base64.b64encode(
"{0}:{1}".format(
client_id, client_secret_key
).encode()
).decode('utf-8')
),
})
if response.status_code != 200:
raise AuthorizationError(response.status_code, response.text)
response_json = response.json()
access_token_expiry_time = time.time() - 2 + response_json["expires_in"]
return response_json["access_token"], access_token_expiry_time
class AuthorizationError(Exception):
"""Raised from the client if the server generated an error while generating
an access token.
"""
def __init__(self, http_code, message):
super(AuthorizationError, self).__init__(message)
self.http_code = http_code
def call_api_with_access_token(
endpoint_url, access_token, function_name, args, kwargs):
"""Call into the API using an access token that was returned by
get_access_token.
"""
response = requests.post(
endpoint_url,
headers={
"Authorization": "Bearer " + access_token,
},
data=dict(
json=json.dumps([function_name, args, kwargs]),
))
if response.status_code == 200:
return response.json()
raise APIError(response.status_code, response.text)
class APIError(Exception):
"""Raised from the client if the server generated an error while calling
into the API.
"""
def __init__(self, http_code, message):
super(APIError, self).__init__(message)
self.http_code = http_code
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Download a Houdini Installation')
parser.add_argument('version', type=str, help='Major.Minor version of Houdini to download')
parser.add_argument('platform', type=str, help='Platform target')
parser.add_argument('--prod', action='store_true', help='Only download production builds')
parser.add_argument('--list', action='store_true', help='Just list the available builds and exit.')
args = parser.parse_args()
version = args.version
platform = args.platform
only_production = args.prod
user_client_id = os.getenv('HOUDINI_CLIENT_ID')
user_client_secret_key = os.getenv('HOUDINI_SECRET_KEY')
if not re.match('[0-9][0-9]\.[0-9]$', version):
raise IOError('Invalid Houdini Version "%s", expecting in the form "major.minor" such as "16.0"' % version)
service = service(
access_token_url="https://www.sidefx.com/oauth2/application_token",
client_id=user_client_id,
client_secret_key=user_client_secret_key,
endpoint_url="https://www.sidefx.com/api/",
)
releases_list = service.download.get_daily_builds_list(
product='houdini', version=version, platform=platform, only_production=only_production)
print('Available builds:')
for rel in releases_list:
rel = copy.deepcopy(rel)
if 'third_party_libraries' in rel:
# Don't print these
del rel['third_party_libraries']
print(rel)
if args.list:
sys.exit(0)
print('Selecting build: ' + releases_list[0]['build'])
latest_release = service.download.get_daily_build_download(
product='houdini', version=version, platform=platform, build=releases_list[0]['build'])
print(latest_release)
# Can't do this procedurally as latest_release['filename'] can contain
# multiple periods and may have multiple trailing extensions...
extension = ''
if 'linux' in platform: extension = 'tar.gz'
elif 'macos' in platform: extension = 'dmg'
elif 'win64' in platform: extension = 'exe'
assert(extension in latest_release['filename'])
# Download the file and save it as hou.extension
local_filename = 'hou.' + extension
print('Writing to "' + local_filename + '"')
response = requests.get(latest_release['download_url'], stream=True)
if response.status_code == 200:
response.raw.decode_content = True
if has_tqdm:
file_size = int(response.headers.get('Content-Length', 0))
desc = "(Unknown total file size)" if file_size == 0 else ""
with tqdm.wrapattr(response.raw, "read", total=file_size, desc=desc) as r_raw:
with open(local_filename, 'wb') as f:
shutil.copyfileobj(r_raw, f)
else:
with open(local_filename, 'wb') as f:
shutil.copyfileobj(response.raw, f)
else:
raise Exception('Error downloading file!')
# Verify the file checksum is matching
file_hash = hashlib.md5()
with open(local_filename, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
file_hash.update(chunk)
if file_hash.hexdigest() != latest_release['hash']:
raise Exception('Checksum does not match!')
-129
View File
@@ -1,129 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
HOUDINI_MAJOR="$1"
PLATFORM="$2"
OTHER_ARGS="$3"
pip install --user requests
python ci/download_houdini.py $HOUDINI_MAJOR $PLATFORM $OTHER_ARGS
if [[ $PLATFORM =~ "linux" ]]; then
# create dir hierarchy
mkdir -p hou/bin
mkdir -p hou/houdini
mkdir -p hou/toolkit
mkdir -p hou/dsolib
# unpack hou.tar.gz and cleanup
tar -xzf hou.tar.gz
rm -rf hou.tar.gz
cd houdini*
tar -xzf houdini.tar.gz
# copy required files into hou dir
cp houdini_setup* ../hou/.
# report library names
ls -al dsolib/
# copy required libraries
cp -r toolkit/cmake ../hou/toolkit/.
cp -r toolkit/include ../hou/toolkit/.
cp -r dsolib/libHoudini* ../hou/dsolib/.
cp -r dsolib/libopenvdb_sesi* ../hou/dsolib/.
cp -r dsolib/libblosc* ../hou/dsolib/.
cp -r dsolib/libhboost* ../hou/dsolib/.
cp -r dsolib/libz* ../hou/dsolib/.
cp -r dsolib/libbz2* ../hou/dsolib/.
cp -r dsolib/libtbb* ../hou/dsolib/.
cp -r dsolib/libjemalloc* ../hou/dsolib/.
cp -r dsolib/liblzma* ../hou/dsolib/.
cp -r dsolib/libIex* ../hou/dsolib/.
cp -r dsolib/libImath* ../hou/dsolib/.
cp -r dsolib/libIlmThread* ../hou/dsolib/.
cd ..
elif [[ $PLATFORM =~ "macos" ]]; then
# Exract files by mounting the downloaded dmg (we only really want to
# expand Houdini.framework)
hdiutil attach hou.dmg
pkgutil --expand-full /Volumes/Houdini/Houdini.pkg Houdini
hdiutil detach /Volumes/Houdini
rm hou.dmg
# Move the required Frameworks and delete the extracted src
mkdir -p hou/Frameworks
mv Houdini/Framework.pkg/Payload/Houdini.framework hou/Frameworks/Houdini.framework
rm -rf Houdini
# Report library names
ls -al hou/Frameworks/Houdini.framework/Libraries
# Remove unused resources
cd hou/Frameworks/Houdini.framework/Resources/
rm -rf $(ls | grep -e toolkit -v)
cd -
# Handle libraries. On some versions of MacOS with older versions of ld,
# ld will complain (error) if shared libraries contain missing files which
# are referenced with LC_LOAD_DYLIB or LC_RPATH entries (even though they
# are not explicitly required at link time). We still want to delete these
# unused libs as they occupt ~1-2GB. To handle this, we generate a unique
# list of libs that our direct dependencies reference and create an empty
# shared dylib in their place.
cd hou/Frameworks/Houdini.framework/Libraries
# Remove any folders here, they aren't needed
rm -rf $(ls -p | grep /)
# Remove any library that does not match the -e patterns (inverse grep with -v)
unused_libraries=$(ls | \
grep -e libHoudini \
-e libopenvdb_sesi \
-e libblosc \
-e libhboost \
-e libz \
-e libbz2 \
-e libtbb \
-e libjemalloc \
-e liblzma \
-e libIex \
-e libImath \
-e libIlmThread \
-v)
rm -rf ${unused_libraries}
# Create an empty valid shared lib
echo '' | clang -x c -shared -o libempty.dylib -
# Generate a unique list of libs that our remaining libs reference
for i in $(ls); do otool -LX $i >> libnames; done
sort -u libnames | grep @rpath | cut -f1 -d' ' | xargs > rpaths
# Recreate unused libraries that have been deleted as empty shared dylibs
# to keep ld happy
for libpath in $(cat rpaths); do
libpath=${libpath#"@rpath/"}
echo "Checking $libpath"
if [ ! -f $libpath ]; then
echo "Creating empty library at $libpath"
mkdir -p $(dirname $libpath)
cp libempty.dylib $libpath
fi
done
rm libempty.dylib
cd -
fi
# write hou into hou.tar.gz and cleanup
tar -czvf hou.tar.gz hou
# move hou.tar.gz into hou subdirectory
rm -rf hou/*
mv hou.tar.gz hou
# inspect size of tarball
ls -lart hou/hou.tar.gz
-108
View File
@@ -1,108 +0,0 @@
#!/usr/bin/env python3
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
import os
import sys
import time
import threading
import zipfile
import argparse
try:
from urllib.request import urlretrieve
except ImportError:
from urllib import urlretrieve
parser = argparse.ArgumentParser(description='VDB files to download')
parser.add_argument('--files', '-f', type=str, nargs='+',
help='files to download i.e. bunny.vdb fire.vdb')
args = parser.parse_args()
vdbs = [
'armadillo.vdb',
'boat_points.vdb',
'buddha.vdb',
'bunny.vdb',
'bunny_cloud.vdb',
'bunny_points.vdb',
'crawler.vdb',
'cube.vdb',
'dragon.vdb',
'emu.vdb',
'explosion.vdb',
'fire.vdb',
'icosahedron.vdb',
'iss.vdb',
'smoke1.vdb',
'smoke2.vdb',
'space.vdb',
'sphere.vdb',
'sphere_points.vdb',
'torus.vdb',
'torus_knot.vdb',
'utahteapot.vdb',
'venusstatue.vdb',
'waterfall_points.vdb'
]
if args.files:
vdbs = list(set(vdbs) & set(args.files))
if not vdbs:
raise RuntimeError('No valid VDBs specified for download')
# forma urls in the form:
# 'https://artifacts.aswf.io/io/aswf/openvdb/models/buddha.vdb/1.0.0/buddha.vdb-1.0.0.zip'
vdb_urls = []
for vdb in vdbs:
url = 'https://artifacts.aswf.io/io/aswf/openvdb/models/' + \
vdb +'/1.0.0/' + vdb + '-1.0.0.zip'
vdb_urls.append(url)
def download(link, filelocation):
urlretrieve(link, filelocation)
# Init downloads
downloads = dict()
for url in vdb_urls:
zip_filename = os.path.basename(url)
print('Initiating download "' + url + '"')
download_thread = threading.Thread(target=download, args=(url,zip_filename))
download_thread.start()
downloads[zip_filename] = download_thread
sys.stdout.flush()
# Process files
while downloads:
zip_file = None
while not zip_file:
time.sleep(1)
for file, thread in downloads.items():
if not thread.is_alive():
thread.join()
zip_file = file
break
# Remove the entry
del downloads[zip_file]
try:
# Extract the downloaded zip
print('Extracting "' + zip_file + '"...')
sys.stdout.flush()
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall()
print('Cleaning up "' + zip_file + '"...')
sys.stdout.flush()
if os.path.isfile(zip_file): os.remove(zip_file)
except Exception as e:
print(e)
pass
-94
View File
@@ -1,94 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#################################################################################
# This script extracts all code blocks from AX documentation which are NOT #
# marked as cpp/sh/unparsed and attempts to parse or compile them through the #
# vdb_ax command line binary. Code blocks can be marked with a preceding #
# notation to determine compilation mode: #
# <!--- P ---> = points #
# <!--- V ---> = volumes #
# <!--- A ---> = all #
# If not marked, code is only parsed (though ideally all code blocks should be #
# compiled) #
#################################################################################
set -e
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/../"
VDB_AX=$ROOT/build/openvdb_cmd/vdb_ax/vdb_ax
DOCS=()
DOCS+=($ROOT/doc/ax/ax.txt)
DOCS+=($ROOT/doc/ax/axcplusplus.txt)
DOCS+=($ROOT/doc/ax/axexamples.txt)
# DOCS+=($ROOT/doc/ax/axfunctionlist.txt) do not test this file
DOCS+=($ROOT/doc/ax/doc.txt)
uncompiled=0
for DOC in "${DOCS[@]}"; do
echo "Checking doxygen code in '$DOC...'"
# Make sure the file exists
if [ ! -f $DOC ]; then
echo "Could not find '$DOC.'"
exit -1
fi
# Extract all code segments from doxygen documentation in between @code and @endcode
data=$(sed -n '/@code.* *$/,/^ *@endcode *$/p' $DOC)
str=""
compile=""
skip=false
count=0
# For each extracted line, rebuild each code segment from @code and @endcode and
# run it through a vdb_ax binary if necessary
while IFS= read -r line; do
# If the code is marked as unparsed, c++ or shell, skip
if [[ "$line" == "@code{.unparsed}" ]]; then
skip=true
elif [[ "$line" == "@code{.cpp}" ]]; then
skip=true
elif [[ "$line" == "@code{.sh}" ]]; then
skip=true
elif [[ $line == @code* ]]; then
str=""
compile="none"
elif [[ $line == "<!-- V -->@code"* ]]; then
str=""
compile="volumes"
elif [[ $line == "<!-- P -->@code"* ]]; then
str=""
compile="points"
elif [[ $line == "<!-- A -->@code"* ]]; then
str=""
compile=""
elif [[ $line == @endcode ]]; then
echo -e "\nTesting [$count]:"
if [ "$skip" = true ]; then
echo "Skipping the following unparsed/c++/shell code:"
echo -e "$str" | sed 's/^/ /'
else
# parse
if [ "$compile" = "none" ]; then
$VDB_AX analyze -s "$str" -v
uncompiled=$((uncompiled+1))
else
$VDB_AX analyze -s "$str" --try-compile $compile -v
fi
fi
skip=false
count=$((count+1))
str=""
compile="none"
else
str+="$line"$'\n'
fi
done <<< "$data"
done
echo ""
echo "Extract test examples completed successfully"
if [ $uncompiled -gt 0 ]; then
echo " with $uncompiled uncompiled tests"
fi
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
BLOSC_VERSION="$1"
INSTALL_ROOT="$2"
CMAKE_EXTRA=()
if [ ! -z "${INSTALL_ROOT}" ]; then
CMAKE_EXTRA+=("-DCMAKE_INSTALL_PREFIX=${INSTALL_ROOT}")
fi
git clone https://github.com/Blosc/c-blosc.git
cd c-blosc
if [ "$BLOSC_VERSION" != "latest" ]; then
git checkout tags/v${BLOSC_VERSION} -b v${BLOSC_VERSION}
fi
mkdir build
cd build
# On MacOS there's a bug between blosc 1.14-1.20 where unistd isn't included
# in zlib-1.2.8/gzlib.c. Provide -DPREFER_EXTERNAL_ZLIB to use the installed
# version of zlib.
# https://github.com/Blosc/python-blosc/issues/229
cmake \
-DPREFER_EXTERNAL_ZLIB=ON \
-DBUILD_STATIC=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_FUZZERS=OFF \
-DBUILD_BENCHMARKS=OFF \
"${CMAKE_EXTRA[@]}" \
..
make -j8
make install
-17
View File
@@ -1,17 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
CURL_VERSION="$1"
wget -O cppunit.tar.gz https://dev-www.libreoffice.org/src/cppunit-${CURL_VERSION}.tar.gz
tar -xzf cppunit.tar.gz
cd cppunit-${CURL_VERSION}
./configure
make -j8
make install
-20
View File
@@ -1,20 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
DOXYGEN_VERSION="$1"
git clone https://github.com/doxygen/doxygen.git
cd doxygen
if [ "$DOXYGEN_VERSION" != "latest" ]; then
git checkout Release_${DOXYGEN_VERSION} -b v${DOXYGEN_VERSION}
fi
mkdir build
cd build
cmake ../.
make -j8
make install
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
GLFW_VERSION="$1"
git clone https://github.com/glfw/glfw.git
cd glfw
if [ "$GLFW_VERSION" != "latest" ]; then
git checkout tags/${GLFW_VERSION} -b ${GLFW_VERSION}
fi
mkdir build
cd build
cmake ..
make -j8
make install
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
GTEST_VERSION="$1"
git clone https://github.com/google/googletest.git -b v${GTEST_VERSION}
cd googletest
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
-33
View File
@@ -1,33 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
LLVM_CRT="$1"
git clone -b llvmorg-14.0.0 --depth 1 https://github.com/llvm/llvm-project.git llvm
cd llvm
mkdir .build
cd .build
# @note currently only test static builds with MT
cmake -B . -S ../llvm -A x64 -G "Visual Studio 17 2022" -Thost=x64 \
-DCMAKE_INSTALL_PREFIX="${HOME}/llvm_install" \
-DLLVM_TARGETS_TO_BUILD="host" \
-DLLVM_BUILD_TOOLS=OFF \
-DLLVM_INCLUDE_BENCHMARKS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_TOOLS=OFF \
-DLLVM_USE_CRT_RELEASE=${LLVM_CRT}
cmake --build . --config Release --target install
cd ..
du -h .build -d0
du -h ${HOME}/llvm_install -d0
rm -rf .build
-53
View File
@@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -x
# Remove Python3 symlinks in /usr/local/bin as workaround to brew update issues
# https://github.com/actions/setup-python/issues/577
rm /usr/local/bin/2to3* || :
rm /usr/local/bin/idle3* || :
rm /usr/local/bin/pydoc* || :
rm /usr/local/bin/python3* || :
brew update
brew install bash gnu-getopt # for CI scripts
brew install boost
brew install c-blosc
brew install cmake
brew install glfw
brew install googletest
brew install jq # for trivial parsing of brew json
brew install openexr
brew install nanobind # also installs the dependent python version
brew install robin-map # required for nanobind
brew install zlib
brew install jemalloc
# Alias python version installed by nanobind to path
py_version=$(brew info nanobind --json | \
jq -cr '.[].dependencies[] | select(. | startswith("python"))')
echo "Using python $py_version"
# export for subsequent action steps (note, not exported for this env)
echo "Python_ROOT_DIR=/usr/local/opt/$py_version" >> $GITHUB_ENV
echo "/usr/local/opt/$py_version/bin" >> $GITHUB_PATH
# use bash
echo "/usr/local/opt/bash/bin" >> $GITHUB_PATH
echo "/opt/homebrew/opt/bash/bin" >> $GITHUB_PATH
# use gnu-getopt
echo "/usr/local/opt/gnu-getopt/bin" >> $GITHUB_PATH
echo "/opt/homebrew/opt/gnu-getopt/bin" >> $GITHUB_PATH
LLVM_VERSION=$1
if [ ! -z "$LLVM_VERSION" ]; then
if [ "$LLVM_VERSION" == "latest" ]; then
brew install llvm
brew install cppunit
else
brew install llvm@$LLVM_VERSION
brew install cppunit
fi
fi
-30
View File
@@ -1,30 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
PYBIND11_VERSION="$1"
INSTALL_ROOT="$2"
CMAKE_EXTRA=()
if [ ! -z "${INSTALL_ROOT}" ]; then
CMAKE_EXTRA+=("-DCMAKE_INSTALL_PREFIX=${INSTALL_ROOT}")
fi
git clone --recurse-submodules https://github.com/wjakob/nanobind.git
cd nanobind
if [ "$PYBIND11_VERSION" != "latest" ]; then
git checkout tags/v${PYBIND11_VERSION} -b v${PYBIND11_VERSION}
fi
mkdir build
cd build
cmake \
-DNB_TEST=OFF \
"${CMAKE_EXTRA[@]}" \
..
make -j8
sudo make install
-8
View File
@@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -x
brew update
brew install tbb
-40
View File
@@ -1,40 +0,0 @@
# Enable verbose and stop on error
$ErrorActionPreference = "Stop"
$VerbosePreference = "Continue"
# Required dependencies
$vcpkgPackages = @(
"zlib",
"libpng",
"openexr",
"tbb",
"gtest",
"cppunit",
"blosc",
"glfw3",
"glew",
"python3",
"jemalloc",
"boost-iostreams",
"boost-interprocess",
"boost-algorithm",
"nanobind"
)
# Update vcpkg
vcpkg update
# Allow the vcpkg command to fail once so we can retry with the latest
try {
vcpkg install $vcpkgPackages
} catch {
Write-Host "vcpkg install failed, retrying with latest ports..."
# Retry the installation with updated ports
Push-Location $env:VCPKG_INSTALLATION_ROOT
git pull
Pop-Location
vcpkg update
vcpkg install $vcpkgPackages
}
Write-Host "vcpkg install completed successfully"
-174
View File
@@ -1,174 +0,0 @@
# Download and install CUDA on windows. Based off the scripts by:
# https://github.com/ptheywood/cuda-cmake-github-actions
## -------------------
## Constants
## -------------------
# Dictionary of known cuda versions and thier download URLS, which do not follow a consistent pattern :(
$CUDA_KNOWN_URLS = @{
"8.0.44" = "http://developer.nvidia.com/compute/cuda/8.0/Prod/network_installers/cuda_8.0.44_win10_network-exe";
"8.0.61" = "http://developer.nvidia.com/compute/cuda/8.0/Prod2/network_installers/cuda_8.0.61_win10_network-exe";
"9.0.176" = "http://developer.nvidia.com/compute/cuda/9.0/Prod/network_installers/cuda_9.0.176_win10_network-exe";
"9.1.85" = "http://developer.nvidia.com/compute/cuda/9.1/Prod/network_installers/cuda_9.1.85_win10_network";
"9.2.148" = "http://developer.nvidia.com/compute/cuda/9.2/Prod2/network_installers2/cuda_9.2.148_win10_network";
"10.0.130" = "http://developer.nvidia.com/compute/cuda/10.0/Prod/network_installers/cuda_10.0.130_win10_network";
"10.1.105" = "http://developer.nvidia.com/compute/cuda/10.1/Prod/network_installers/cuda_10.1.105_win10_network.exe";
"10.1.168" = "http://developer.nvidia.com/compute/cuda/10.1/Prod/network_installers/cuda_10.1.168_win10_network.exe";
"10.1.243" = "http://developer.download.nvidia.com/compute/cuda/10.1/Prod/network_installers/cuda_10.1.243_win10_network.exe";
"10.2.89" = "http://developer.download.nvidia.com/compute/cuda/10.2/Prod/network_installers/cuda_10.2.89_win10_network.exe";
"11.0.1" = "http://developer.download.nvidia.com/compute/cuda/11.0.1/network_installers/cuda_11.0.1_win10_network.exe";
"11.0.2" = "http://developer.download.nvidia.com/compute/cuda/11.0.2/network_installers/cuda_11.0.2_win10_network.exe";
"11.0.3" = "http://developer.download.nvidia.com/compute/cuda/11.0.3/network_installers/cuda_11.0.3_win10_network.exe";
"11.1.0" = "https://developer.download.nvidia.com/compute/cuda/11.1.0/network_installers/cuda_11.1.0_win10_network.exe";
"11.1.1" = "https://developer.download.nvidia.com/compute/cuda/11.1.1/network_installers/cuda_11.1.1_win10_network.exe";
"11.2.0" = "https://developer.download.nvidia.com/compute/cuda/11.2.0/network_installers/cuda_11.2.0_win10_network.exe";
"11.2.1" = "https://developer.download.nvidia.com/compute/cuda/11.2.1/network_installers/cuda_11.2.1_win10_network.exe";
"11.2.2" = "https://developer.download.nvidia.com/compute/cuda/11.2.2/network_installers/cuda_11.2.2_win10_network.exe";
"11.3.0" = "https://developer.download.nvidia.com/compute/cuda/11.3.0/network_installers/cuda_11.3.0_win10_network.exe";
"11.6.2" = "https://developer.download.nvidia.com/compute/cuda/11.6.2/network_installers/cuda_11.6.2_windows_network.exe";
"12.4.0" = "https://developer.download.nvidia.com/compute/cuda/12.4.0/network_installers/cuda_12.4.0_windows_network.exe"
}
# @todo - change this to be based on _MSC_VER intead, or invert it to be CUDA keyed instead?
$VISUAL_STUDIO_MIN_CUDA = @{
"2022" = "12.4";
"2019" = "10.1";
"2017" = "10.0"; # Depends on which version of 2017! 9.0 to 10.0 depending on version
"2015" = "8.0"; # might support older, unsure.
}
# cuda_runtime.h is in nvcc <= 10.2, but cudart >= 11.0
# @todo - make this easier to vary per CUDA version.
$CUDA_PACKAGES_IN = @(
"nvcc";
"visual_studio_integration";
"curand_dev";
"nvrtc_dev";
"cudart";
"thrust";
)
## -------------------
## Select CUDA version
## -------------------
# Get the cuda version from the environment as env:cuda.
$CUDA_VERSION_FULL = $env:cuda
# Make sure CUDA_VERSION_FULL is set and valid, otherwise error.
# Validate CUDA version, extracting components via regex
$cuda_ver_matched = $CUDA_VERSION_FULL -match "^(?<major>[1-9][0-9]*)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)$"
if(-not $cuda_ver_matched){
Write-Output "Invalid CUDA version specified, <major>.<minor>.<patch> required. '$CUDA_VERSION_FULL'."
exit 1
}
$CUDA_MAJOR=$Matches.major
$CUDA_MINOR=$Matches.minor
$CUDA_PATCH=$Matches.patch
## ---------------------------
## Visual studio support check
## ---------------------------
# Exit if visual studio is too new for the cuda version.
$VISUAL_STUDIO = $env:visual_studio.trim()
if ($VISUAL_STUDIO.length -ge 4) {
$VISUAL_STUDIO_YEAR = $VISUAL_STUDIO.Substring($VISUAL_STUDIO.Length-4)
if ($VISUAL_STUDIO_YEAR.length -eq 4 -and $VISUAL_STUDIO_MIN_CUDA.containsKey($VISUAL_STUDIO_YEAR)){
$MINIMUM_CUDA_VERSION = $VISUAL_STUDIO_MIN_CUDA[$VISUAL_STUDIO_YEAR]
if ([version]$CUDA_VERSION_FULL -lt [version]$MINIMUM_CUDA_VERSION) {
Write-Output "Error: Visual Studio $($VISUAL_STUDIO_YEAR) requires CUDA >= $($MINIMUM_CUDA_VERSION)"
exit 1
}
}
} else {
Write-Output "Warning: Unknown Visual Studio Version. CUDA version may be insufficient."
}
## ------------------------------------------------
## Select CUDA packages to install from environment
## ------------------------------------------------
$CUDA_PACKAGES = ""
# for CUDA >= 11 cudart is a required package.
# if([version]$CUDA_VERSION_FULL -ge [version]"11.0") {
# if(-not $CUDA_PACKAGES_IN -contains "cudart") {
# $CUDA_PACKAGES_IN += 'cudart'
# }
# }
Foreach ($package in $CUDA_PACKAGES_IN) {
# Make sure the correct package name is used for nvcc.
if($package -eq "nvcc" -and [version]$CUDA_VERSION_FULL -lt [version]"9.1"){
$package="compiler"
} elseif($package -eq "compiler" -and [version]$CUDA_VERSION_FULL -ge [version]"9.1") {
$package="nvcc"
}
$CUDA_PACKAGES += " $($package)_$($CUDA_MAJOR).$($CUDA_MINOR)"
}
echo "$($CUDA_PACKAGES)"
## -----------------
## Prepare download
## -----------------
# Select the download link if known, otherwise have a guess.
$CUDA_REPO_PKG_REMOTE=""
if($CUDA_KNOWN_URLS.containsKey($CUDA_VERSION_FULL)){
$CUDA_REPO_PKG_REMOTE=$CUDA_KNOWN_URLS[$CUDA_VERSION_FULL]
} else{
# Guess what the url is given the most recent pattern (at the time of writing, 10.1)
Write-Output "note: URL for CUDA ${$CUDA_VERSION_FULL} not known, estimating."
$CUDA_REPO_PKG_REMOTE="http://developer.download.nvidia.com/compute/cuda/$($CUDA_MAJOR).$($CUDA_MINOR)/Prod/network_installers/cuda_$($CUDA_VERSION_FULL)_win10_network.exe"
}
$CUDA_REPO_PKG_LOCAL="cuda_$($CUDA_VERSION_FULL)_win10_network.exe"
## ------------
## Install CUDA
## ------------
# Get CUDA network installer
Write-Output "Downloading CUDA Network Installer for $($CUDA_VERSION_FULL) from: $($CUDA_REPO_PKG_REMOTE)"
Invoke-WebRequest $CUDA_REPO_PKG_REMOTE -OutFile $CUDA_REPO_PKG_LOCAL | Out-Null
if(Test-Path -Path $CUDA_REPO_PKG_LOCAL){
Write-Output "Downloading Complete"
} else {
Write-Output "Error: Failed to download $($CUDA_REPO_PKG_LOCAL) from $($CUDA_REPO_PKG_REMOTE)"
exit 1
}
# Invoke silent install of CUDA (via network installer)
Write-Output "Installing CUDA $($CUDA_VERSION_FULL). Subpackages $($CUDA_PACKAGES)"
Start-Process -Wait -FilePath .\"$($CUDA_REPO_PKG_LOCAL)" -ArgumentList "-s $($CUDA_PACKAGES)"
# Check the return status of the CUDA installer.
if (!$?) {
Write-Output "Error: CUDA installer reported error. $($LASTEXITCODE)"
exit 1
}
# Store the CUDA_PATH in the environment for the current session, to be forwarded in the action.
$CUDA_PATH = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$($CUDA_MAJOR).$($CUDA_MINOR)"
$CUDA_PATH_VX_Y = "CUDA_PATH_V$($CUDA_MAJOR)_$($CUDA_MINOR)"
# Set environmental variables in this session
$env:CUDA_PATH = "$($CUDA_PATH)"
$env:CUDA_PATH_VX_Y = "$($CUDA_PATH_VX_Y)"
Write-Output "CUDA_PATH $($CUDA_PATH)"
Write-Output "CUDA_PATH_VX_Y $($CUDA_PATH_VX_Y)"
# PATH needs updating elsewhere, anything in here won't persist.
# Append $CUDA_PATH/bin to path.
# Set CUDA_PATH as an environmental variable
# If executing on github actions, emit the appropriate echo statements to update environment variables
if (Test-Path "env:GITHUB_ACTIONS") {
# Set paths for subsequent steps, using $env:CUDA_PATH
echo "Adding CUDA to CUDA_PATH, CUDA_PATH_X_Y and PATH"
echo "CUDA_PATH=$env:CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$env:CUDA_PATH_VX_Y=$env:CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$env:CUDA_PATH/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -e
# Various tests to test the FindOpenVDB CMake modules and
# general VDB installation
# 1) Test basic CMakeLists is able to build vdb_print with
# the expected VDB installation
cmakelists="
cmake_minimum_required(VERSION 3.20)
project(TestInstall LANGUAGES CXX)
find_package(OpenVDB REQUIRED COMPONENTS openvdb)
add_executable(test_vdb_print \"../openvdb_cmd/vdb_print/main.cc\")
target_link_libraries(test_vdb_print OpenVDB::openvdb)
"
mkdir tmp
cd tmp
echo -e "$cmakelists" > CMakeLists.txt
cmake -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake/OpenVDB/ .
cmake --build . --config Release --target test_vdb_print
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
set -ex
SONAR_VERSION=3.3.0.1492
wget -q https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_VERSION}-linux.zip
unzip sonar-scanner-cli-${SONAR_VERSION}-linux.zip
mkdir coverage
cd coverage
for g in $(find ../build -name "*.gcno" -type f); do
gcov -p -l -o $(dirname "$g") $(echo "$g" | sed -e 's/\/build\//\//' -e 's/\.gcno/\.cc/' -e 's/\/CMakeFiles.*\.dir\//\//')
done
cd ..
sonar-scanner-${SONAR_VERSION}-linux/bin/sonar-scanner -X \
-Dsonar.projectKey=openvdb \
-Dsonar.links.homepage=https://www.openvdb.org/ \
-Dsonar.links.scm=https://github.com/AcademySoftwareFoundation/openvdb \
-Dsonar.links.issue=https://jira.aswf.io/projects/OVDB \
-Dsonar.sources=openvdb \
-Dsonar.exclusions=openvdb/cmd/**,openvdb/unittest/**,openvdb/viewer/**,openvdb/python/** \
-Dsonar.binaries=build/openvdb/unittest/vdb_test \
-Dsonar.tests=openvdb/unittest \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.organization=danrbailey-github \
-Dsonar.cfamily.build-wrapper-output=build/bw_output \
-Dsonar.cfamily.gcov.reportsPath=coverage \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.login=$SONAR_TOKEN
-430
View File
@@ -1,430 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindBlosc
---------
Find Blosc include dirs and libraries
Use this module by invoking find_package with the form::
find_package(Blosc
[version] [EXACT] # Minimum or EXACT version e.g. 1.5.0
[REQUIRED] # Fail with error if Blosc is not found
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``Blosc::blosc``
This module defines IMPORTED target Blosc::Blosc, if Blosc has been found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Blosc_FOUND``
True if the system has the Blosc library.
``Blosc_VERSION``
The version of the Blosc library which was found.
``Blosc_INCLUDE_DIRS``
Include directories needed to use Blosc.
``Blosc_RELEASE_LIBRARIES``
Libraries needed to link to the release version of Blosc.
``Blosc_RELEASE_LIBRARY_DIRS``
Blosc release library directories.
``Blosc_DEBUG_LIBRARIES``
Libraries needed to link to the debug version of Blosc.
``Blosc_DEBUG_LIBRARY_DIRS``
Blosc debug library directories.
Deprecated - use [RELEASE|DEBUG] variants:
``Blosc_LIBRARIES``
Libraries needed to link to Blosc.
``Blosc_LIBRARY_DIRS``
Blosc library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Blosc_INCLUDE_DIR``
The directory containing ``blosc.h``.
``Blosc_LIBRARY``
The path to the Blosc library. may include target_link_libraries() debug/optimized keywords
``Blosc_LIBRARY_RELEASE``
The path to the Blosc release library.
``Blosc_LIBRARY_DEBUG``
The path to the Blosc debug library.
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``Blosc_ROOT``
Preferred installation prefix.
``BLOSC_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``BLOSC_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``BLOSC_DEBUG_SUFFIX``
Suffix of the debug version of blosc. Defaults to "_d", OR the empty string for VCPKG_TOOLCHAIN
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``BLOSC_USE_STATIC_LIBS``
Only search for static blosc libraries
``BLOSC_USE_EXTERNAL_SOURCES``
Set to ON if Blosc has been built using external sources for LZ4, snappy,
zlib and zstd. Default is OFF.
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
Blosc_INCLUDE_DIR
Blosc_LIBRARY
)
set(_FIND_BLOSC_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_BLOSC_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _BLOSC_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV BLOSC_ROOT from CMake 3.12
if(Blosc_ROOT)
set(_BLOSC_ROOT ${Blosc_ROOT})
elseif(DEFINED ENV{Blosc_ROOT})
set(_BLOSC_ROOT $ENV{Blosc_ROOT})
elseif(BLOSC_ROOT)
set(_BLOSC_ROOT ${BLOSC_ROOT})
elseif(DEFINED ENV{BLOSC_ROOT})
set(_BLOSC_ROOT $ENV{BLOSC_ROOT})
endif()
# Additionally try and use pkconfig to find blosc
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_Blosc QUIET blosc)
endif()
endif()
# ------------------------------------------------------------------------
# Search for blosc include DIR
# ------------------------------------------------------------------------
set(_BLOSC_INCLUDE_SEARCH_DIRS "")
list(APPEND _BLOSC_INCLUDE_SEARCH_DIRS
${BLOSC_INCLUDEDIR}
${_BLOSC_ROOT}
${PC_Blosc_INCLUDE_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
# Look for a standard blosc header file.
find_path(Blosc_INCLUDE_DIR blosc.h
${_FIND_BLOSC_ADDITIONAL_OPTIONS}
PATHS ${_BLOSC_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
)
if(EXISTS "${Blosc_INCLUDE_DIR}/blosc.h")
file(STRINGS "${Blosc_INCLUDE_DIR}/blosc.h"
_blosc_version_major_string REGEX "#define BLOSC_VERSION_MAJOR +[0-9]+ "
)
string(REGEX REPLACE "#define BLOSC_VERSION_MAJOR +([0-9]+).*$" "\\1"
_blosc_version_major_string "${_blosc_version_major_string}"
)
string(STRIP "${_blosc_version_major_string}" Blosc_VERSION_MAJOR)
file(STRINGS "${Blosc_INCLUDE_DIR}/blosc.h"
_blosc_version_minor_string REGEX "#define BLOSC_VERSION_MINOR +[0-9]+ "
)
string(REGEX REPLACE "#define BLOSC_VERSION_MINOR +([0-9]+).*$" "\\1"
_blosc_version_minor_string "${_blosc_version_minor_string}"
)
string(STRIP "${_blosc_version_minor_string}" Blosc_VERSION_MINOR)
file(STRINGS "${Blosc_INCLUDE_DIR}/blosc.h"
_blosc_version_release_string REGEX "#define BLOSC_VERSION_RELEASE +[0-9]+ "
)
string(REGEX REPLACE "#define BLOSC_VERSION_RELEASE +([0-9]+).*$" "\\1"
_blosc_version_release_string "${_blosc_version_release_string}"
)
string(STRIP "${_blosc_version_release_string}" Blosc_VERSION_RELEASE)
unset(_blosc_version_major_string)
unset(_blosc_version_minor_string)
unset(_blosc_version_release_string)
set(Blosc_VERSION ${Blosc_VERSION_MAJOR}.${Blosc_VERSION_MINOR}.${Blosc_VERSION_RELEASE})
endif()
# ------------------------------------------------------------------------
# Search for blosc lib DIR
# ------------------------------------------------------------------------
set(_BLOSC_LIBRARYDIR_SEARCH_DIRS "")
list(APPEND _BLOSC_LIBRARYDIR_SEARCH_DIRS
${BLOSC_LIBRARYDIR}
${_BLOSC_ROOT}
${PC_Blosc_LIBRARY_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
set(Blosc_LIB_COMPONENTS "")
# NOTE: Search for debug version first (see vcpkg hack)
list(APPEND BLOSC_BUILD_TYPES DEBUG RELEASE)
foreach(BUILD_TYPE ${BLOSC_BUILD_TYPES})
set(_BLOSC_LIB_NAME blosc)
set(_BLOSC_CMAKE_IGNORE_PATH ${CMAKE_IGNORE_PATH})
if(VCPKG_TOOLCHAIN)
# Blosc is installed very strangely in VCPKG (debug/release libs have the
# same name, static build uses external deps, dll doesn't) and blosc itself
# comes with almost zero downstream CMake support for us to detect settings.
# We should not support external package managers in our own modules like
# this, but there doesn't seem to be a work around
if(NOT DEFINED BLOSC_DEBUG_SUFFIX)
set(BLOSC_DEBUG_SUFFIX "")
endif()
if(BUILD_TYPE STREQUAL RELEASE)
if(EXISTS ${Blosc_LIBRARY_DEBUG})
get_filename_component(_BLOSC_DEBUG_DIR ${Blosc_LIBRARY_DEBUG} DIRECTORY)
list(APPEND CMAKE_IGNORE_PATH ${_BLOSC_DEBUG_DIR})
endif()
endif()
endif()
if(BUILD_TYPE STREQUAL DEBUG)
if(NOT DEFINED BLOSC_DEBUG_SUFFIX)
set(BLOSC_DEBUG_SUFFIX _d)
endif()
set(_BLOSC_LIB_NAME "${_BLOSC_LIB_NAME}${BLOSC_DEBUG_SUFFIX}")
endif()
find_library(Blosc_LIBRARY_${BUILD_TYPE} ${_BLOSC_LIB_NAME}
${_FIND_BLOSC_ADDITIONAL_OPTIONS}
PATHS ${_BLOSC_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib
)
list(APPEND Blosc_LIB_COMPONENTS ${Blosc_LIBRARY_${BUILD_TYPE}})
set(CMAKE_IGNORE_PATH ${_BLOSC_CMAKE_IGNORE_PATH})
endforeach()
if(Blosc_LIBRARY_DEBUG AND Blosc_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(Blosc_LIBRARY optimized ${Blosc_LIBRARY_RELEASE} debug ${Blosc_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(Blosc_LIBRARY ${Blosc_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(Blosc_LIBRARIES optimized ${Blosc_LIBRARY_RELEASE} debug ${Blosc_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(Blosc_LIBRARY_RELEASE AND NOT Blosc_LIBRARY_DEBUG)
set(Blosc_LIBRARY_DEBUG ${Blosc_LIBRARY_RELEASE})
set(Blosc_LIBRARY ${Blosc_LIBRARY_RELEASE})
set(Blosc_LIBRARIES ${Blosc_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(Blosc_LIBRARY_DEBUG AND NOT Blosc_LIBRARY_RELEASE)
set(Blosc_LIBRARY_RELEASE ${Blosc_LIBRARY_DEBUG})
set(Blosc_LIBRARY ${Blosc_LIBRARY_DEBUG})
set(Blosc_LIBRARIES ${Blosc_LIBRARY_DEBUG})
endif()
# If the debug & release library ends up being the same, omit the keywords
if("${Blosc_LIBRARY_RELEASE}" STREQUAL "${Blosc_LIBRARY_DEBUG}")
set(Blosc_LIBRARY ${Blosc_LIBRARY_RELEASE} )
set(Blosc_LIBRARIES ${Blosc_LIBRARY_RELEASE} )
endif()
if(Blosc_LIBRARY)
set(Blosc_FOUND TRUE)
else()
set(Blosc_FOUND FALSE)
endif()
# ------------------------------------------------------------------------
# Cache and set Blosc_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Blosc
FOUND_VAR Blosc_FOUND
REQUIRED_VARS
Blosc_LIBRARY
Blosc_INCLUDE_DIR
VERSION_VAR Blosc_VERSION
)
if(NOT Blosc_FOUND)
if(Blosc_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find Blosc")
endif()
return()
endif()
# Partition release/debug lib vars
set(Blosc_RELEASE_LIBRARIES ${Blosc_LIBRARY_RELEASE})
get_filename_component(Blosc_RELEASE_LIBRARY_DIRS ${Blosc_RELEASE_LIBRARIES} DIRECTORY)
set(Blosc_DEBUG_LIBRARIES ${Blosc_LIBRARY_DEBUG})
get_filename_component(Blosc_DEBUG_LIBRARY_DIRS ${Blosc_DEBUG_LIBRARIES} DIRECTORY)
set(Blosc_LIBRARIES ${Blosc_RELEASE_LIBRARIES})
set(Blosc_LIBRARY_DIRS ${Blosc_RELEASE_LIBRARY_DIRS})
set(Blosc_INCLUDE_DIRS ${Blosc_INCLUDE_DIR})
set(Blosc_INCLUDE_DIRS ${Blosc_INCLUDE_DIR})
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(BLOSC_LIB_TYPE UNKNOWN)
if(BLOSC_USE_STATIC_LIBS)
set(BLOSC_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_BLOSC_EXT ${Blosc_LIBRARY_RELEASE} EXT)
if(_BLOSC_EXT STREQUAL ".a")
set(BLOSC_LIB_TYPE STATIC)
elseif(_BLOSC_EXT STREQUAL ".so" OR
_BLOSC_EXT STREQUAL ".dylib")
set(BLOSC_LIB_TYPE SHARED)
endif()
endif()
get_filename_component(Blosc_LIBRARY_DIRS ${Blosc_LIBRARY_RELEASE} DIRECTORY)
if(NOT TARGET Blosc::blosc)
add_library(Blosc::blosc ${BLOSC_LIB_TYPE} IMPORTED)
set_target_properties(Blosc::blosc PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_Blosc_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Blosc_INCLUDE_DIRS}")
# Standard location
set_target_properties(Blosc::blosc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${Blosc_LIBRARY}")
# Release location
if(EXISTS "${Blosc_LIBRARY_RELEASE}")
set_property(TARGET Blosc::blosc APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Blosc::blosc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${Blosc_LIBRARY_RELEASE}")
endif()
# Debug location
if(EXISTS "${Blosc_LIBRARY_DEBUG}")
set_property(TARGET Blosc::blosc APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Blosc::blosc PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "${Blosc_LIBRARY_DEBUG}")
endif()
# Blosc may optionally be compiled with external sources for
# lz4, snappy and zlib . Add them as interface libs if requested
# (there doesn't seem to be a way to figure this out automatically).
# We assume they live along side blosc
if(BLOSC_USE_EXTERNAL_SOURCES)
set_target_properties(Blosc::blosc PROPERTIES
INTERFACE_LINK_DIRECTORIES
"\$<\$<CONFIG:Release>:${Blosc_RELEASE_LIBRARY_DIRS}>;\$<\$<CONFIG:Debug>:${Blosc_DEBUG_LIBRARY_DIRS}>")
set(BLOSC_EXTERNAL_LIBRARIES lz4 snappy zlib zstd)
foreach(BLOSC_EXTERNAL_LIB ${BLOSC_EXTERNAL_LIBRARIES})
foreach(BUILD_TYPE ${BLOSC_BUILD_TYPES})
set(_BLOSC_CMAKE_IGNORE_PATH ${CMAKE_IGNORE_PATH})
if(VCPKG_TOOLCHAIN)
if(BUILD_TYPE STREQUAL RELEASE)
list(APPEND CMAKE_IGNORE_PATH ${Blosc_DEBUG_LIBRARY_DIRS})
else()
list(APPEND CMAKE_IGNORE_PATH ${Blosc_RELEASE_LIBRARY_DIRS})
endif()
endif()
find_library(${BLOSC_EXTERNAL_LIB}_LIBRARY_${BUILD_TYPE} ${BLOSC_EXTERNAL_LIB}
${_FIND_BLOSC_ADDITIONAL_OPTIONS}
PATHS ${_BLOSC_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib)
if(NOT ${BLOSC_EXTERNAL_LIB}_LIBRARY_${BUILD_TYPE})
if(BUILD_TYPE STREQUAL DEBUG)
find_library(${BLOSC_EXTERNAL_LIB}_LIBRARY_${BUILD_TYPE} "${BLOSC_EXTERNAL_LIB}d"
${_FIND_BLOSC_ADDITIONAL_OPTIONS}
PATHS ${_BLOSC_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib)
endif()
endif()
set(CMAKE_IGNORE_PATH ${_BLOSC_CMAKE_IGNORE_PATH})
endforeach()
if(${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG AND ${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(${BLOSC_EXTERNAL_LIB}_LIBRARY optimized ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE} debug ${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(${BLOSC_EXTERNAL_LIB}_LIBRARY ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(${BLOSC_EXTERNAL_LIB}_LIBRARIES optimized ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE} debug ${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE AND NOT ${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG)
set(${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE})
set(${BLOSC_EXTERNAL_LIB}_LIBRARY ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE})
set(${BLOSC_EXTERNAL_LIB}_LIBRARIES ${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG AND NOT ${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE)
set(${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE ${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG})
set(${BLOSC_EXTERNAL_LIB}_LIBRARY ${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG})
set(${BLOSC_EXTERNAL_LIB}_LIBRARIES ${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG})
endif()
target_link_libraries(Blosc::blosc INTERFACE
$<$<CONFIG:Release>:${${BLOSC_EXTERNAL_LIB}_LIBRARY_RELEASE}>
$<$<CONFIG:Debug>:${${BLOSC_EXTERNAL_LIB}_LIBRARY_DEBUG}>)
endforeach()
endif()
endif()
-320
View File
@@ -1,320 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindCppUnit
-----------
Find CppUnit include dirs and libraries
Use this module by invoking find_package with the form::
find_package(CppUnit
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if CppUnit is not found
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``CppUnit::cppunit``
This module defines IMPORTED target CppUnit::cppunit, if CppUnit has been
found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``CppUnit_FOUND``
True if the system has the CppUnit library.
``CppUnit_VERSION``
The version of the CppUnit library which was found.
``CppUnit_INCLUDE_DIRS``
Include directories needed to use CppUnit.
``CppUnit_RELEASE_LIBRARIES``
Libraries needed to link to the release version of CppUnit.
``CppUnit_RELEASE_LIBRARY_DIRS``
CppUnit release library directories.
``CppUnit_DEBUG_LIBRARIES``
Libraries needed to link to the debug version of CppUnit.
``CppUnit_DEBUG_LIBRARY_DIRS``
CppUnit debug library directories.
Deprecated - use [RELEASE|DEBUG] variants:
``CppUnit_LIBRARIES``
Libraries needed to link to CppUnit.
``CppUnit_LIBRARY_DIRS``
CppUnit library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``CppUnit_INCLUDE_DIR``
The directory containing ``cppunit/Portability.h``.
``CppUnit_LIBRARY``
The path to the CppUnit library.
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``CppUnit_ROOT``
Preferred installation prefix.
``CPPUNIT_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``CPPUNIT_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``CPPUNIT_DEBUG_SUFFIX``
Suffix of the debug version of CppUnit libs. Defaults to "_d".
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``CPPUNIT_USE_STATIC_LIBS``
Only search for static cppunit libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
CppUnit_INCLUDE_DIR
CppUnit_LIBRARY
)
set(_FIND_CPPUNIT_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_CPPUNIT_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _CPPUNIT_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV CPPUNIT_ROOT from CMake 3.12
if(CppUnit_ROOT)
set(_CPPUNIT_ROOT ${CppUnit_ROOT})
elseif(DEFINED ENV{CppUnit_ROOT})
set(_CPPUNIT_ROOT $ENV{CppUnit_ROOT})
elseif(CPPUNIT_ROOT)
set(_CPPUNIT_ROOT ${CPPUNIT_ROOT})
elseif(DEFINED ENV{CPPUNIT_ROOT})
set(_CPPUNIT_ROOT $ENV{CPPUNIT_ROOT})
endif()
# Additionally try and use pkconfig to find cppunit
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
pkg_check_modules(PC_CppUnit QUIET cppunit)
endif()
# ------------------------------------------------------------------------
# Search for CppUnit include DIR
# ------------------------------------------------------------------------
set(_CPPUNIT_INCLUDE_SEARCH_DIRS "")
list(APPEND _CPPUNIT_INCLUDE_SEARCH_DIRS
${CPPUNIT_INCLUDEDIR}
${_CPPUNIT_ROOT}
${PC_CppUnit_INCLUDEDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Look for a standard cppunit header file.
find_path(CppUnit_INCLUDE_DIR cppunit/Portability.h
${_FIND_CPPUNIT_ADDITIONAL_OPTIONS}
PATHS ${_CPPUNIT_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
)
if(EXISTS "${CppUnit_INCLUDE_DIR}/cppunit/Portability.h")
file(STRINGS "${CppUnit_INCLUDE_DIR}/cppunit/Portability.h"
_cppunit_version_string REGEX "#define CPPUNIT_VERSION "
)
string(REGEX REPLACE "#define CPPUNIT_VERSION +\"(.+)\".*$" "\\1"
_cppunit_version_string "${_cppunit_version_string}"
)
string(STRIP "${_cppunit_version_string}" CppUnit_VERSION)
unset(_cppunit_version_string )
endif()
# ------------------------------------------------------------------------
# Search for CppUnit lib DIR
# ------------------------------------------------------------------------
if(NOT DEFINED CPPUNIT_DEBUG_SUFFIX)
set(CPPUNIT_DEBUG_SUFFIX "d")
endif()
set(_CPPUNIT_LIBRARYDIR_SEARCH_DIRS "")
list(APPEND _CPPUNIT_LIBRARYDIR_SEARCH_DIRS
${CPPUNIT_LIBRARYDIR}
${_CPPUNIT_ROOT}
${PC_CppUnit_LIBDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Library suffix handling
set(_CPPUNIT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(MSVC)
if(CPPUNIT_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
else()
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_dll.lib")
endif()
else()
if(CPPUNIT_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
endif()
list(APPEND CPPUNIT_BUILD_TYPES RELEASE DEBUG)
foreach(BUILD_TYPE ${CPPUNIT_BUILD_TYPES})
set(_CPPUNIT_LIB_NAME cppunit)
if(BUILD_TYPE STREQUAL DEBUG)
set(_CPPUNIT_LIB_NAME "${_CPPUNIT_LIB_NAME}${CPPUNIT_DEBUG_SUFFIX}")
endif()
# Find the lib
find_library(CppUnit_LIBRARY_${BUILD_TYPE} ${_CPPUNIT_LIB_NAME}
${_FIND_CPPUNIT_ADDITIONAL_OPTIONS}
PATHS ${_CPPUNIT_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib
)
endforeach()
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CPPUNIT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_CPPUNIT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
if(CppUnit_LIBRARY_DEBUG AND CppUnit_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(CppUnit_LIBRARY optimized ${CppUnit_LIBRARY_RELEASE} debug ${CppUnit_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(CppUnit_LIBRARY ${CppUnit_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(CppUnit_LIBRARIES optimized ${CppUnit_LIBRARY_RELEASE} debug ${CppUnit_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(CppUnit_LIBRARY_RELEASE AND NOT CppUnit_LIBRARY_DEBUG)
set(CppUnit_LIBRARY_DEBUG ${CppUnit_LIBRARY_RELEASE})
set(CppUnit_LIBRARY ${CppUnit_LIBRARY_RELEASE})
set(CppUnit_LIBRARIES ${CppUnit_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(CppUnit_LIBRARY_DEBUG AND NOT CppUnit_LIBRARY_RELEASE)
set(CppUnit_LIBRARY_RELEASE ${CppUnit_LIBRARY_DEBUG})
set(CppUnit_LIBRARY ${CppUnit_LIBRARY_DEBUG})
set(CppUnit_LIBRARIES ${CppUnit_LIBRARY_DEBUG})
endif()
# If the debug & release library ends up being the same, omit the keywords
if("${CppUnit_LIBRARY_RELEASE}" STREQUAL "${CppUnit_LIBRARY_DEBUG}")
set(CppUnit_LIBRARY ${CppUnit_LIBRARY_RELEASE} )
set(CppUnit_LIBRARIES ${CppUnit_LIBRARY_RELEASE} )
endif()
if(CppUnit_LIBRARY)
set(CppUnit_FOUND TRUE)
else()
set(CppUnit_FOUND FALSE)
endif()
# ------------------------------------------------------------------------
# Cache and set CppUnit_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CppUnit
FOUND_VAR CppUnit_FOUND
REQUIRED_VARS
CppUnit_LIBRARY
CppUnit_INCLUDE_DIR
VERSION_VAR CppUnit_VERSION
)
if(NOT CppUnit_FOUND)
if(CppUnit_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find CppUnit")
endif()
return()
endif()
# Partition release/debug lib vars
set(CppUnit_RELEASE_LIBRARIES ${CppUnit_LIBRARY_RELEASE})
get_filename_component(CppUnit_RELEASE_LIBRARY_DIRS ${CppUnit_RELEASE_LIBRARIES} DIRECTORY)
set(CppUnit_DEBUG_LIBRARIES ${CppUnit_LIBRARY_DEBUG})
get_filename_component(CppUnit_DEBUG_LIBRARY_DIRS ${CppUnit_DEBUG_LIBRARIES} DIRECTORY)
set(CppUnit_LIBRARIES ${CppUnit_RELEASE_LIBRARIES})
set(CppUnit_LIBRARY_DIRS ${CppUnit_RELEASE_LIBRARY_DIRS})
set(CppUnit_INCLUDE_DIRS ${CppUnit_INCLUDE_DIR})
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(CPPUNIT_LIB_TYPE UNKNOWN)
if(CPPUNIT_USE_STATIC_LIBS)
set(CPPUNIT_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_CPPUNIT_EXT ${CppUnit_LIBRARY_RELEASE} EXT)
if(_CPPUNIT_EXT STREQUAL ".a")
set(CPPUNIT_LIB_TYPE STATIC)
elseif(_CPPUNIT_EXT STREQUAL ".so" OR
_CPPUNIT_EXT STREQUAL ".dylib")
set(CPPUNIT_LIB_TYPE SHARED)
endif()
endif()
if(NOT TARGET CppUnit::cppunit)
add_library(CppUnit::cppunit ${CPPUNIT_LIB_TYPE} IMPORTED)
set_target_properties(CppUnit::cppunit PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_CppUnit_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${CppUnit_INCLUDE_DIRS}")
# Standard location
set_target_properties(CppUnit::cppunit PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${CppUnit_LIBRARY}")
# Release location
if(EXISTS "${CppUnit_LIBRARY_RELEASE}")
set_property(TARGET CppUnit::cppunit APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(CppUnit::cppunit PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${CppUnit_LIBRARY_RELEASE}")
endif()
# Debug location
if(EXISTS "${CppUnit_LIBRARY_DEBUG}")
set_property(TARGET CppUnit::cppunit APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(CppUnit::cppunit PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "${CppUnit_LIBRARY_DEBUG}")
endif()
endif()
-190
View File
@@ -1,190 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindJemalloc
-----------
Find Jemalloc include dirs and libraries
Use this module by invoking find_package with the form::
find_package(Jemalloc
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if Jemalloc is not found
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``Jemalloc::jemalloc``
This module defines IMPORTED target Jemalloc::jemalloc, if Jemalloc has been
found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Jemalloc_FOUND``
True if the system has the Jemalloc library.
``Jemalloc_VERSION``
The version of the Jemalloc library which was found.
``Jemalloc_LIBRARIES``
Libraries needed to link to Jemalloc.
``Jemalloc_LIBRARY_DIRS``
Jemalloc library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Jemalloc_LIBRARY``
The path to the Jemalloc library.
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``Jemalloc_ROOT``
Preferred installation prefix.
``JEMALLOC_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``JEMALLOC_USE_STATIC_LIBS``
Only search for static jemalloc libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
Jemalloc_LIBRARY
)
set(_FIND_JEMALLOC_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_JEMALLOC_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _JEMALLOC_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV JEMALLOC_ROOT from CMake 3.12
if(Jemalloc_ROOT)
set(_JEMALLOC_ROOT ${Jemalloc_ROOT})
elseif(DEFINED ENV{Jemalloc_ROOT})
set(_JEMALLOC_ROOT $ENV{Jemalloc_ROOT})
elseif(JEMALLOC_ROOT)
set(_JEMALLOC_ROOT ${JEMALLOC_ROOT})
elseif(DEFINED ENV{JEMALLOC_ROOT})
set(_JEMALLOC_ROOT $ENV{JEMALLOC_ROOT})
endif()
# Additionally try and use pkconfig to find jemalloc
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
pkg_check_modules(PC_Jemalloc QUIET jemalloc)
# ------------------------------------------------------------------------
# Search for Jemalloc lib DIR
# ------------------------------------------------------------------------
set(_JEMALLOC_LIBRARYDIR_SEARCH_DIRS "")
list(APPEND _JEMALLOC_LIBRARYDIR_SEARCH_DIRS
${JEMALLOC_LIBRARYDIR}
${_JEMALLOC_ROOT}
${PC_Jemalloc_LIBDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Library suffix handling
set(_JEMALLOC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(MSVC)
if(JEMALLOC_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
else()
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_dll.lib")
endif()
else()
if(JEMALLOC_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
endif()
# Build suffix directories
set(JEMALLOC_PATH_SUFFIXES
${CMAKE_INSTALL_LIBDIR}
lib64
lib
)
find_library(Jemalloc_LIBRARY jemalloc
${_FIND_JEMALLOC_ADDITIONAL_OPTIONS}
PATHS ${_JEMALLOC_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${JEMALLOC_PATH_SUFFIXES}
)
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_JEMALLOC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_JEMALLOC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
# ------------------------------------------------------------------------
# Cache and set Jemalloc_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Jemalloc
FOUND_VAR Jemalloc_FOUND
REQUIRED_VARS
Jemalloc_LIBRARY
VERSION_VAR Jemalloc_VERSION
)
if(Jemalloc_FOUND)
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(JEMALLOC_LIB_TYPE UNKNOWN)
if(JEMALLOC_USE_STATIC_LIBS)
set(JEMALLOC_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_JEMALLOC_EXT ${Jemalloc_LIBRARY} EXT)
if(_JEMALLOC_EXT STREQUAL ".a")
set(JEMALLOC_LIB_TYPE STATIC)
elseif(_JEMALLOC_EXT STREQUAL ".so" OR
_JEMALLOC_EXT STREQUAL ".dylib")
set(JEMALLOC_LIB_TYPE SHARED)
endif()
endif()
set(Jemalloc_LIBRARIES ${Jemalloc_LIBRARY})
get_filename_component(Jemalloc_LIBRARY_DIRS ${Jemalloc_LIBRARY} DIRECTORY)
if(NOT TARGET Jemalloc::jemalloc)
add_library(Jemalloc::jemalloc ${JEMALLOC_LIB_TYPE} IMPORTED)
set_target_properties(Jemalloc::jemalloc PROPERTIES
IMPORTED_LOCATION "${Jemalloc_LIBRARIES}"
INTERFACE_COMPILE_OPTIONS "${PC_Jemalloc_CFLAGS_OTHER}"
)
endif()
elseif(Jemalloc_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find Jemalloc")
endif()
-344
View File
@@ -1,344 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindLog4cplus
-------------
Find Log4cplus include dirs and libraries
Use this module by invoking find_package with the form::
find_package(Log4cplus
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if Log4cplus is not found
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``Log4cplus::Log4cplus``
This module defines IMPORTED target Log4cplus::log4cplus, if Log4cplus has been
found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Log4cplus_FOUND``
True if the system has the Log4cplus library.
``Log4cplus_VERSION``
The version of the Log4cplus library which was found.
``Log4cplus_INCLUDE_DIRS``
Include directories needed to use Log4cplus.
``Log4cplus_RELEASE_LIBRARIES``
Libraries needed to link to the release version of Log4cplus.
``Log4cplus_RELEASE_LIBRARY_DIRS``
Log4cplus release library directories.
``Log4cplus_DEBUG_LIBRARIES``
Libraries needed to link to the debug version of Log4cplus.
``Log4cplus_DEBUG_LIBRARY_DIRS``
Log4cplus debug library directories.
Deprecated - use [RELEASE|DEBUG] variants:
``Log4cplus_LIBRARIES``
Libraries needed to link to Log4cplus.
``Log4cplus_LIBRARY_DIRS``
Log4cplus library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Log4cplus_INCLUDE_DIR``
The directory containing ``log4cplus/version.h``.
``Log4cplus_LIBRARY``
The path to the Log4cplus library. may include target_link_libraries() debug/optimized keywords.
``Log4cplus_LIBRARY_RELEASE``
The path to the Log4cplus release library.
``Log4cplus_LIBRARY_DEBUG``
The path to the Log4cplus debug library.
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``Log4cplus_ROOT``
Preferred installation prefix.
``LOG4CPLUS_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``LOG4CPLUS_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``LOG4CPLUS_DEBUG_SUFFIX``
Suffix of the debug version of the log4cplus lib. Defaults to "D".
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``LOG4CPLUS_USE_STATIC_LIBS``
Only search for static log4cplus libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
Log4cplus_INCLUDE_DIR
Log4cplus_LIBRARY
)
set(_FIND_LOG4CPLUS_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_LOG4CPLUS_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _LOG4CPLUS_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV LOG4CPLUS_ROOT from CMake 3.12
if(Log4cplus_ROOT)
set(_LOG4CPLUS_ROOT ${Log4cplus_ROOT})
elseif(DEFINED ENV{Log4cplus_ROOT})
set(_LOG4CPLUS_ROOT $ENV{Log4cplus_ROOT})
elseif(LOG4CPLUS_ROOT)
set(_LOG4CPLUS_ROOT ${LOG4CPLUS_ROOT})
elseif(DEFINED ENV{LOG4CPLUS_ROOT})
set(_LOG4CPLUS_ROOT $ENV{LOG4CPLUS_ROOT})
endif()
# Additionally try and use pkconfig to find log4cplus
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_Log4cplus QUIET log4cplus)
endif()
endif()
# ------------------------------------------------------------------------
# Search for Log4cplus include DIR
# ------------------------------------------------------------------------
set(_LOG4CPLUS_INCLUDE_SEARCH_DIRS "")
list(APPEND _LOG4CPLUS_INCLUDE_SEARCH_DIRS
${LOG4CPLUS_INCLUDEDIR}
${_LOG4CPLUS_ROOT}
${PC_Log4cplus_INCLUDEDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Look for a standard log4cplus header file.
find_path(Log4cplus_INCLUDE_DIR log4cplus/version.h
${_FIND_LOG4CPLUS_ADDITIONAL_OPTIONS}
PATHS ${_LOG4CPLUS_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
)
if(EXISTS "${Log4cplus_INCLUDE_DIR}/log4cplus/version.h")
file(STRINGS "${Log4cplus_INCLUDE_DIR}/log4cplus/version.h"
_log4cplus_version_string REGEX "#define LOG4CPLUS_VERSION LOG4CPLUS_MAKE_VERSION"
)
string(REGEX REPLACE "#define LOG4CPLUS_VERSION LOG4CPLUS_MAKE_VERSION\((.*)\).*$" "\\1"
_log4cplus_version_string "${_log4cplus_version_string}"
)
string(REGEX REPLACE "[(]([0-9]+),.*[)].*$" "\\1"
Log4cplus_MAJOR_VERSION "${_log4cplus_version_string}"
)
string(REGEX REPLACE "[(].+, ([0-9]+),.+[)].*$" "\\1"
Log4cplus_MINOR_VERSION "${_log4cplus_version_string}"
)
string(REGEX REPLACE "[(].*,.*, ([0-9]+)[)].*$" "\\1"
Log4cplus_PATCH_VERSION "${_log4cplus_version_string}"
)
unset(_log4cplus_version_string)
set(Log4cplus_VERSION ${Log4cplus_MAJOR_VERSION}.${Log4cplus_MINOR_VERSION}.${Log4cplus_PATCH_VERSION})
endif()
# ------------------------------------------------------------------------
# Search for Log4cplus lib DIR
# ------------------------------------------------------------------------
if(NOT DEFINED LOG4CPLUS_DEBUG_SUFFIX)
set(LOG4CPLUS_DEBUG_SUFFIX D)
endif()
set(_LOG4CPLUS_LIBRARYDIR_SEARCH_DIRS "")
list(APPEND _LOG4CPLUS_LIBRARYDIR_SEARCH_DIRS
${LOG4CPLUS_LIBRARYDIR}
${_LOG4CPLUS_ROOT}
${PC_Log4cplus_LIBDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Library suffix handling
set(_LOG4CPLUS_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(MSVC)
if(LOG4CPLUS_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
endif()
else()
if(LOG4CPLUS_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
endif()
set(Log4cplus_LIB_COMPONENTS "")
list(APPEND LOG4CPLUS_BUILD_TYPES RELEASE DEBUG)
foreach(BUILD_TYPE ${LOG4CPLUS_BUILD_TYPES})
set(_LOG4CPLUS_LIB_NAME log4cplus)
if(BUILD_TYPE STREQUAL DEBUG)
set(_LOG4CPLUS_LIB_NAME "${_LOG4CPLUS_LIB_NAME}${LOG4CPLUS_DEBUG_SUFFIX}")
endif()
find_library(Log4cplus_LIBRARY_${BUILD_TYPE} ${_LOG4CPLUS_LIB_NAME}
${_FIND_LOG4CPLUS_ADDITIONAL_OPTIONS}
PATHS ${_LOG4CPLUS_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib
)
list(APPEND Log4cplus_LIB_COMPONENTS ${Log4cplus_LIBRARY_${BUILD_TYPE}})
endforeach()
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_LOG4CPLUS_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_LOG4CPLUS_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
if(Log4cplus_LIBRARY_DEBUG AND Log4cplus_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(Log4cplus_LIBRARY optimized ${Log4cplus_LIBRARY_RELEASE} debug ${Log4cplus_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(Log4cplus_LIBRARY ${Log4cplus_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(Log4cplus_LIBRARIES optimized ${Log4cplus_LIBRARY_RELEASE} debug ${Log4cplus_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(Log4cplus_LIBRARY_RELEASE AND NOT Log4cplus_LIBRARY_DEBUG)
set(Log4cplus_LIBRARY_DEBUG ${Log4cplus_LIBRARY_RELEASE})
set(Log4cplus_LIBRARY ${Log4cplus_LIBRARY_RELEASE})
set(Log4cplus_LIBRARIES ${Log4cplus_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(Log4cplus_LIBRARY_DEBUG AND NOT Log4cplus_LIBRARY_RELEASE)
set(Log4cplus_LIBRARY_RELEASE ${Log4cplus_LIBRARY_DEBUG})
set(Log4cplus_LIBRARY ${Log4cplus_LIBRARY_DEBUG})
set(Log4cplus_LIBRARIES ${Log4cplus_LIBRARY_DEBUG})
endif()
# If the debug & release library ends up being the same, omit the keywords
if("${Log4cplus_LIBRARY_RELEASE}" STREQUAL "${Log4cplus_LIBRARY_DEBUG}")
set(Log4cplus_LIBRARY ${Log4cplus_LIBRARY_RELEASE} )
set(Log4cplus_LIBRARIES ${Log4cplus_LIBRARY_RELEASE} )
endif()
if(Log4cplus_LIBRARY)
set(Log4cplus_FOUND TRUE)
else()
set(Log4cplus_FOUND FALSE)
endif()
# ------------------------------------------------------------------------
# Cache and set Log4cplus_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Log4cplus
FOUND_VAR Log4cplus_FOUND
REQUIRED_VARS
Log4cplus_LIBRARY
Log4cplus_INCLUDE_DIR
VERSION_VAR Log4cplus_VERSION
)
if(NOT Log4cplus_FOUND)
if(Log4cplus_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find Log4cplus")
endif()
return()
endif()
# Partition release/debug lib vars
set(Log4cplus_RELEASE_LIBRARIES ${Log4cplus_LIBRARY_RELEASE})
get_filename_component(Log4cplus_RELEASE_LIBRARY_DIRS ${Log4cplus_RELEASE_LIBRARIES} DIRECTORY)
set(Log4cplus_DEBUG_LIBRARIES ${Log4cplus_LIBRARY_DEBUG})
get_filename_component(Log4cplus_DEBUG_LIBRARY_DIRS ${Log4cplus_DEBUG_LIBRARIES} DIRECTORY)
set(Log4cplus_LIBRARIES ${Log4cplus_RELEASE_LIBRARIES})
set(Log4cplus_LIBRARY_DIRS ${Log4cplus_RELEASE_LIBRARY_DIRS})
set(Log4cplus_INCLUDE_DIRS ${Log4cplus_INCLUDE_DIR})
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(LOG4CPLUS_LIB_TYPE UNKNOWN)
if(LOG4CPLUS_USE_STATIC_LIBS)
set(LOG4CPLUS_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_LOG4CPLUS_EXT ${Log4cplus_LIBRARY} EXT)
if(_LOG4CPLUS_EXT STREQUAL ".a")
set(LOG4CPLUS_LIB_TYPE STATIC)
elseif(_LOG4CPLUS_EXT STREQUAL ".so" OR
_LOG4CPLUS_EXT STREQUAL ".dylib")
set(LOG4CPLUS_LIB_TYPE SHARED)
endif()
endif()
get_filename_component(Log4cplus_LIBRARY_DIRS ${Log4cplus_LIBRARY_RELEASE} DIRECTORY)
if(NOT TARGET Log4cplus::log4cplus)
add_library(Log4cplus::log4cplus ${LOG4CPLUS_LIB_TYPE} IMPORTED)
set_target_properties(Log4cplus::log4cplus PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_Log4cplus_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Log4cplus_INCLUDE_DIRS}")
# Standard location
set_target_properties(Log4cplus::log4cplus PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX;RC"
IMPORTED_LOCATION "${Log4cplus_LIBRARY}")
# WIN32 APIs
if(WIN32)
set_target_properties(Log4cplus::log4cplus PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES "ws2_32;advapi32")
endif()
# Release location
if(EXISTS "${Log4cplus_LIBRARY_RELEASE}")
set_property(TARGET Log4cplus::log4cplus APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Log4cplus::log4cplus PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX;RC"
IMPORTED_LOCATION_RELEASE "${Log4cplus_LIBRARY_RELEASE}")
endif()
# Debug location
if(EXISTS "${Log4cplus_LIBRARY_DEBUG}")
set_property(TARGET Log4cplus::log4cplus APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Log4cplus::log4cplus PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX;RC"
IMPORTED_LOCATION_DEBUG "${Log4cplus_LIBRARY_DEBUG}")
endif()
endif()
-442
View File
@@ -1,442 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindOpenEXR
-----------
Find OpenEXR include dirs and libraries
Use this module by invoking find_package with the form::
find_package(OpenEXR
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if OpenEXR is not found
[COMPONENTS <libs>...] # OpenEXR libraries by their canonical name
# e.g. "IlmImf" for "libIlmImf"
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``OpenEXR::IlmImf``
The IlmImf library target.
``OpenEXR::IlmImfUtil``
The IlmImfUtil library target.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``OpenEXR_FOUND``
True if the system has the OpenEXR library.
``OpenEXR_VERSION``
The version of the OpenEXR library which was found.
``OpenEXR_INCLUDE_DIRS``
Include directories needed to use OpenEXR.
``OpenEXR_RELEASE_LIBRARIES``
Libraries needed to link to the release version of OpenEXR.
``OpenEXR_RELEASE_LIBRARY_DIRS``
OpenEXR release library directories.
``OpenEXR_DEBUG_LIBRARIES``
Libraries needed to link to the debug version of OpenEXR.
``OpenEXR_DEBUG_LIBRARY_DIRS``
OpenEXR debug library directories.
``OpenEXR_DEFINITIONS``
Definitions to use when compiling code that uses OpenEXR.
``OpenEXR_{COMPONENT}_FOUND``
True if the system has the named OpenEXR component.
Deprecated - use [RELEASE|DEBUG] variants:
``OpenEXR_LIBRARIES``
Libraries needed to link to OpenEXR.
``OpenEXR_LIBRARY_DIRS``
OpenEXR library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``OpenEXR_INCLUDE_DIR``
The directory containing ``OpenEXR/config-auto.h``.
``OpenEXR_{COMPONENT}_LIBRARY``
Individual component libraries for OpenEXR. may include target_link_libraries() debug/optimized keywords.
``OpenEXR_{COMPONENT}_LIBRARY_RELEASE``
Individual component libraries for OpenEXR release
``OpenEXR_{COMPONENT}_LIBRARY_DEBUG``
Individual component libraries for OpenEXR debug
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``OpenEXR_ROOT``
Preferred installation prefix.
``OPENEXR_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``OPENEXR_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``OPENEXR_DEBUG_SUFFIX``
Suffix of the debug version of openexr libs. Defaults to "_d".
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``OPENEXR_USE_STATIC_LIBS``
Only search for static openexr libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
OpenEXR_INCLUDE_DIR
OpenEXR_LIBRARY
)
set(_FIND_OPENEXR_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_OPENEXR_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _OPENEXR_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV OPENEXR_ROOT from CMake 3.12
if(OpenEXR_ROOT)
set(_OPENEXR_ROOT ${OpenEXR_ROOT})
elseif(DEFINED ENV{OpenEXR_ROOT})
set(_OPENEXR_ROOT $ENV{OpenEXR_ROOT})
elseif(OPENEXR_ROOT)
set(_OPENEXR_ROOT ${OPENEXR_ROOT})
elseif(DEFINED ENV{OPENEXR_ROOT})
set(_OPENEXR_ROOT $ENV{OPENEXR_ROOT})
endif()
# Additionally try and use pkconfig to find OpenEXR
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
pkg_check_modules(PC_OpenEXR QUIET OpenEXR)
endif()
# ------------------------------------------------------------------------
# Search for OpenEXR include DIR
# ------------------------------------------------------------------------
set(_OPENEXR_INCLUDE_SEARCH_DIRS "")
list(APPEND _OPENEXR_INCLUDE_SEARCH_DIRS
${OPENEXR_INCLUDEDIR}
${_OPENEXR_ROOT}
${PC_OpenEXR_INCLUDEDIR}
${SYSTEM_LIBRARY_PATHS}
)
# Look for a standard OpenEXR header file.
find_path(OpenEXR_INCLUDE_DIR OpenEXRConfig.h
${_FIND_OPENEXR_ADDITIONAL_OPTIONS}
PATHS ${_OPENEXR_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR}/OpenEXR include/OpenEXR OpenEXR
)
if(EXISTS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h")
# Get the EXR version information from the config header
file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h"
_openexr_version_major_string REGEX "#define OPENEXR_VERSION_MAJOR "
)
string(REGEX REPLACE "#define OPENEXR_VERSION_MAJOR" ""
_openexr_version_major_string "${_openexr_version_major_string}"
)
string(STRIP "${_openexr_version_major_string}" OpenEXR_VERSION_MAJOR)
file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h"
_openexr_version_minor_string REGEX "#define OPENEXR_VERSION_MINOR "
)
string(REGEX REPLACE "#define OPENEXR_VERSION_MINOR" ""
_openexr_version_minor_string "${_openexr_version_minor_string}"
)
string(STRIP "${_openexr_version_minor_string}" OpenEXR_VERSION_MINOR)
unset(_openexr_version_major_string)
unset(_openexr_version_minor_string)
set(OpenEXR_VERSION ${OpenEXR_VERSION_MAJOR}.${OpenEXR_VERSION_MINOR})
endif()
if(${OpenEXR_VERSION} VERSION_GREATER_EQUAL 3.0)
set(_OPENEXR_COMPONENT_LIST OpenEXR OpenEXRUtil Iex IlmThread)
else()
set(_OPENEXR_COMPONENT_LIST IlmImf IlmImfUtil)
endif()
if(OpenEXR_FIND_COMPONENTS)
set(OPENEXR_COMPONENTS_PROVIDED TRUE)
set(_IGNORED_COMPONENTS "")
foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS})
if(NOT ${COMPONENT} IN_LIST _OPENEXR_COMPONENT_LIST)
list(APPEND _IGNORED_COMPONENTS ${COMPONENT})
endif()
endforeach()
if(_IGNORED_COMPONENTS)
message(STATUS "Ignoring unknown components of OpenEXR:")
foreach(COMPONENT ${_IGNORED_COMPONENTS})
message(STATUS " ${COMPONENT}")
endforeach()
list(REMOVE_ITEM OpenEXR_FIND_COMPONENTS ${_IGNORED_COMPONENTS})
endif()
else()
set(OPENEXR_COMPONENTS_PROVIDED FALSE)
set(OpenEXR_FIND_COMPONENTS ${_OPENEXR_COMPONENT_LIST})
endif()
# ------------------------------------------------------------------------
# Search for OPENEXR lib DIR
# ------------------------------------------------------------------------
if(NOT DEFINED OPENEXR_DEBUG_SUFFIX)
set(OPENEXR_DEBUG_SUFFIX _d)
endif()
set(_OPENEXR_LIBRARYDIR_SEARCH_DIRS "")
# Append to _OPENEXR_LIBRARYDIR_SEARCH_DIRS in priority order
list(APPEND _OPENEXR_LIBRARYDIR_SEARCH_DIRS
${OPENEXR_LIBRARYDIR}
${_OPENEXR_ROOT}
${PC_OpenEXR_LIBDIR}
${SYSTEM_LIBRARY_PATHS}
)
set(OpenEXR_LIB_COMPONENTS "")
list(APPEND OPENEXR_BUILD_TYPES RELEASE DEBUG)
foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS})
foreach(BUILD_TYPE ${OPENEXR_BUILD_TYPES})
set(_TMP_SUFFIX "")
if(BUILD_TYPE STREQUAL DEBUG)
set(_TMP_SUFFIX ${OPENEXR_DEBUG_SUFFIX})
endif()
set(_OpenEXR_Version_Suffix "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}")
set(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
if(OPENEXR_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES "${_TMP_SUFFIX}.lib")
endif()
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.lib")
else()
if(OPENEXR_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES "${_TMP_SUFFIX}.a")
else()
if(APPLE)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.dylib")
else()
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.so")
endif()
endif()
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.a")
endif()
# Find the lib
find_library(OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE} ${COMPONENT}
${_FIND_OPENEXR_ADDITIONAL_OPTIONS}
PATHS ${_OPENEXR_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib
)
if(EXISTS ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
list(APPEND OpenEXR_LIB_COMPONENTS ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
list(APPEND OpenEXR_LIB_COMPONENTS_${BUILD_TYPE} ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
endif()
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
unset(_OpenEXR_Version_Suffix)
unset(_TMP_SUFFIX)
endforeach()
if(OpenEXR_${COMPONENT}_LIBRARY_DEBUG AND OpenEXR_${COMPONENT}_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(OpenEXR_${COMPONENT}_LIBRARY optimized ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} debug ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(OpenEXR_${COMPONENT}_LIBRARIES optimized ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} debug ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(OpenEXR_${COMPONENT}_LIBRARY_RELEASE AND NOT OpenEXR_${COMPONENT}_LIBRARY_DEBUG)
set(OpenEXR_${COMPONENT}_LIBRARY_DEBUG ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE})
set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE})
set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(OpenEXR_${COMPONENT}_LIBRARY_DEBUG AND NOT OpenEXR_${COMPONENT}_LIBRARY_RELEASE)
set(OpenEXR_${COMPONENT}_LIBRARY_RELEASE ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG})
set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG})
set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG})
endif()
# If the debug & release library ends up being the same, omit the keywords
if("${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}" STREQUAL "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}")
set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} )
set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} )
endif()
if(OpenEXR_${COMPONENT}_LIBRARY)
set(OpenEXR_${COMPONENT}_FOUND TRUE)
else()
set(OpenEXR_${COMPONENT}_FOUND FALSE)
endif()
endforeach()
# ------------------------------------------------------------------------
# Cache and set OPENEXR_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenEXR
FOUND_VAR OpenEXR_FOUND
REQUIRED_VARS
OpenEXR_INCLUDE_DIR
OpenEXR_LIB_COMPONENTS
VERSION_VAR OpenEXR_VERSION
HANDLE_COMPONENTS
)
if(NOT OpenEXR_FOUND)
if(OpenEXR_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find OpenEXR")
endif()
return()
endif()
# Partition release/debug lib vars
set(OpenEXR_RELEASE_LIBRARIES "")
set(OpenEXR_RELEASE_LIBRARY_DIRS "")
set(OpenEXR_DEBUG_LIBRARIES "")
set(OpenEXR_DEBUG_LIBRARY_DIRS "")
foreach(LIB ${OpenEXR_LIB_COMPONENTS_RELEASE})
get_filename_component(_EXR_LIBDIR ${LIB} DIRECTORY)
list(APPEND OpenEXR_RELEASE_LIBRARIES ${LIB})
list(APPEND OpenEXR_RELEASE_LIBRARY_DIRS ${_EXR_LIBDIR})
endforeach()
foreach(LIB ${OpenEXR_LIB_COMPONENTS_DEBUG})
get_filename_component(_EXR_LIBDIR ${LIB} DIRECTORY)
list(APPEND OpenEXR_DEBUG_LIBRARIES ${LIB})
list(APPEND OpenEXR_DEBUG_LIBRARY_DIRS ${_EXR_LIBDIR})
endforeach()
list(REMOVE_DUPLICATES OpenEXR_RELEASE_LIBRARY_DIRS)
list(REMOVE_DUPLICATES OpenEXR_DEBUG_LIBRARY_DIRS)
set(OpenEXR_LIBRARIES ${OpenEXR_RELEASE_LIBRARIES})
set(OpenEXR_LIBRARY_DIRS ${OpenEXR_RELEASE_LIBRARY_DIRS})
# We have to add both include and include/OpenEXR to the include
# path in case OpenEXR and IlmBase are installed separately.
#
# Make sure we get the absolute path to avoid issues where
# /usr/include/OpenEXR/../ is picked up and passed to gcc from cmake
# which won't correctly compute /usr/include as an implicit system
# dir if the path is relative:
#
# https://github.com/AcademySoftwareFoundation/openvdb/issues/632
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129
set(_OpenEXR_Parent_Dir "")
get_filename_component(_OpenEXR_Parent_Dir
${OpenEXR_INCLUDE_DIR}/../ ABSOLUTE)
set(OpenEXR_INCLUDE_DIRS)
list(APPEND OpenEXR_INCLUDE_DIRS
${_OpenEXR_Parent_Dir}
${OpenEXR_INCLUDE_DIR}
)
unset(_OpenEXR_Parent_Dir)
# Configure imported target
foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS})
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(OpenEXR_${COMPONENT}_LIB_TYPE UNKNOWN)
if(OPENEXR_USE_STATIC_LIBS)
set(OpenEXR_${COMPONENT}_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_OpenEXR_${COMPONENT}_EXT ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} EXT)
if(${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".a")
set(OpenEXR_${COMPONENT}_LIB_TYPE STATIC)
elseif(${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".so" OR
${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".dylib")
set(OpenEXR_${COMPONENT}_LIB_TYPE SHARED)
endif()
endif()
set(OpenEXR_${COMPONENT}_DEFINITIONS)
# Add the OPENEXR_DLL define if the library is not static on WIN32
if(WIN32)
if(NOT OpenEXR_${COMPONENT}_LIB_TYPE STREQUAL STATIC)
list(APPEND OpenEXR_${COMPONENT}_DEFINITIONS OPENEXR_DLL)
endif()
endif()
if(NOT TARGET OpenEXR::${COMPONENT})
add_library(OpenEXR::${COMPONENT} ${OpenEXR_${COMPONENT}_LIB_TYPE} IMPORTED)
set_target_properties(OpenEXR::${COMPONENT} PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_OpenEXR_CFLAGS_OTHER}"
INTERFACE_COMPILE_DEFINITIONS "${OpenEXR_${COMPONENT}_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenEXR_INCLUDE_DIRS}")
# Standard location
set_target_properties(OpenEXR::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${OpenEXR_${COMPONENT}_LIBRARY}")
# Release location
if(EXISTS "${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}")
set_property(TARGET OpenEXR::${COMPONENT} APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(OpenEXR::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}")
endif()
# Debug location
if(EXISTS "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}")
set_property(TARGET OpenEXR::${COMPONENT} APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(OpenEXR::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}")
endif()
endif()
endforeach()
-810
View File
@@ -1,810 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindOpenVDB
-----------
Find OpenVDB include dirs, libraries and settings
Use this module by invoking find_package with the form::
find_package(OpenVDB
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if OpenVDB is not found
[COMPONENTS <libs>...] # OpenVDB libraries by their canonical name
# e.g. "openvdb" for "libopenvdb",
# "pyopenvdb" for the python plugin
# "openvdb_ax" for the OpenVDB AX extension
# "openvdb_houdini" for the houdini plugin
# "nanovdb" for the nanovdb extension
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``OpenVDB::openvdb``
The core openvdb library target.
``OpenVDB::openvdb_je``
The core openvdb library target with jemalloc.
``OpenVDB::pyopenvdb``
The openvdb python library target.
``OpenVDB::openvdb_houdini``
The openvdb houdini library target.
``OpenVDB::openvdb_ax``
The openvdb_ax library target.
``OpenVDB::nanovdb``
The nanovdb library target.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``OpenVDB_FOUND``
True if the system has the OpenVDB library.
``OpenVDB_VERSION``
The version of the OpenVDB library which was found.
``OpenVDB_INCLUDE_DIRS``
Include directories needed to use OpenVDB.
``OpenVDB_LIBRARIES``
Libraries needed to link to OpenVDB.
``OpenVDB_LIBRARY_DIRS``
OpenVDB library directories.
``OpenVDB_DEFINITIONS``
Definitions to use when compiling code that uses OpenVDB.
``OpenVDB_${COMPONENT}_FOUND``
True if the system has the named OpenVDB component.
``OpenVDB_USES_BLOSC``
True if the OpenVDB Library has been built with blosc support
``OpenVDB_USES_ZLIB``
True if the OpenVDB Library has been built with zlib support
``OpenVDB_USES_LOG4CPLUS``
True if the OpenVDB Library has been built with log4cplus support
``OpenVDB_USES_IMATH_HALF``
True if the OpenVDB Library has been built with Imath half support
``OpenVDB_USES_DELAYED_LOADING``
True if the OpenVDB Library has been built with delayed-loading
``OpenVDB_ABI``
Set if this module was able to determine the ABI number the located
OpenVDB Library was built against. Unset otherwise.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``OpenVDB_INCLUDE_DIR``
The directory containing ``openvdb/version.h``.
``OpenVDB_${COMPONENT}_INCLUDE_DIR``
Individual component include directories for OpenVDB
``OpenVDB_${COMPONENT}_LIBRARY``
Individual component libraries for OpenVDB
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``OpenVDB_ROOT``
Preferred installation prefix.
``OPENVDB_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``OPENVDB_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``OPENVDB_${COMPONENT}_ROOT``
Preferred installation prefix of a specific component.
``OPENVDB_${COMPONENT}_INCLUDEDIR``
Preferred include directory of a specific component e.g. <prefix>/include
``OPENVDB_${COMPONENT}_LIBRARYDIR``
Preferred library directory of a specific component e.g. <prefix>/lib
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``OPENVDB_USE_STATIC_LIBS``
Only search for static openvdb libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
# Include utility functions for version information
include(${CMAKE_CURRENT_LIST_DIR}/OpenVDBUtils.cmake)
mark_as_advanced(
OpenVDB_INCLUDE_DIR
OpenVDB_LIBRARY
)
set(_FIND_OPENVDB_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_OPENVDB_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
set(_OPENVDB_COMPONENT_LIST
openvdb
openvdb_je
pyopenvdb
openvdb_ax
openvdb_houdini
nanovdb
)
if(OpenVDB_FIND_COMPONENTS)
set(OPENVDB_COMPONENTS_PROVIDED TRUE)
set(_IGNORED_COMPONENTS "")
foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS})
if(NOT ${COMPONENT} IN_LIST _OPENVDB_COMPONENT_LIST)
list(APPEND _IGNORED_COMPONENTS ${COMPONENT})
endif()
endforeach()
if(_IGNORED_COMPONENTS)
message(STATUS "Ignoring unknown components of OpenVDB:")
foreach(COMPONENT ${_IGNORED_COMPONENTS})
message(STATUS " ${COMPONENT}")
endforeach()
list(REMOVE_ITEM OpenVDB_FIND_COMPONENTS ${_IGNORED_COMPONENTS})
endif()
else()
set(OPENVDB_COMPONENTS_PROVIDED FALSE)
set(OpenVDB_FIND_COMPONENTS openvdb)
endif()
# always make sure openvdb is picked up as a component i.e.
# find_package(OpenVDB COMPONENTS pyopenvdb) results in both
# openvdb and pyopenvdb targets. Also make sure it appears
# first in the component lists.
list(INSERT OpenVDB_FIND_COMPONENTS 0 openvdb)
list(REMOVE_DUPLICATES OpenVDB_FIND_COMPONENTS)
# Set _OPENVDB_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV OPENVDB_ROOT from CMake 3.12
if(OpenVDB_ROOT)
set(_OPENVDB_ROOT ${OpenVDB_ROOT})
elseif(DEFINED ENV{OpenVDB_ROOT})
set(_OPENVDB_ROOT $ENV{OpenVDB_ROOT})
elseif(OPENVDB_ROOT)
set(_OPENVDB_ROOT ${OPENVDB_ROOT})
elseif(DEFINED ENV{OPENVDB_ROOT})
set(_OPENVDB_ROOT $ENV{OPENVDB_ROOT})
endif()
# Additionally try and use pkconfig to find OpenVDB
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
pkg_check_modules(PC_OpenVDB QUIET OpenVDB)
endif()
# This CMake module supports being called from external packages AND from
# within the OpenVDB repository for building openvdb components with the
# core library build disabled. Determine where we are being called from:
#
# (repo structure = <root>/cmake/FindOpenVDB.cmake)
# (inst structure = <root>/lib/cmake/OpenVDB/FindOpenVDB.cmake)
get_filename_component(_DIR_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
if(${_DIR_NAME} STREQUAL "cmake")
# Called from root repo for openvdb components
elseif(${_DIR_NAME} STREQUAL "OpenVDB")
# Set the install variable to track directories if this is being called from
# an installed location and from another package. The expected installation
# directory structure is:
# <root>/lib/cmake/OpenVDB/FindOpenVDB.cmake
# <root>/include
# <root>/bin
get_filename_component(_IMPORT_PREFIX ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
get_filename_component(_IMPORT_PREFIX ${_IMPORT_PREFIX} DIRECTORY)
get_filename_component(_IMPORT_PREFIX ${_IMPORT_PREFIX} DIRECTORY)
set(_OPENVDB_INSTALL ${_IMPORT_PREFIX})
list(APPEND _OPENVDB_ROOT ${_OPENVDB_INSTALL})
endif()
unset(_DIR_NAME)
unset(_IMPORT_PREFIX)
# ------------------------------------------------------------------------
# Search for OpenVDB include DIR
# ------------------------------------------------------------------------
set(_OPENVDB_INCLUDE_SEARCH_DIRS "")
list(APPEND _OPENVDB_INCLUDE_SEARCH_DIRS
${OPENVDB_INCLUDEDIR}
${_OPENVDB_ROOT}
${PC_OpenVDB_INCLUDE_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS})
# Add in extra component paths
set(_VDB_COMPONENT_SEARCH_DIRS ${_OPENVDB_INCLUDE_SEARCH_DIRS})
list(APPEND _VDB_COMPONENT_SEARCH_DIRS
${OPENVDB_${COMPONENT}_ROOT}
${OPENVDB_${COMPONENT}_INCLUDEDIR}
)
if(_VDB_COMPONENT_SEARCH_DIRS)
list(REMOVE_DUPLICATES _VDB_COMPONENT_SEARCH_DIRS)
endif()
# Look for a standard header files.
if(${COMPONENT} STREQUAL "openvdb")
# Look for a standard OpenVDB header file.
find_path(OpenVDB_${COMPONENT}_INCLUDE_DIR openvdb/version.h
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES
${CMAKE_INSTALL_INCLUDEDIR}
include
)
elseif(${COMPONENT} STREQUAL "pyopenvdb")
find_path(OpenVDB_${COMPONENT}_INCLUDE_DIR pyopenvdb.h
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES
${CMAKE_INSTALL_INCLUDEDIR}/openvdb/python
${CMAKE_INSTALL_INCLUDEDIR}/openvdb
${CMAKE_INSTALL_INCLUDEDIR}
include
)
elseif(${COMPONENT} STREQUAL "openvdb_ax")
# Look for a standard OpenVDB header file.
find_path(OpenVDB_${COMPONENT}_INCLUDE_DIR compiler/Compiler.h
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES
${CMAKE_INSTALL_INCLUDEDIR}/openvdb/openvdb_ax
${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax
${CMAKE_INSTALL_INCLUDEDIR}
include
)
elseif(${COMPONENT} STREQUAL "openvdb_houdini")
# @note Expects both houdini_utils and openvdb_houdini folders
# to be located in the same place
find_path(OpenVDB_${COMPONENT}_INCLUDE_DIR openvdb_houdini/SOP_NodeVDB.h
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES
${CMAKE_INSTALL_INCLUDEDIR}/openvdb
${CMAKE_INSTALL_INCLUDEDIR}
include
)
elseif(${COMPONENT} STREQUAL "nanovdb")
# Look for NanoVDB.h
find_path(OpenVDB_${COMPONENT}_INCLUDE_DIR NanoVDB.h
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES
${CMAKE_INSTALL_INCLUDEDIR}/nanovdb
${CMAKE_INSTALL_INCLUDEDIR}
include
)
endif()
unset(_VDB_COMPONENT_SEARCH_DIRS)
endforeach()
set(OpenVDB_INCLUDE_DIR ${OpenVDB_openvdb_INCLUDE_DIR}
CACHE PATH "The OpenVDB core include directory")
set(_OPENVDB_VERSION_HEADER "${OpenVDB_INCLUDE_DIR}/openvdb/version.h")
OPENVDB_VERSION_FROM_HEADER("${_OPENVDB_VERSION_HEADER}"
VERSION OpenVDB_VERSION
MAJOR OpenVDB_MAJOR_VERSION
MINOR OpenVDB_MINOR_VERSION
PATCH OpenVDB_PATCH_VERSION
ABI OpenVDB_ABI_FROM_HEADER # will be OpenVDB_MAJOR_VERSION prior to 8.1.0
)
if(OpenVDB_VERSION VERSION_LESS 8.1.0)
set(_OPENVDB_HAS_NEW_VERSION_HEADER FALSE)
# ABI gets computed later
else()
set(_OPENVDB_HAS_NEW_VERSION_HEADER TRUE)
set(OpenVDB_ABI ${OpenVDB_ABI_FROM_HEADER})
endif()
unset(OpenVDB_ABI_FROM_HEADER)
# ------------------------------------------------------------------------
# Search for OPENVDB lib DIR
# ------------------------------------------------------------------------
set(_OPENVDB_LIBRARYDIR_SEARCH_DIRS "")
# Append to _OPENVDB_LIBRARYDIR_SEARCH_DIRS in priority order
list(APPEND _OPENVDB_LIBRARYDIR_SEARCH_DIRS
${OPENVDB_LIBRARYDIR}
${_OPENVDB_ROOT}
${PC_OpenVDB_LIBRARY_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
# Library suffix handling
set(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(OPENVDB_PYTHON_PATH_SUFFIXES
lib64/python
lib64/python3
lib/python
lib/python3
)
# Recurse through all the site-packages and dist-packages on the file system
file(GLOB PYTHON_SITE_PACKAGES ${CMAKE_INSTALL_FULL_LIBDIR}/python**/*)
foreach(_site_package_full_dir ${PYTHON_SITE_PACKAGES})
string(REPLACE ${CMAKE_INSTALL_FULL_LIBDIR} "${CMAKE_INSTALL_LIBDIR}"
_site_package_dir ${_site_package_full_dir})
list(APPEND OPENVDB_PYTHON_PATH_SUFFIXES ${_site_package_dir})
endforeach()
set(OPENVDB_LIB_PATH_SUFFIXES
${CMAKE_INSTALL_LIBDIR}
lib64
lib
)
list(REMOVE_DUPLICATES OPENVDB_PYTHON_PATH_SUFFIXES)
list(REMOVE_DUPLICATES OPENVDB_LIB_PATH_SUFFIXES)
# Static library setup
if(MSVC)
if(OPENVDB_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
endif()
else()
if(OPENVDB_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
endif()
set(OpenVDB_LIB_COMPONENTS "")
foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS})
message("COMPONENT = " ${COMPONENT})
set(LIB_NAME ${COMPONENT})
# Add in extra component paths
set(_VDB_COMPONENT_SEARCH_DIRS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS})
list(APPEND _VDB_COMPONENT_SEARCH_DIRS
${OPENVDB_${COMPONENT}_ROOT}
${OPENVDB_${COMPONENT}_LIBRARYDIR}
)
if(${COMPONENT} STREQUAL "pyopenvdb")
set(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
set(CMAKE_FIND_LIBRARY_PREFIXES ";lib") # find non-prefixed
find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME}
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES ${OPENVDB_PYTHON_PATH_SUFFIXES}
)
set(CMAKE_FIND_LIBRARY_PREFIXES ${_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_PREFIXES})
elseif(${COMPONENT} STREQUAL "openvdb_je")
# alias to the result of openvdb which should be handled first
set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_openvdb_LIBRARY})
elseif(${COMPONENT} STREQUAL "nanovdb")
# alias to the result of openvdb which should be handled first
set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_openvdb_LIBRARY})
else()
find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME}
${_FIND_OPENVDB_ADDITIONAL_OPTIONS}
PATHS ${_VDB_COMPONENT_SEARCH_DIRS}
PATH_SUFFIXES ${OPENVDB_LIB_PATH_SUFFIXES}
)
endif()
list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY})
if(${COMPONENT} STREQUAL "nanovdb")
# nanovdb is headers-only, no lib component
if(OpenVDB_${COMPONENT}_INCLUDE_DIR)
set(OpenVDB_${COMPONENT}_FOUND TRUE)
else()
set(OpenVDB_${COMPONENT}_FOUND FALSE)
endif()
else()
if(OpenVDB_${COMPONENT}_LIBRARY)
set(OpenVDB_${COMPONENT}_FOUND TRUE)
else()
set(OpenVDB_${COMPONENT}_FOUND FALSE)
endif()
endif()
unset(_VDB_COMPONENT_SEARCH_DIRS)
endforeach()
unset(OPENVDB_PYTHON_PATH_SUFFIXES)
unset(OPENVDB_LIB_PATH_SUFFIXES)
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
# ------------------------------------------------------------------------
# Cache and set OPENVDB_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenVDB
FOUND_VAR OpenVDB_FOUND
REQUIRED_VARS
OpenVDB_INCLUDE_DIR
OpenVDB_LIB_COMPONENTS
VERSION_VAR OpenVDB_VERSION
HANDLE_COMPONENTS
)
# ------------------------------------------------------------------------
# Determine ABI number
# ------------------------------------------------------------------------
# Set the ABI number the library was built against. The old system,
# which didn't define the ABI in the build config, uses vdb_print
if(NOT _OPENVDB_HAS_NEW_VERSION_HEADER)
if(_OPENVDB_INSTALL)
OPENVDB_ABI_VERSION_FROM_PRINT(
"${_OPENVDB_INSTALL}/bin/vdb_print"
ABI OpenVDB_ABI
)
else()
# Try and find vdb_print from the include path
OPENVDB_ABI_VERSION_FROM_PRINT(
"${OpenVDB_INCLUDE_DIR}/../bin/vdb_print"
ABI OpenVDB_ABI
)
endif()
endif()
if(NOT OpenVDB_FIND_QUIETLY)
if(NOT OpenVDB_ABI)
message(WARNING "Unable to determine OpenVDB ABI version from OpenVDB "
"installation. The library major version \"${OpenVDB_MAJOR_VERSION}\" "
"will be inferred. If this is not correct, use "
"add_definitions(-DOPENVDB_ABI_VERSION_NUMBER=N)"
)
else()
message(STATUS "OpenVDB ABI Version: ${OpenVDB_ABI}")
endif()
endif()
# ------------------------------------------------------------------------
# Handle OpenVDB dependencies and interface settings
# ------------------------------------------------------------------------
# Handle openvdb_houdini first to configure search paths
if(openvdb_houdini IN_LIST OpenVDB_FIND_COMPONENTS)
include(OpenVDBHoudiniSetup)
endif()
# Add standard dependencies
find_package(TBB REQUIRED COMPONENTS tbb)
# Add deps for pyopenvdb
if(pyopenvdb IN_LIST OpenVDB_FIND_COMPONENTS)
find_package(Python REQUIRED)
endif()
# Add deps for openvdb_ax
if(openvdb_ax IN_LIST OpenVDB_FIND_COMPONENTS)
find_package(LLVM REQUIRED)
find_library(found_LLVM LLVM HINTS ${LLVM_LIBRARY_DIRS})
if(found_LLVM)
set(LLVM_LIBS "LLVM")
else()
llvm_map_components_to_libnames(_llvm_libs
native core executionengine support mcjit passes objcarcopts)
set(LLVM_LIBS "${_llvm_libs}")
endif()
if(NOT OpenVDB_FIND_QUIET)
message(STATUS "Found LLVM: ${LLVM_DIR} (found version \"${LLVM_PACKAGE_VERSION}\")")
endif()
endif()
# As the way we resolve optional libraries relies on library file names, use
# the configuration options from the main CMakeLists.txt to allow users
# to manually identify the requirements of OpenVDB builds if they know them.
set(OpenVDB_USES_BLOSC ${USE_BLOSC})
set(OpenVDB_USES_ZLIB ${USE_ZLIB})
set(OpenVDB_USES_LOG4CPLUS ${USE_LOG4CPLUS})
set(OpenVDB_USES_IMATH_HALF ${USE_IMATH_HALF})
set(OpenVDB_USES_DELAYED_LOADING ${OPENVDB_USE_DELAYED_LOADING})
set(OpenVDB_DEFINITIONS)
if(WIN32)
if(OPENVDB_USE_STATIC_LIBS)
list(APPEND OpenVDB_DEFINITIONS OPENVDB_STATICLIB)
else()
list(APPEND OpenVDB_DEFINITIONS OPENVDB_DLL)
endif()
# Newer version of OpenVDB define these in Platform.h, but they are also
# provided here to maintain backwards compatibility with header include
# others
list(APPEND OpenVDB_DEFINITIONS _WIN32)
list(APPEND OpenVDB_DEFINITIONS NOMINMAX)
endif()
if(MINGW)
list(APPEND OpenVDB_DEFINITIONS _USE_MATH_DEFINES)
endif()
if(OpenVDB_ABI)
# Newer version of OpenVDB defines this in version.h, but it is are also
# provided here to maintain backwards compatibility with header include
# others
list(APPEND OpenVDB_DEFINITIONS OPENVDB_ABI_VERSION_NUMBER=${OpenVDB_ABI})
endif()
# Configure deps
if(_OPENVDB_HAS_NEW_VERSION_HEADER)
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_IMATH_HALF" OpenVDB_USES_IMATH_HALF)
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_BLOSC" OpenVDB_USES_BLOSC)
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_ZLIB" OpenVDB_USES_ZLIB)
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_DELAYED_LOADING" OpenVDB_USES_DELAYED_LOADING)
elseif(NOT OPENVDB_USE_STATIC_LIBS)
# Use GetPrerequisites to see which libraries this OpenVDB lib has linked to
# which we can query for optional deps. This basically runs ldd/otoll/objdump
# etc to track deps. We could use a vdb_config binary tools here to improve
# this process
include(GetPrerequisites)
set(_EXCLUDE_SYSTEM_PREREQUISITES 1)
set(_RECURSE_PREREQUISITES 0)
set(_OPENVDB_PREREQUISITE_LIST)
get_prerequisites(${OpenVDB_openvdb_LIBRARY}
_OPENVDB_PREREQUISITE_LIST
${_EXCLUDE_SYSTEM_PREREQUISITES}
${_RECURSE_PREREQUISITES}
""
"${SYSTEM_LIBRARY_PATHS}"
)
unset(_EXCLUDE_SYSTEM_PREREQUISITES)
unset(_RECURSE_PREREQUISITES)
# Search for optional dependencies
foreach(PREREQUISITE ${_OPENVDB_PREREQUISITE_LIST})
set(_HAS_DEP)
get_filename_component(PREREQUISITE ${PREREQUISITE} NAME)
string(FIND ${PREREQUISITE} "blosc" _HAS_DEP)
if(NOT ${_HAS_DEP} EQUAL -1)
set(OpenVDB_USES_BLOSC ON)
endif()
string(FIND ${PREREQUISITE} "zlib" _HAS_DEP)
if(NOT ${_HAS_DEP} EQUAL -1)
set(OpenVDB_USES_ZLIB ON)
endif()
string(FIND ${PREREQUISITE} "log4cplus" _HAS_DEP)
if(NOT ${_HAS_DEP} EQUAL -1)
set(OpenVDB_USES_LOG4CPLUS ON)
endif()
string(FIND ${PREREQUISITE} "Half" _HAS_DEP)
if(NOT ${_HAS_DEP} EQUAL -1)
set(OpenVDB_USES_IMATH_HALF ON)
endif()
string(FIND ${PREREQUISITE} "boost_iostreams" _HAS_DEP)
if(NOT ${_HAS_DEP} EQUAL -1)
set(OpenVDB_USES_DELAYED_LOADING ON)
endif()
endforeach()
unset(_OPENVDB_PREREQUISITE_LIST)
endif()
if(OpenVDB_USES_BLOSC)
find_package(Blosc REQUIRED)
endif()
if(OpenVDB_USES_ZLIB)
find_package(ZLIB REQUIRED)
endif()
if(OpenVDB_USES_LOG4CPLUS)
find_package(Log4cplus REQUIRED)
endif()
if(OpenVDB_USES_IMATH_HALF)
find_package(Imath REQUIRED CONFIG)
endif()
if(OpenVDB_USES_DELAYED_LOADING)
find_package(Boost REQUIRED COMPONENTS iostreams)
endif()
if(UNIX)
find_package(Threads REQUIRED)
endif()
# Set deps. Note that the order here is important. If we're building against
# Houdini we must include Imath deps first to ensure the users chosen
# namespaced headers are correctly prioritized. Otherwise other include paths
# from shared installs (including houdini) may pull in the wrong headers
set(_OPENVDB_VISIBLE_DEPENDENCIES "")
if(OpenVDB_USES_DELAYED_LOADING)
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES Boost::iostreams)
list(APPEND OpenVDB_DEFINITIONS OPENVDB_USE_DELAYED_LOADING)
endif()
if(OpenVDB_USES_IMATH_HALF)
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES Imath::Imath)
endif()
if(OpenVDB_USES_LOG4CPLUS)
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES Log4cplus::log4cplus)
list(APPEND OpenVDB_DEFINITIONS OPENVDB_USE_LOG4CPLUS)
endif()
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES
TBB::tbb
)
if(UNIX)
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES
Threads::Threads
)
endif()
set(_OPENVDB_HIDDEN_DEPENDENCIES)
if(NOT OPENVDB_USE_STATIC_LIBS)
if(OpenVDB_USES_BLOSC)
list(APPEND _OPENVDB_HIDDEN_DEPENDENCIES Blosc::blosc)
endif()
if(OpenVDB_USES_ZLIB)
list(APPEND _OPENVDB_HIDDEN_DEPENDENCIES ZLIB::ZLIB)
endif()
endif()
if(openvdb_je IN_LIST OpenVDB_FIND_COMPONENTS)
find_package(Jemalloc REQUIRED)
endif()
# ------------------------------------------------------------------------
# Configure imported targets
# ------------------------------------------------------------------------
set(OpenVDB_LIBRARIES ${OpenVDB_LIB_COMPONENTS})
set(OpenVDB_INCLUDE_DIRS ${OpenVDB_INCLUDE_DIR})
set(OpenVDB_LIBRARY_DIRS "")
foreach(LIB ${OpenVDB_LIB_COMPONENTS})
get_filename_component(_OPENVDB_LIBDIR ${LIB} DIRECTORY)
list(APPEND OpenVDB_LIBRARY_DIRS ${_OPENVDB_LIBDIR})
endforeach()
list(REMOVE_DUPLICATES OpenVDB_LIBRARY_DIRS)
# OpenVDB::openvdb
if(NOT TARGET OpenVDB::openvdb)
set(OPENVDB_openvdb_LIB_TYPE UNKNOWN)
if(OPENVDB_USE_STATIC_LIBS)
set(OPENVDB_openvdb_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_OPENVDB_openvdb_EXT
${OpenVDB_openvdb_LIBRARY} EXT)
if(_OPENVDB_openvdb_EXT STREQUAL ".a")
set(OPENVDB_openvdb_LIB_TYPE STATIC)
elseif(_OPENVDB_openvdb_EXT STREQUAL ".so" OR
_OPENVDB_openvdb_EXT STREQUAL ".dylib")
set(OPENVDB_openvdb_LIB_TYPE SHARED)
endif()
endif()
add_library(OpenVDB::openvdb ${OPENVDB_openvdb_LIB_TYPE} IMPORTED)
set_target_properties(OpenVDB::openvdb PROPERTIES
IMPORTED_LOCATION "${OpenVDB_openvdb_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_OpenVDB_CFLAGS_OTHER}"
INTERFACE_COMPILE_DEFINITIONS "${OpenVDB_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}"
IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps
INTERFACE_LINK_LIBRARIES "${_OPENVDB_VISIBLE_DEPENDENCIES}" # visible deps (headers)
INTERFACE_COMPILE_FEATURES cxx_std_17
)
endif()
# OpenVDB::openvdb_je
if(OpenVDB_openvdb_je_LIBRARY)
if(NOT TARGET OpenVDB::openvdb_je)
add_library(OpenVDB::openvdb_je INTERFACE IMPORTED)
target_link_libraries(OpenVDB::openvdb_je INTERFACE OpenVDB::openvdb)
target_link_libraries(OpenVDB::openvdb_je INTERFACE Jemalloc::jemalloc)
endif()
endif()
# OpenVDB::pyopenvdb
if(OpenVDB_pyopenvdb_LIBRARY)
if(NOT TARGET OpenVDB::pyopenvdb)
add_library(OpenVDB::pyopenvdb MODULE IMPORTED)
set_target_properties(OpenVDB::pyopenvdb PROPERTIES
IMPORTED_LOCATION "${OpenVDB_pyopenvdb_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_pyopenvdb_INCLUDE_DIR};${PYTHON_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "OpenVDB::openvdb;${PYTHON_LIBRARIES}"
INTERFACE_COMPILE_FEATURES cxx_std_17
)
endif()
endif()
# OpenVDB::openvdb_houdini
if(OpenVDB_openvdb_houdini_LIBRARY)
if(NOT TARGET OpenVDB::openvdb_houdini)
add_library(OpenVDB::openvdb_houdini SHARED IMPORTED)
set_target_properties(OpenVDB::openvdb_houdini PROPERTIES
IMPORTED_LOCATION "${OpenVDB_openvdb_houdini_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_openvdb_houdini_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "OpenVDB::openvdb;Houdini"
INTERFACE_COMPILE_FEATURES cxx_std_17
)
endif()
endif()
# OpenVDB::openvdb_ax
if(OpenVDB_openvdb_ax_LIBRARY)
set(OPENVDB_openvdb_ax_LIB_TYPE UNKNOWN)
if(OPENVDB_USE_STATIC_LIBS)
set(OPENVDB_openvdb_ax_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_OPENVDB_openvdb_ax_EXT
${OpenVDB_openvdb_ax_LIBRARY} EXT)
if(_OPENVDB_openvdb_ax_EXT STREQUAL ".a")
set(OPENVDB_openvdb_ax_LIB_TYPE STATIC)
elseif(_OPENVDB_openvdb_ax_EXT STREQUAL ".so" OR
_OPENVDB_openvdb_ax_EXT STREQUAL ".dylib")
set(OPENVDB_openvdb_ax_LIB_TYPE SHARED)
endif()
endif()
if(NOT TARGET OpenVDB::openvdb_ax)
add_library(OpenVDB::openvdb_ax UNKNOWN IMPORTED)
set_target_properties(OpenVDB::openvdb_ax PROPERTIES
IMPORTED_LOCATION "${OpenVDB_openvdb_ax_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_openvdb_ax_INCLUDE_DIR}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "OpenVDB::openvdb;${LLVM_LIBS}"
INTERFACE_COMPILE_FEATURES cxx_std_17
)
endif()
endif()
# OpenVDB::nanovdb
if(OpenVDB_nanovdb_LIBRARY)
if(NOT TARGET OpenVDB::nanovdb)
add_library(OpenVDB::nanovdb INTERFACE IMPORTED)
set_target_properties(OpenVDB::nanovdb PROPERTIES
IMPORTED_LOCATION "${OpenVDB_nanovdb_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_nanovdb_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "OpenVDB::openvdb;"
INTERFACE_COMPILE_FEATURES cxx_std_17
)
endif()
endif()
unset(_OPENVDB_VISIBLE_DEPENDENCIES)
unset(_OPENVDB_HIDDEN_DEPENDENCIES)
-478
View File
@@ -1,478 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
FindTBB
-------
Find Tbb include dirs and libraries
Use this module by invoking find_package with the form::
find_package(TBB
[version] [EXACT] # Minimum or EXACT version
[REQUIRED] # Fail with error if Tbb is not found
[COMPONENTS <libs>...] # Tbb libraries by their canonical name
# e.g. "tbb" for "libtbb"
)
IMPORTED Targets
^^^^^^^^^^^^^^^^
``TBB::tbb``
The tbb library target.
``TBB::tbbmalloc``
The tbbmalloc library target.
``TBB::tbbmalloc_proxy``
The tbbmalloc_proxy library target.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Tbb_FOUND``
True if the system has the Tbb library.
``Tbb_VERSION`` ``TBB_VERSION``
The version of the Tbb library which was found.
``Tbb_INCLUDE_DIRS``
Include directories needed to use Tbb.
``Tbb_RELEASE_LIBRARIES``
Libraries needed to link to the release version of Tbb.
``Tbb_RELEASE_LIBRARY_DIRS``
Tbb release library directories.
``Tbb_DEBUG_LIBRARIES``
Libraries needed to link to the debug version of Tbb.
``Tbb_DEBUG_LIBRARY_DIRS``
Tbb debug library directories.
``TBB_{COMPONENT}_FOUND``
True if the system has the named TBB component.
Deprecated - use [RELEASE|DEBUG] variants:
``Tbb_LIBRARIES``
Libraries needed to link to Tbb.
``Tbb_LIBRARY_DIRS``
Tbb library directories.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Tbb_INCLUDE_DIR``
The directory containing ``tbb/tbb_stddef.h``.
``Tbb_{COMPONENT}_LIBRARY``
Individual component libraries for Tbb. may include target_link_libraries() debug/optimized keywords.
``Tbb_{COMPONENT}_LIBRARY_RELEASE``
Individual component libraries for Tbb release
``Tbb_{COMPONENT}_LIBRARY_DEBUG``
Individual debug component libraries for Tbb debug
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``TBB_ROOT``
Preferred installation prefix.
``TBB_INCLUDEDIR``
Preferred include directory e.g. <prefix>/include
``TBB_LIBRARYDIR``
Preferred library directory e.g. <prefix>/lib
``TBB_DEBUG_SUFFIX``
Suffix of the debug version of tbb. Defaults to "_debug".
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``TBB_USE_STATIC_LIBS``
Only search for static tbb libraries
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
include(GNUInstallDirs)
mark_as_advanced(
Tbb_INCLUDE_DIR
Tbb_LIBRARY
)
set(_FIND_TBB_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_TBB_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
set(_TBB_COMPONENT_LIST
tbb
tbbmalloc
tbbmalloc_proxy
)
if(TBB_FIND_COMPONENTS)
set(_TBB_COMPONENTS_PROVIDED TRUE)
set(_IGNORED_COMPONENTS "")
foreach(COMPONENT ${TBB_FIND_COMPONENTS})
if(NOT ${COMPONENT} IN_LIST _TBB_COMPONENT_LIST)
list(APPEND _IGNORED_COMPONENTS ${COMPONENT})
endif()
endforeach()
if(_IGNORED_COMPONENTS)
message(STATUS "Ignoring unknown components of TBB:")
foreach(COMPONENT ${_IGNORED_COMPONENTS})
message(STATUS " ${COMPONENT}")
endforeach()
list(REMOVE_ITEM TBB_FIND_COMPONENTS ${_IGNORED_COMPONENTS})
endif()
else()
set(_TBB_COMPONENTS_PROVIDED FALSE)
set(TBB_FIND_COMPONENTS ${_TBB_COMPONENT_LIST})
endif()
if(TBB_ROOT)
set(_TBB_ROOT ${TBB_ROOT})
elseif(DEFINED ENV{TBB_ROOT})
set(_TBB_ROOT $ENV{TBB_ROOT})
endif()
# Additionally try and use pkconfig to find Tbb
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_Tbb QUIET tbb)
endif()
endif()
# ------------------------------------------------------------------------
# Search for tbb include DIR
# ------------------------------------------------------------------------
set(_TBB_INCLUDE_SEARCH_DIRS "")
list(APPEND _TBB_INCLUDE_SEARCH_DIRS
${TBB_INCLUDEDIR}
${_TBB_ROOT}
${PC_Tbb_INCLUDE_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
if(NOT Tbb_INCLUDE_DIR)
# Look for a legacy tbb header file.
find_path(Tbb_LEGACY_INCLUDE_DIR tbb/tbb_stddef.h
${_FIND_TBB_ADDITIONAL_OPTIONS}
PATHS ${_TBB_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
)
else()
set(Tbb_LEGACY_INCLUDE_DIR ${Tbb_INCLUDE_DIR})
endif()
# Look for a new tbb header installation
# From TBB 2021, tbb_stddef is removed and the directory include/tbb is
# simply an alias for include/oneapi/tbb. Try and find the version header
# in oneapi/tbb
find_path(Tbb_INCLUDE_DIR oneapi/tbb/version.h
${_FIND_TBB_ADDITIONAL_OPTIONS}
PATHS ${_TBB_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
)
set(_tbb_legacy_version_file "${Tbb_LEGACY_INCLUDE_DIR}/tbb/tbb_stddef.h")
set(_tbb_version_file "${Tbb_INCLUDE_DIR}/oneapi/tbb/version.h")
if(EXISTS ${_tbb_legacy_version_file})
if(EXISTS ${_tbb_version_file})
message(WARNING "
FindTBB located both an old and new tbb installation.
old: ${_tbb_legacy_version_file}
new: ${_tbb_version_file}
The NEWER versioned installation will be used. You can set TBB_INCLUDEDIR
to control FindTBB.cmake search, or explicitly set Tbb_INCLUDE_DIR to the
desired location.
")
else()
set(_tbb_version_file "${_tbb_legacy_version_file}")
set(Tbb_INCLUDE_DIR ${Tbb_LEGACY_INCLUDE_DIR} CACHE STRING "" FORCE)
endif()
endif()
if(EXISTS ${_tbb_version_file})
file(STRINGS ${_tbb_version_file} _tbb_version_major_string REGEX "#define TBB_VERSION_MAJOR " )
string(REGEX REPLACE "#define TBB_VERSION_MAJOR" "" _tbb_version_major_string "${_tbb_version_major_string}")
string(STRIP "${_tbb_version_major_string}" Tbb_VERSION_MAJOR)
file(STRINGS ${_tbb_version_file} _tbb_version_minor_string REGEX "#define TBB_VERSION_MINOR ")
string(REGEX REPLACE "#define TBB_VERSION_MINOR" "" _tbb_version_minor_string "${_tbb_version_minor_string}")
string(STRIP "${_tbb_version_minor_string}" Tbb_VERSION_MINOR)
file(STRINGS ${_tbb_version_file} _tbb_binary_version_string REGEX "#define __TBB_BINARY_VERSION ")
string(REGEX REPLACE "#define __TBB_BINARY_VERSION" "" _tbb_binary_version_string "${_tbb_binary_version_string}")
string(STRIP "${_tbb_binary_version_string}" Tbb_BINARY_VERSION)
unset(_tbb_version_major_string)
unset(_tbb_version_minor_string)
unset(_tbb_binary_version_string)
# Set both for compatibility reasons, TBB's CONFIG files only set the latter
set(Tbb_VERSION ${Tbb_VERSION_MAJOR}.${Tbb_VERSION_MINOR})
set(TBB_VERSION ${Tbb_VERSION})
endif()
unset(_tbb_version_file)
unset(_tbb_legacy_version_file)
unset(Tbb_LEGACY_INCLUDE_DIR)
# ------------------------------------------------------------------------
# Search for TBB lib DIR
# ------------------------------------------------------------------------
set(_TBB_LIBRARYDIR_SEARCH_DIRS "")
# Append to _TBB_LIBRARYDIR_SEARCH_DIRS in priority order
set(_TBB_LIBRARYDIR_SEARCH_DIRS "")
list(APPEND _TBB_LIBRARYDIR_SEARCH_DIRS
${TBB_LIBRARYDIR}
${_TBB_ROOT}
${PC_Tbb_LIBRARY_DIRS}
${SYSTEM_LIBRARY_PATHS}
)
# Library suffix handling
if(NOT DEFINED TBB_DEBUG_SUFFIX)
set(TBB_DEBUG_SUFFIX _debug)
endif()
set(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(MSVC)
if(TBB_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
endif()
else()
if(TBB_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
endif()
set(Tbb_LIB_COMPONENTS "")
list(APPEND TBB_BUILD_TYPES RELEASE DEBUG)
foreach(COMPONENT ${TBB_FIND_COMPONENTS})
foreach(BUILD_TYPE ${TBB_BUILD_TYPES})
set(_TBB_LIB_NAME ${COMPONENT})
if(BUILD_TYPE STREQUAL DEBUG)
set(_TBB_LIB_NAME "${_TBB_LIB_NAME}${TBB_DEBUG_SUFFIX}")
endif()
find_library(Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} ${_TBB_LIB_NAME}
${_FIND_TBB_ADDITIONAL_OPTIONS}
PATHS ${_TBB_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib)
# If we didn't find the library, prepend Tbb_BINARY_VERSION to each possible
# component name and try again. As of TBB 2021, TBB decides to version some
# of its libraries on some of its platforms...
if(NOT Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} AND Tbb_BINARY_VERSION)
set(_TBB_LIB_NAME "${COMPONENT}${Tbb_BINARY_VERSION}")
if(BUILD_TYPE STREQUAL DEBUG)
set(_TBB_LIB_NAME "${_TBB_LIB_NAME}${TBB_DEBUG_SUFFIX}")
endif()
find_library(Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} ${_TBB_LIB_NAME}
${_FIND_TBB_ADDITIONAL_OPTIONS}
PATHS ${_TBB_LIBRARYDIR_SEARCH_DIRS}
PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib)
endif()
# On Unix, TBB sometimes uses linker scripts instead of symlinks, so parse the linker script
# and correct the library name if so
if(UNIX AND EXISTS ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
# Ignore files where the first four bytes equals the ELF magic number
file(READ ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}} Tbb_${COMPONENT}_HEX OFFSET 0 LIMIT 4 HEX)
if(NOT ${Tbb_${COMPONENT}_HEX} STREQUAL "7f454c46")
# Read the first 1024 bytes of the library and match against an "INPUT (file)" regex
file(READ ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}} Tbb_${COMPONENT}_ASCII OFFSET 0 LIMIT 1024)
if("${Tbb_${COMPONENT}_ASCII}" MATCHES "INPUT \\(([^(]+)\\)")
# Extract the directory and apply the matched text (in brackets)
get_filename_component(Tbb_${COMPONENT}_DIR "${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}}" DIRECTORY)
set(Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} "${Tbb_${COMPONENT}_DIR}/${CMAKE_MATCH_1}")
endif()
endif()
endif()
if(EXISTS ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
list(APPEND Tbb_LIB_COMPONENTS ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
list(APPEND Tbb_LIB_COMPONENTS_${BUILD_TYPE} ${Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE}})
endif()
endforeach()
if(Tbb_${COMPONENT}_LIBRARY_DEBUG AND Tbb_${COMPONENT}_LIBRARY_RELEASE)
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
set(Tbb_${COMPONENT}_LIBRARY optimized ${Tbb_${COMPONENT}_LIBRARY_RELEASE} debug ${Tbb_${COMPONENT}_LIBRARY_DEBUG})
else()
# For single-config generators where CMAKE_BUILD_TYPE has no value,
# just use the release libraries
set(Tbb_${COMPONENT}_LIBRARY ${Tbb_${COMPONENT}_LIBRARY_RELEASE})
endif()
# FIXME: This probably should be set for both cases
set(Tbb_${COMPONENT}_LIBRARIES optimized ${Tbb_${COMPONENT}_LIBRARY_RELEASE} debug ${Tbb_${COMPONENT}_LIBRARY_DEBUG})
endif()
# if only the release version was found, set the debug variable also to the release version
if(Tbb_${COMPONENT}_LIBRARY_RELEASE AND NOT Tbb_${COMPONENT}_LIBRARY_DEBUG)
set(Tbb_${COMPONENT}_LIBRARY_DEBUG ${Tbb_${COMPONENT}_LIBRARY_RELEASE})
set(Tbb_${COMPONENT}_LIBRARY ${Tbb_${COMPONENT}_LIBRARY_RELEASE})
set(Tbb_${COMPONENT}_LIBRARIES ${Tbb_${COMPONENT}_LIBRARY_RELEASE})
endif()
# if only the debug version was found, set the release variable also to the debug version
if(Tbb_${COMPONENT}_LIBRARY_DEBUG AND NOT Tbb_${COMPONENT}_LIBRARY_RELEASE)
set(Tbb_${COMPONENT}_LIBRARY_RELEASE ${Tbb_${COMPONENT}_LIBRARY_DEBUG})
set(Tbb_${COMPONENT}_LIBRARY ${Tbb_${COMPONENT}_LIBRARY_DEBUG})
set(Tbb_${COMPONENT}_LIBRARIES ${Tbb_${COMPONENT}_LIBRARY_DEBUG})
endif()
# If the debug & release library ends up being the same, omit the keywords
if("${Tbb_${COMPONENT}_LIBRARY_RELEASE}" STREQUAL "${Tbb_${COMPONENT}_LIBRARY_DEBUG}")
set(Tbb_${COMPONENT}_LIBRARY ${Tbb_${COMPONENT}_LIBRARY_RELEASE} )
set(Tbb_${COMPONENT}_LIBRARIES ${Tbb_${COMPONENT}_LIBRARY_RELEASE} )
endif()
if(Tbb_${COMPONENT}_LIBRARY)
set(TBB_${COMPONENT}_FOUND TRUE)
else()
set(TBB_${COMPONENT}_FOUND FALSE)
endif()
endforeach()
# Reset library suffix
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
# ------------------------------------------------------------------------
# Cache and set TBB_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TBB
FOUND_VAR TBB_FOUND
REQUIRED_VARS
Tbb_INCLUDE_DIR
Tbb_LIB_COMPONENTS
VERSION_VAR Tbb_VERSION
HANDLE_COMPONENTS
)
if(NOT TBB_FOUND)
if(TBB_FIND_REQUIRED)
message(FATAL_ERROR "Unable to find TBB")
endif()
return()
endif()
# Partition release/debug lib vars
set(Tbb_RELEASE_LIBRARIES "")
set(Tbb_RELEASE_LIBRARY_DIRS "")
set(Tbb_DEBUG_LIBRARIES "")
set(Tbb_DEBUG_LIBRARY_DIRS "")
foreach(LIB ${Tbb_LIB_COMPONENTS_RELEASE})
get_filename_component(_TBB_LIBDIR ${LIB} DIRECTORY)
list(APPEND Tbb_RELEASE_LIBRARIES ${LIB})
list(APPEND Tbb_RELEASE_LIBRARY_DIRS ${_TBB_LIBDIR})
endforeach()
foreach(LIB ${Tbb_LIB_COMPONENTS_DEBUG})
get_filename_component(_TBB_LIBDIR ${LIB} DIRECTORY)
list(APPEND Tbb_DEBUG_LIBRARIES ${LIB})
list(APPEND Tbb_DEBUG_LIBRARY_DIRS ${_TBB_LIBDIR})
endforeach()
list(REMOVE_DUPLICATES Tbb_RELEASE_LIBRARY_DIRS)
list(REMOVE_DUPLICATES Tbb_DEBUG_LIBRARY_DIRS)
set(Tbb_LIBRARIES ${Tbb_RELEASE_LIBRARIES})
set(Tbb_LIBRARY_DIRS ${Tbb_RELEASE_LIBRARY_DIRS})
set(Tbb_INCLUDE_DIRS ${Tbb_INCLUDE_DIR})
# Configure imported targets
foreach(COMPONENT ${TBB_FIND_COMPONENTS})
# Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static
# lib is in use. If win32, we can't mark the import .libs as shared, so
# these are always marked as UNKNOWN. Otherwise, infer from extension.
set(TBB_${COMPONENT}_LIB_TYPE UNKNOWN)
if(TBB_USE_STATIC_LIBS)
set(TBB_${COMPONENT}_LIB_TYPE STATIC)
elseif(UNIX)
get_filename_component(_TBB_${COMPONENT}_EXT ${Tbb_${COMPONENT}_LIBRARY_RELEASE} EXT)
if(_TBB_${COMPONENT}_EXT STREQUAL ".a")
set(TBB_${COMPONENT}_LIB_TYPE STATIC)
elseif(_TBB_${COMPONENT}_EXT STREQUAL ".so" OR
_TBB_${COMPONENT}_EXT STREQUAL ".dylib")
set(TBB_${COMPONENT}_LIB_TYPE SHARED)
endif()
endif()
set(Tbb_${COMPONENT}_DEFINITIONS)
# Add the TBB linking defines if the library is static on WIN32
if(WIN32)
if(${COMPONENT} STREQUAL tbb)
if(Tbb_${COMPONENT}_LIB_TYPE STREQUAL STATIC)
list(APPEND Tbb_${COMPONENT}_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE=1)
endif()
else() # tbbmalloc
if(Tbb_${COMPONENT}_LIB_TYPE STREQUAL STATIC)
list(APPEND Tbb_${COMPONENT}_DEFINITIONS __TBB_MALLOC_NO_IMPLICIT_LINKAGE=1)
endif()
endif()
endif()
if(NOT TARGET TBB::${COMPONENT})
add_library(TBB::${COMPONENT} ${TBB_${COMPONENT}_LIB_TYPE} IMPORTED)
set_target_properties(TBB::${COMPONENT} PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_Tbb_CFLAGS_OTHER}"
INTERFACE_COMPILE_DEFINITIONS "${Tbb_${COMPONENT}_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Tbb_INCLUDE_DIR}"
INTERFACE_LINK_DIRECTORIES "${Tbb_LIBRARY_DIRS}")
# Standard location
set_target_properties(TBB::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${Tbb_${COMPONENT}_LIBRARY}")
# Release location
if(EXISTS "${Tbb_${COMPONENT}_LIBRARY_RELEASE}")
set_property(TARGET TBB::${COMPONENT} APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(TBB::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${Tbb_${COMPONENT}_LIBRARY_RELEASE}"
MAP_IMPORTED_CONFIG_MINSIZEREL Release
MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release)
endif()
# Debug location
if(EXISTS "${Tbb_${COMPONENT}_LIBRARY_DEBUG}")
set_property(TARGET TBB::${COMPONENT} APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(TBB::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "${Tbb_${COMPONENT}_LIBRARY_DEBUG}")
endif()
endif()
endforeach()
-142
View File
@@ -1,142 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
OpenVDBGLFW3Setup
-----------------
Wraps the call the FindPackage ( glfw3 ) for OpenVDB builds. Provides
some extra options for finding the glfw3 installation without polluting
the OpenVDB Binaries cmake.
Use this module by invoking include with the form::
include ( OpenVDBGLFW3Setup )
IMPORTED Targets
^^^^^^^^^^^^^^^^
``glfw``
The glfw3 library target.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``glfw3_FOUND``
True if the system has glfw3 installed.
``glfw3_VERSION``
The version of the glfw3 library which was found.
Hints
^^^^^
The following variables may be provided to tell this module where to look.
``GLFW3_ROOT``
Preferred installation prefix.
``SYSTEM_LIBRARY_PATHS``
Global list of library paths intended to be searched by and find_xxx call
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
# Find the glfw3 installation and use glfw's CMake to initialize
# the glfw lib
cmake_minimum_required(VERSION 3.20)
set(_FIND_GLFW3_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_GLFW3_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
set(_GLFW3_ROOT_SEARCH_DIR "")
if(GLFW3_ROOT)
list(APPEND _GLFW3_ROOT_SEARCH_DIR ${GLFW3_ROOT})
else()
set(_ENV_GLFW_ROOT $ENV{GLFW3_ROOT})
if(_ENV_GLFW_ROOT)
list(APPEND _GLFW3_ROOT_SEARCH_DIR ${_ENV_GLFW_ROOT})
endif()
endif()
# Additionally try and use pkconfig to find glfw, though we only use
# pkg-config to re-direct to the cmake. In other words, glfw's cmake is
# expected to be installed
if(USE_PKGCONFIG)
if(NOT DEFINED PKG_CONFIG_FOUND)
find_package(PkgConfig)
endif()
pkg_check_modules(PC_glfw3 QUIET glfw3)
endif()
if(PC_glfw3_FOUND)
foreach(DIR ${PC_glfw3_LIBRARY_DIRS})
list(APPEND _GLFW3_ROOT_SEARCH_DIR ${DIR})
endforeach()
endif()
list(APPEND _GLFW3_ROOT_SEARCH_DIR ${SYSTEM_LIBRARY_PATHS})
set(_GLFW3_PATH_SUFFIXES "lib/cmake/glfw3" "cmake/glfw3" "glfw3")
# GLFW 3.1 installs CMake modules into glfw instead of glfw3
list(APPEND _GLFW3_PATH_SUFFIXES "lib/cmake/glfw" "cmake/glfw" "glfw")
find_path(GLFW3_CMAKE_LOCATION glfw3Config.cmake
${_FIND_GLFW3_ADDITIONAL_OPTIONS}
PATHS ${_GLFW3_ROOT_SEARCH_DIR}
PATH_SUFFIXES ${_GLFW3_PATH_SUFFIXES}
)
if(GLFW3_CMAKE_LOCATION)
if(EXISTS "${GLFW3_CMAKE_LOCATION}/glfw3Targets.cmake")
include("${GLFW3_CMAKE_LOCATION}/glfw3Targets.cmake")
elseif(EXISTS "${GLFW3_CMAKE_LOCATION}/glfwTargets.cmake")
include("${GLFW3_CMAKE_LOCATION}/glfwTargets.cmake")
endif()
endif()
if(GLFW3_CMAKE_LOCATION)
list(APPEND CMAKE_PREFIX_PATH "${GLFW3_CMAKE_LOCATION}")
endif()
set(glfw3_FIND_VERSION ${MINIMUM_GLFW_VERSION})
find_package(glfw3 ${MINIMUM_GLFW_VERSION} REQUIRED)
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_GLFW_VERSION)
if(glfw3_VERSION VERSION_LESS ${FUTURE_MINIMUM_GLFW_VERSION})
message(DEPRECATION "Support for GLFW versions < ${FUTURE_MINIMUM_GLFW_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
unset(glfw3_FIND_VERSION)
# GLFW 3.1 does not export INTERFACE_LINK_LIBRARIES so detect this
# version and set the property ourselves
# @todo investigate how this might apply for Mac OSX
if(UNIX)
if(glfw3_VERSION VERSION_LESS 3.2)
message(WARNING "GLFW 3.1 does not set the INTERFACE_LINK_LIBRARIES property, "
"hard-coding to expect a dependency on X11. To use a different "
"library dependency, consider upgrading to GLFW 3.2+ where this "
"property is set by the CMake find package module for GLFW.")
find_package(X11 REQUIRED)
set_property(TARGET glfw
PROPERTY INTERFACE_LINK_LIBRARIES
${X11_Xrandr_LIB}
${X11_Xxf86vm_LIB}
${X11_Xcursor_LIB}
${X11_Xinerama_LIB}
${X11_Xi_LIB}
${X11_LIBRARIES}
${CMAKE_DL_LIBS}
)
endif()
endif()
-405
View File
@@ -1,405 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
OpenVDBHoudiniSetup
-------------------
Wraps the call the FindPackage ( Houdini ) for OpenVDB builds. This
ensures that all dependencies that are included with a Houdini
distribution are configured to load from that installation.
This CMake searches for the HoudiniConfig.cmake module provided by
SideFX to configure the OpenVDB Houdini base and DSO libraries. Users
can provide paths to the location of their Houdini Installation by
setting HOUDINI_ROOT either as an environment variable or by passing it
to CMake. This module also reads the value of $HFS, usually set by
sourcing the Houdini Environment. Note that as long as you provide a
path to your Houdini Installation you do not need to source the
Houdini Environment.
Use this module by invoking include with the form::
include ( OpenVDBHoudiniSetup )
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Houdini_FOUND``
True if the system has Houdini installed.
``Houdini_VERSION``
The version of the Houdini which was found.
``OPENVDB_HOUDINI_ABI``
The ABI version that Houdini uses for it's own OpenVDB installation.
``HOUDINI_INCLUDE_DIR``
The Houdini include directory.
``HOUDINI_LIB_DIR``
The Houdini lib directory.
A variety of variables will also be set from HoudiniConfig.cmake.
Additionally, the following values are set for all dependent OpenVDB
builds, ensuring they link against the correct libraries. This may
overwrite user provided values.
``ZLIB_ROOT``
``ZLIB_LIBRARY``
``OPENEXR_INCLUDEDIR``
``OPENEXR_LIBRARYDIR``
``TBB_INCLUDEDIR``
``TBB_LIBRARYDIR``
``BLOSC_INCLUDEDIR``
``BLOSC_LIBRARYDIR``
``JEMALLOC_LIBRARYDIR``
Hints
^^^^^
Instead of explicitly setting the cache variables, the following variables
may be provided to tell this module where to look.
``ENV{HFS}``
Preferred installation prefix.
``Houdini_ROOT``
Preferred installation prefix.
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
# Find the Houdini installation and use Houdini's CMake to initialize
# the Houdini lib
cmake_minimum_required(VERSION 3.20)
# Include utility functions for version information
include(${CMAKE_CURRENT_LIST_DIR}/OpenVDBUtils.cmake)
set(_FIND_HOUDINI_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_HOUDINI_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _HOUDINI_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV HOUDINI_ROOT from CMake 3.12
if(Houdini_ROOT)
set(_HOUDINI_ROOT ${Houdini_ROOT})
elseif(DEFINED ENV{Houdini_ROOT})
set(_HOUDINI_ROOT $ENV{Houdini_ROOT})
elseif(HOUDINI_ROOT)
set(_HOUDINI_ROOT ${HOUDINI_ROOT})
elseif(DEFINED ENV{HOUDINI_ROOT})
set(_HOUDINI_ROOT $ENV{HOUDINI_ROOT})
endif()
set(_HOUDINI_ROOT_SEARCH_DIR)
if(_HOUDINI_ROOT)
list(APPEND _HOUDINI_ROOT_SEARCH_DIR ${_HOUDINI_ROOT})
endif()
if(DEFINED ENV{HFS})
list(APPEND _HOUDINI_ROOT_SEARCH_DIR $ENV{HFS})
endif()
# ------------------------------------------------------------------------
# Search for Houdini
# ------------------------------------------------------------------------
set(_HOUDINI_CMAKE_PATH_SUFFIXES)
if(APPLE)
list(APPEND _HOUDINI_CMAKE_PATH_SUFFIXES
Frameworks/Houdini.framework/Versions/Current/Resources/toolkit/cmake
Houdini.framework/Versions/Current/Resources/toolkit/cmake
Versions/Current/Resources/toolkit/cmake
Current/Resources/toolkit/cmake
Resources/toolkit/cmake
)
endif()
list(APPEND _HOUDINI_CMAKE_PATH_SUFFIXES
toolkit/cmake
cmake
)
find_package(Houdini
${_FIND_HOUDINI_ADDITIONAL_OPTIONS}
PATHS ${_HOUDINI_ROOT_SEARCH_DIR}
PATH_SUFFIXES ${_HOUDINI_CMAKE_PATH_SUFFIXES}
REQUIRED)
# Note that passing MINIMUM_HOUDINI_VERSION into find_package(Houdini) doesn't work
if(NOT Houdini_FOUND)
message(FATAL_ERROR "Unable to locate Houdini Installation.")
elseif(MINIMUM_HOUDINI_VERSION)
if(Houdini_VERSION VERSION_LESS MINIMUM_HOUDINI_VERSION)
message(FATAL_ERROR "Unsupported Houdini Version ${Houdini_VERSION}. Minimum "
"supported is ${MINIMUM_HOUDINI_VERSION}."
)
endif()
endif()
set(Houdini_VERSION_MAJOR_MINOR "${Houdini_VERSION_MAJOR}.${Houdini_VERSION_MINOR}")
find_package(PackageHandleStandardArgs)
find_package_handle_standard_args(Houdini
REQUIRED_VARS _houdini_install_root Houdini_FOUND
VERSION_VAR Houdini_VERSION
)
# ------------------------------------------------------------------------
# Add support for older versions of Houdini
# ------------------------------------------------------------------------
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_HOUDINI_VERSION)
if(Houdini_VERSION VERSION_LESS ${FUTURE_MINIMUM_HOUDINI_VERSION})
message(DEPRECATION "Support for Houdini versions < ${FUTURE_MINIMUM_HOUDINI_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
# ------------------------------------------------------------------------
# Configure imported Houdini target
# ------------------------------------------------------------------------
# Set the relative directory containing Houdini libs and populate an extra list
# of Houdini dependencies for _houdini_create_libraries.
if(NOT HOUDINI_DSOLIB_DIR)
if(APPLE)
set(HOUDINI_DSOLIB_DIR Frameworks/Houdini.framework/Versions/Current/Libraries)
elseif(UNIX)
set(HOUDINI_DSOLIB_DIR dsolib)
elseif(WIN32)
set(HOUDINI_DSOLIB_DIR custom/houdini/dsolib)
endif()
endif()
set(_HOUDINI_EXTRA_LIBRARIES)
set(_HOUDINI_EXTRA_LIBRARY_NAMES)
if(APPLE)
list(APPEND _HOUDINI_EXTRA_LIBRARIES
${HOUDINI_DSOLIB_DIR}/libHoudiniRAY.dylib
${HOUDINI_DSOLIB_DIR}/libhboost_regex.dylib
${HOUDINI_DSOLIB_DIR}/libhboost_thread.dylib
)
list(APPEND _HOUDINI_EXTRA_LIBRARY_NAMES
HoudiniRAY
hboost_regex
hboost_thread
)
elseif(UNIX)
list(APPEND _HOUDINI_EXTRA_LIBRARIES
${HOUDINI_DSOLIB_DIR}/libHoudiniRAY.so
${HOUDINI_DSOLIB_DIR}/libhboost_regex.so
${HOUDINI_DSOLIB_DIR}/libhboost_thread.so
)
list(APPEND _HOUDINI_EXTRA_LIBRARY_NAMES
HoudiniRAY
hboost_regex
hboost_thread
)
elseif(WIN32)
#libRAY is already included by houdini for windows builds
if(Houdini_VERSION VERSION_LESS 18.5)
list(APPEND _HOUDINI_EXTRA_LIBRARIES
${HOUDINI_DSOLIB_DIR}/hboost_regex-mt.lib
${HOUDINI_DSOLIB_DIR}/hboost_thread-mt.lib
)
else()
list(APPEND _HOUDINI_EXTRA_LIBRARIES
${HOUDINI_DSOLIB_DIR}/hboost_regex-mt-x64.lib
${HOUDINI_DSOLIB_DIR}/hboost_thread-mt-x64.lib
)
endif()
list(APPEND _HOUDINI_EXTRA_LIBRARY_NAMES
hboost_regex
hboost_thread
)
endif()
# Additionally link extra deps
_houdini_create_libraries(
PATHS ${_HOUDINI_EXTRA_LIBRARIES}
TARGET_NAMES ${_HOUDINI_EXTRA_LIBRARY_NAMES}
TYPE SHARED
)
unset(_HOUDINI_EXTRA_LIBRARIES)
unset(_HOUDINI_EXTRA_LIBRARY_NAMES)
# Set Houdini lib and include directories
set(HOUDINI_INCLUDE_DIR ${_houdini_include_dir})
set(HOUDINI_LIB_DIR ${_houdini_install_root}/${HOUDINI_DSOLIB_DIR})
# ------------------------------------------------------------------------
# Configure dependencies
# ------------------------------------------------------------------------
# Congfigure dependency hints to point to Houdini. Allow for user overriding
# if custom Houdini installations are in use
# ZLIB - FindPackage ( ZLIB) only supports a few path hints. We use
# ZLIB_ROOT to find the zlib includes and explicitly set the path to
# the zlib library
if(NOT ZLIB_ROOT)
set(ZLIB_ROOT ${HOUDINI_INCLUDE_DIR})
endif()
if(NOT ZLIB_LIBRARY)
# Full path to zlib library - FindPackage ( ZLIB)
find_library(ZLIB_LIBRARY z
${_FIND_HOUDINI_ADDITIONAL_OPTIONS}
PATHS ${HOUDINI_LIB_DIR}
)
if(NOT EXISTS ${ZLIB_LIBRARY})
message(WARNING "The OpenVDB Houdini CMake setup is unable to locate libz within "
"the Houdini installation at: ${HOUDINI_LIB_DIR}. OpenVDB may not build correctly."
)
endif()
endif()
# TBB
if(NOT TBB_INCLUDEDIR)
set(TBB_INCLUDEDIR ${HOUDINI_INCLUDE_DIR})
endif()
if(NOT TBB_LIBRARYDIR)
set(TBB_LIBRARYDIR ${HOUDINI_LIB_DIR})
endif()
# Blosc
if(NOT BLOSC_INCLUDEDIR)
set(BLOSC_INCLUDEDIR ${HOUDINI_INCLUDE_DIR})
endif()
if(NOT BLOSC_LIBRARYDIR)
set(BLOSC_LIBRARYDIR ${HOUDINI_LIB_DIR})
endif()
# Jemalloc
# * On Mac OSX, linking against Jemalloc < 4.3.0 seg-faults with this error:
# malloc: *** malloc_zone_unregister() failed for 0xaddress
# As of Houdini 20, it still ships with Jemalloc 3.6.0, so don't expose it
# on Mac OSX (https://github.com/jemalloc/jemalloc/issues/420).
if(NOT APPLE AND NOT JEMALLOC_LIBRARYDIR)
set(JEMALLOC_LIBRARYDIR ${HOUDINI_LIB_DIR})
endif()
# OpenEXR
if(NOT OPENEXR_INCLUDEDIR)
set(OPENEXR_INCLUDEDIR ${HOUDINI_INCLUDE_DIR})
endif()
if(NOT OPENEXR_LIBRARYDIR)
set(OPENEXR_LIBRARYDIR ${HOUDINI_LIB_DIR})
endif()
# Boost - currently must be provided as VDB is not fully configured to
# use Houdini's namespaced hboost
# Add the required suffix as part of the cmake lib suffix searches
if(APPLE)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_sidefx.dylib")
elseif(UNIX)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_sidefx.so")
elseif(WIN32)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_sidefx.lib")
endif()
# ------------------------------------------------------------------------
# Configure OpenVDB ABI
# ------------------------------------------------------------------------
# Explicitly configure the OpenVDB ABI version depending on the Houdini
# version.
find_file(_houdini_openvdb_version_file "openvdb/version.h"
PATHS ${HOUDINI_INCLUDE_DIR}
NO_DEFAULT_PATH)
if(_houdini_openvdb_version_file)
OPENVDB_VERSION_FROM_HEADER("${_houdini_openvdb_version_file}"
ABI OPENVDB_HOUDINI_ABI)
endif()
unset(_houdini_openvdb_version_file)
if(NOT OPENVDB_HOUDINI_ABI)
message(WARNING "Unknown version of Houdini, assuming OpenVDB ABI=${OpenVDB_MAJOR_VERSION}, "
"but if this not correct, the CMake flag -DOPENVDB_HOUDINI_ABI=<N> can override this value.")
set(OPENVDB_HOUDINI_ABI ${OpenVDB_MAJOR_VERSION})
endif()
# ------------------------------------------------------------------------
# Configure libstc++ CXX11 ABI
# ------------------------------------------------------------------------
if(UNIX AND NOT APPLE)
# Assume we're using libstdc++
message(STATUS "Configuring CXX11 ABI for Houdini compatibility...")
execute_process(COMMAND echo "#include <string>"
COMMAND ${CMAKE_CXX_COMPILER} "-x" "c++" "-E" "-dM" "-"
COMMAND grep "-F" "_GLIBCXX_USE_CXX11_ABI"
TIMEOUT 10
RESULT_VARIABLE QUERIED_GCC_CXX11_ABI_SUCCESS
OUTPUT_VARIABLE _GCC_CXX11_ABI)
set(GLIBCXX_USE_CXX11_ABI "UNKNOWN")
if(NOT QUERIED_GCC_CXX11_ABI_SUCCESS)
string(FIND ${_GCC_CXX11_ABI} "_GLIBCXX_USE_CXX11_ABI 0" GCC_OLD_CXX11_ABI)
string(FIND ${_GCC_CXX11_ABI} "_GLIBCXX_USE_CXX11_ABI 1" GCC_NEW_CXX11_ABI)
if(NOT (${GCC_OLD_CXX11_ABI} EQUAL -1))
set(GLIBCXX_USE_CXX11_ABI 0)
endif()
if(NOT (${GCC_NEW_CXX11_ABI} EQUAL -1))
set(GLIBCXX_USE_CXX11_ABI 1)
endif()
endif()
# Try and query the Houdini CXX11 ABI. Allow it to be provided by users to
# override this logic should Houdini's CMake ever change
if(NOT DEFINED HOUDINI_CXX11_ABI)
get_target_property(houdini_interface_compile_options
Houdini INTERFACE_COMPILE_OPTIONS)
set(HOUDINI_CXX11_ABI "UNKNOWN")
if("-D_GLIBCXX_USE_CXX11_ABI=0" IN_LIST houdini_interface_compile_options)
set(HOUDINI_CXX11_ABI 0)
elseif("-D_GLIBCXX_USE_CXX11_ABI=1" IN_LIST houdini_interface_compile_options)
set(HOUDINI_CXX11_ABI 1)
endif()
endif()
message(STATUS " GNU CXX11 ABI : ${GLIBCXX_USE_CXX11_ABI}")
message(STATUS " Houdini CXX11 ABI : ${HOUDINI_CXX11_ABI}")
if(${HOUDINI_CXX11_ABI} STREQUAL "UNKNOWN")
message(WARNING "Unable to determine Houdini CXX11 ABI. Assuming newer ABI "
"has been used.")
set(HOUDINI_CXX11_ABI 1)
endif()
if(${GLIBCXX_USE_CXX11_ABI} EQUAL ${HOUDINI_CXX11_ABI})
message(STATUS " Current CXX11 ABI matches Houdini configuration "
"(_GLIBCXX_USE_CXX11_ABI=${HOUDINI_CXX11_ABI}).")
else()
message(WARNING "A potential mismatch was detected between the CXX11 ABI "
"of libstdc++ and Houdini. The following ABI configuration will be used: "
"-D_GLIBCXX_USE_CXX11_ABI=${HOUDINI_CXX11_ABI}. See: "
"https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html and "
"https://vfxplatform.com/#footnote-gcc6 for more information.")
endif()
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=${HOUDINI_CXX11_ABI})
endif()
-253
View File
@@ -1,253 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
OpenVDBMayaSetup
-------------------
Finds the Maya installation and sets up dependencies for OpenVDB builds.
This ensures that all dependencies that are included with a Maya
distribution are configured to load from that installation.
Use this module by invoking include with the form::
include ( OpenVDBMayaSetup )
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Maya_FOUND``
True if the system has Maya installed.
``Maya_VERSION``
The version of the Maya which was found.
Additionally, the following values are set for all dependent OpenVDB
builds, ensuring they link against the correct libraries. This may
overwrite user provided values.
``TBB_INCLUDEDIR``
``TBB_LIBRARYDIR``
Hints
^^^^^
Instead of explicitly setting the cache variables, the following
variables may be provided to tell this module where to look.
``Maya_ROOT``
Preferred installation prefix.
``ENV{Maya_ROOT}``
Preferred installation prefix.
``ENV{MAYA_LOCATION}``
Preferred installation prefix.
``DISABLE_CMAKE_SEARCH_PATHS``
Disable CMakes default search paths for find_xxx calls in this module
#]=======================================================================]
# Find the Maya installation and use Maya's CMake to initialize
# the Maya lib
cmake_minimum_required(VERSION 3.20)
set(_FIND_MAYA_ADDITIONAL_OPTIONS "")
if(DISABLE_CMAKE_SEARCH_PATHS)
set(_FIND_MAYA_ADDITIONAL_OPTIONS NO_DEFAULT_PATH)
endif()
# Set _MAYA_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT}
# are prioritised over the legacy capitalized XXX_ROOT variables for matching
# CMake 3.12 behaviour
# @todo deprecate -D and ENV MAYA_ROOT from CMake 3.12
if(Maya_ROOT)
set(_MAYA_ROOT ${Maya_ROOT})
elseif(DEFINED ENV{Maya_ROOT})
set(_MAYA_ROOT $ENV{Maya_ROOT})
elseif(MAYA_ROOT)
set(_MAYA_ROOT ${MAYA_ROOT})
elseif(DEFINED ENV{MAYA_ROOT})
set(_MAYA_ROOT $ENV{MAYA_ROOT})
endif()
set(_MAYA_ROOT_SEARCH_DIR)
if(_MAYA_ROOT)
list(APPEND _MAYA_ROOT_SEARCH_DIR ${_MAYA_ROOT})
endif()
# @todo deprecate MAYA_LOCATION? There may be workflows which set this variable
if(DEFINED ENV{MAYA_LOCATION})
list(APPEND _MAYA_ROOT_SEARCH_DIR $ENV{MAYA_LOCATION})
endif()
# ------------------------------------------------------------------------
# Search for Maya
# ------------------------------------------------------------------------
find_path(Maya_INCLUDE_DIR maya/MTypes.h
${_FIND_MAYA_ADDITIONAL_OPTIONS}
PATHS ${_MAYA_ROOT_SEARCH_DIR}
PATH_SUFFIXES include
)
if(NOT EXISTS "${Maya_INCLUDE_DIR}/maya/MTypes.h")
message(FATAL_ERROR "Unable to locate Maya Installation.")
endif()
# Determine Maya version, including point releases. Currently only works for
# Maya 2016 and onwards so there is no -x64 and -x32 suffixes in the version
file(STRINGS "${Maya_INCLUDE_DIR}/maya/MTypes.h"
_maya_version_string REGEX "#define MAYA_API_VERSION "
)
string(REGEX REPLACE ".*#define[ \t]+MAYA_API_VERSION[ \t]+([0-9]+).*$" "\\1"
_maya_version_string "${_maya_version_string}"
)
string(SUBSTRING ${_maya_version_string} 0 4 Maya_MAJOR_VERSION)
string(SUBSTRING ${_maya_version_string} 4 2 Maya_MINOR_VERSION)
if(Maya_MINOR_VERSION LESS 50)
set(Maya_VERSION ${Maya_MAJOR_VERSION})
else()
set(Maya_VERSION ${Maya_MAJOR_VERSION}.5)
endif()
unset(_maya_version_string)
# Find required maya libs
set(_MAYA_COMPONENT_LIST
OpenMaya
OpenMayaFX
OpenMayaUI
Foundation
)
set(Maya_LIBRARY_DIR "")
if(APPLE)
set(Maya_LIBRARY_DIR ${Maya_INCLUDE_DIR}/../Maya.app/Contents/MacOS/)
else()
set(Maya_LIBRARY_DIR ${Maya_INCLUDE_DIR}/../lib/)
endif()
set(Maya_LIB_COMPONENTS "")
foreach(COMPONENT ${_MAYA_COMPONENT_LIST})
find_library(Maya_${COMPONENT}_LIBRARY ${COMPONENT}
${_FIND_MAYA_ADDITIONAL_OPTIONS}
PATHS ${Maya_LIBRARY_DIR}
)
list(APPEND Maya_LIB_COMPONENTS ${Maya_${COMPONENT}_LIBRARY})
endforeach()
# ------------------------------------------------------------------------
# Cache and set Maya_FOUND
# ------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Maya
FOUND_VAR Maya_FOUND
REQUIRED_VARS
Maya_INCLUDE_DIR
Maya_LIB_COMPONENTS
VERSION_VAR Maya_VERSION
)
if(NOT Maya_FOUND)
message(FATAL_ERROR "Unable to locate Maya Installation.")
elseif(Maya_VERSION VERSION_LESS MINIMUM_MAYA_VERSION)
message(WARNING "Unsupported Maya Version ${Maya_VERSION}. Minimum "
"supported is ${MINIMUM_MAYA_VERSION}."
)
endif()
# ------------------------------------------------------------------------
# Configure dependencies
# ------------------------------------------------------------------------
if(NOT TBB_INCLUDEDIR)
set(TBB_INCLUDEDIR ${Maya_INCLUDE_DIR})
endif()
if(NOT TBB_LIBRARYDIR)
set(TBB_LIBRARYDIR ${Maya_LIBRARY_DIR})
endif()
# ------------------------------------------------------------------------
# Configure Maya
# ------------------------------------------------------------------------
set(Maya_LIBRARIES ${Maya_LIB_COMPONENTS})
set(Maya_INCLUDE_DIRS ${Maya_INCLUDE_DIR})
set(Maya_LIBRARY_DIRS ${Maya_LIBRARY_DIR})
if(APPLE)
set(Maya_DEFINITIONS
-DMAC_PLUGIN
-DREQUIRE_IOSTREAM
-DOSMac_
-DOSMac_MachO_
-D_BOOL
)
elseif(WIN32)
set(Maya_DEFINITIONS
-DNOMINMAX
-DNT_PLUGIN
-DREQUIRE_IOSTREAM
-D_USE_MATH_DEFINES
-D_CRT_SECURE_NO_WARNINGS
)
else()
set(Maya_DEFINITIONS
-D_BOOL
-DFUNCPROTO
-DGL_GLEXT_PROTOTYPES=1
-DREQUIRE_IOSTREAM
-DUNIX
-fno-gnu-keywords
-fno-omit-frame-pointer
-fno-strict-aliasing
-funsigned-char
-Wno-comment
-Wno-multichar
-Wno-strict-aliasing
-m64
-DBits64_
-DLINUX
-DLINUX_64
)
endif()
# Configure imported targets
if(NOT TARGET Maya)
add_library(Maya INTERFACE)
foreach(COMPONENT ${_MAYA_COMPONENT_LIST})
add_library(Maya::${COMPONENT} UNKNOWN IMPORTED)
set_target_properties(Maya::${COMPONENT} PROPERTIES
IMPORTED_LOCATION "${Maya_${COMPONENT}_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Maya_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Maya_INCLUDE_DIRS}"
)
target_link_libraries(Maya INTERFACE Maya::${COMPONENT})
endforeach()
endif()
macro(MAYA_SET_LIBRARY_PROPERTIES NAME)
if(WIN32)
set_target_properties(${NAME} PROPERTIES
SUFFIX ".mll"
PREFIX ""
LINK_FLAGS "/export:initializePlugin /export:uninitializePlugin"
)
elseif(APPLE)
set_target_properties(${NAME} PROPERTIES
SUFFIX ".bundle"
PREFIX ""
)
else()
set_target_properties(${NAME} PROPERTIES
PREFIX ""
)
endif()
endmacro()
-164
View File
@@ -1,164 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
OpenVDBUtils.cmake
------------------
A utility CMake file which provides helper functions for configuring an
OpenVDB installation.
Use this module by invoking include with the form::
include ( OpenVDBUtils )
The following functions are provided:
``OPENVDB_GET_VERSION_DEFINE``
OPENVDB_GET_VERSION_DEFINE ( <header_path> <key> <value> )
Parse the provided version file to retrieve the a given OpenVDB define
specified by <key> and store the result in <value>. If the define has a
value, the value is stored. If the define has no value but exists, ON is
stored. Else, OFF is stored.
If the file does not exist, <value> is unmodified.
``OPENVDB_VERSION_FROM_HEADER``
OPENVDB_VERSION_FROM_HEADER ( <header_path>
VERSION [<version>]
MAJOR [<version>]
MINOR [<version>]
PATCH [<version>] )
Parse the provided version file to retrieve the current OpenVDB
version information. The file is expected to be a version.h file
as found in the following path of an OpenVDB repository:
openvdb/version.h
If the file does not exist, variables are unmodified.
``OPENVDB_ABI_VERSION_FROM_PRINT``
OPENVDB_ABI_VERSION_FROM_PRINT ( <vdb_print>
[QUIET]
ABI [<version>] )
Retrieve the ABI version that an installation of OpenVDB was compiled
for using the provided vdb_print binary. Parses the result of:
vdb_print --version
If the binary does not exist or fails to launch, variables are
unmodified.
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
function(OPENVDB_GET_VERSION_DEFINE HEADER KEY VALUE)
if(NOT EXISTS ${HEADER})
return()
endif()
file(STRINGS "${HEADER}" details REGEX "^#define[\t ]+${KEY}[\t ]+.*")
if(details)
# define has a value, extract it and return
string(REGEX REPLACE "^.*${KEY}[\t ]+([0-9]*).*$" "\\1" details "${details}")
set(${VALUE} ${details} PARENT_SCOPE)
return()
endif()
# try re-searching for single defines
file(STRINGS "${HEADER}" details REGEX "^#define[\t ]+${KEY}.*")
if(details)
set(${VALUE} ON PARENT_SCOPE)
else()
set(${VALUE} OFF PARENT_SCOPE)
endif()
endfunction()
########################################################################
########################################################################
function(OPENVDB_VERSION_FROM_HEADER OPENVDB_VERSION_FILE)
cmake_parse_arguments(_VDB "" "VERSION;MAJOR;MINOR;PATCH;ABI" "" ${ARGN})
if(NOT EXISTS ${OPENVDB_VERSION_FILE})
return()
endif()
OPENVDB_GET_VERSION_DEFINE(${OPENVDB_VERSION_FILE} "OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER" _OpenVDB_MAJOR_VERSION)
OPENVDB_GET_VERSION_DEFINE(${OPENVDB_VERSION_FILE} "OPENVDB_LIBRARY_MINOR_VERSION_NUMBER" _OpenVDB_MINOR_VERSION)
OPENVDB_GET_VERSION_DEFINE(${OPENVDB_VERSION_FILE} "OPENVDB_LIBRARY_PATCH_VERSION_NUMBER" _OpenVDB_PATCH_VERSION)
OPENVDB_GET_VERSION_DEFINE(${OPENVDB_VERSION_FILE} "OPENVDB_ABI_VERSION_NUMBER" _OpenVDB_ABI_VERSION)
if(_VDB_VERSION)
set(${_VDB_VERSION}
${_OpenVDB_MAJOR_VERSION}.${_OpenVDB_MINOR_VERSION}.${_OpenVDB_PATCH_VERSION}
PARENT_SCOPE
)
endif()
if(_VDB_MAJOR)
set(${_VDB_MAJOR} ${_OpenVDB_MAJOR_VERSION} PARENT_SCOPE)
endif()
if(_VDB_MINOR)
set(${_VDB_MINOR} ${_OpenVDB_MINOR_VERSION} PARENT_SCOPE)
endif()
if(_VDB_PATCH)
set(${_VDB_PATCH} ${_OpenVDB_PATCH_VERSION} PARENT_SCOPE)
endif()
if(_VDB_ABI)
set(${_VDB_ABI} ${_OpenVDB_ABI_VERSION} PARENT_SCOPE)
endif()
endfunction()
########################################################################
########################################################################
function(OPENVDB_ABI_VERSION_FROM_PRINT OPENVDB_PRINT)
cmake_parse_arguments(_VDB "QUIET" "ABI" "" ${ARGN})
if(NOT EXISTS ${OPENVDB_PRINT})
return()
endif()
set(_VDB_PRINT_VERSION_STRING "")
set(_VDB_PRINT_RETURN_STATUS "")
if(${_VDB_QUIET})
execute_process(COMMAND ${OPENVDB_PRINT} "--version"
RESULT_VARIABLE _VDB_PRINT_RETURN_STATUS
OUTPUT_VARIABLE _VDB_PRINT_VERSION_STRING
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else()
execute_process(COMMAND ${OPENVDB_PRINT} "--version"
RESULT_VARIABLE _VDB_PRINT_RETURN_STATUS
OUTPUT_VARIABLE _VDB_PRINT_VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
if(${_VDB_PRINT_RETURN_STATUS})
return()
endif()
set(_OpenVDB_ABI)
string(REGEX REPLACE ".*abi([0-9]*).*" "\\1" _OpenVDB_ABI ${_VDB_PRINT_VERSION_STRING})
unset(_VDB_PRINT_RETURN_STATUS)
unset(_VDB_PRINT_VERSION_STRING)
if(_VDB_ABI)
set(${_VDB_ABI} ${_OpenVDB_ABI} PARENT_SCOPE)
endif()
endfunction()
-41
View File
@@ -1,41 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[.rst:
Uninstall
---------
Adds a custom target to the CMake build generation which allows for
calling::
make uninstall
to remove an installation of OpenVDB. Relies on the install_manifest
existing from a previous run of cmake.
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
if(NOT EXISTS ${MANIFEST})
message(FATAL_ERROR "Cannot find install manifest: '${MANIFEST}'")
endif()
file(STRINGS ${MANIFEST} INSTALLED_FILES)
foreach(INSTALLED_FILE ${INSTALLED_FILES})
if(EXISTS ${INSTALLED_FILE})
message(STATUS "Uninstalling: ${INSTALLED_FILE}")
exec_program(
${CMAKE_COMMAND} ARGS "-E remove ${INSTALLED_FILE}"
OUTPUT_VARIABLE stdout
RETURN_VALUE RESULT
)
if(NOT "${RESULT}" STREQUAL 0)
message(FATAL_ERROR "Failed to remove file: '${INSTALLED_FILE}'.")
endif()
endif()
endforeach(INSTALLED_FILE)
-363
View File
@@ -1,363 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
CXX and CMAKE_CXX options and definitions for OpenVDB build types
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
###############################################################################
# General CMake and CXX settings
if(FUTURE_MINIMUM_CMAKE_VERSION)
if(${CMAKE_VERSION} VERSION_LESS ${FUTURE_MINIMUM_CMAKE_VERSION})
message(DEPRECATION "Support for CMake versions < ${FUTURE_MINIMUM_CMAKE_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD ${MINIMUM_CXX_STANDARD} CACHE STRING
"The C++ standard whose features are requested to build OpenVDB components." FORCE)
elseif(CMAKE_CXX_STANDARD LESS ${MINIMUM_CXX_STANDARD})
message(FATAL_ERROR "Provided C++ Standard is less than the supported minimum."
"Required is at least \"${MINIMUM_CXX_STANDARD}\" (found ${CMAKE_CXX_STANDARD})")
endif()
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_CXX_STANDARD)
if(CMAKE_CXX_STANDARD LESS ${FUTURE_MINIMUM_CXX_STANDARD})
message(DEPRECATION "C++ < 17 is deprecated and will be removed.")
endif()
endif()
# Configure MS Runtime
if(WIN32 AND CMAKE_MSVC_RUNTIME_LIBRARY)
message(STATUS "CMAKE_MSVC_RUNTIME_LIBRARY set to target ${CMAKE_MSVC_RUNTIME_LIBRARY}")
# Configure Boost library varient on Windows
if(NOT Boost_USE_STATIC_RUNTIME)
set(Boost_USE_STATIC_RUNTIME OFF)
if(CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL MultiThreaded OR
CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL MultiThreadedDebug)
set(Boost_USE_STATIC_RUNTIME ON)
endif()
endif()
if(NOT Boost_USE_DEBUG_RUNTIME)
set(Boost_USE_DEBUG_RUNTIME OFF)
if(CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL MultiThreadedDebugDLL OR
CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL MultiThreadedDebug)
set(Boost_USE_DEBUG_RUNTIME ON)
endif()
endif()
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
if(OPENVDB_ENABLE_RPATH)
# Configure rpath for installation base on the following:
# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# @todo make relocatable?
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
endif()
# For CMake's find Threads module which brings in pthread - This flag
# forces the compiler -pthread flag vs -lpthread
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
###############################################################################
# Compiler version checks
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_CLANG_VERSION)
message(FATAL_ERROR "Insufficient clang++ version. Minimum required is "
"\"${MINIMUM_CLANG_VERSION}\". Found version \"${CMAKE_CXX_COMPILER_VERSION}\""
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_GCC_VERSION)
message(FATAL_ERROR "Insufficient g++ version. Minimum required is "
"\"${MINIMUM_GCC_VERSION}\". Found version \"${CMAKE_CXX_COMPILER_VERSION}\""
)
endif()
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_GCC_VERSION)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS FUTURE_MINIMUM_GCC_VERSION)
message(DEPRECATION "Support for GCC versions < ${FUTURE_MINIMUM_GCC_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_ICC_VERSION)
message(FATAL_ERROR "Insufficient ICC version. Minimum required is "
"\"${MINIMUM_ICC_VERSION}\". Found version \"${CMAKE_CXX_COMPILER_VERSION}\""
)
endif()
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_ICC_VERSION)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS FUTURE_MINIMUM_ICC_VERSION)
message(DEPRECATION "Support for ICC versions < ${FUTURE_MINIMUM_ICC_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_MSVC_VERSION)
message(FATAL_ERROR "Insufficient MSVC version. Minimum required is "
"\"${MINIMUM_MSVC_VERSION}\". Found version \"${CMAKE_CXX_COMPILER_VERSION}\""
)
endif()
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_MSVC_VERSION)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS FUTURE_MINIMUM_MSVC_VERSION)
message(DEPRECATION "Support for MSVC versions < ${FUTURE_MINIMUM_MSVC_VERSION} "
"is deprecated and will be removed.")
endif()
endif()
else()
message(WARNING "Unsupported CXX compiler ${CMAKE_CXX_COMPILER_ID}")
endif()
###############################################################################
# Increase the number of sections that an object file can contain
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/bigobj>")
# Enable MSVC options that make it behave like other compilers
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/Zc:throwingNew>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/Zc:inline>")
# Excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets
add_compile_definitions("$<$<CXX_COMPILER_ID:MSVC>:WIN32_LEAN_AND_MEAN>")
# Disable non-secure CRT library function warnings
# https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/
# compiler-warning-level-3-c4996?view=vs-2019#unsafe-crt-library-functions
add_compile_definitions("$<$<CXX_COMPILER_ID:MSVC>:_CRT_SECURE_NO_WARNINGS>")
# Disable POSIX function name warnings
# https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/
# compiler-warning-level-3-c4996?view=vs-2019#posix-function-names
add_compile_definitions("$<$<CXX_COMPILER_ID:MSVC>:_CRT_NONSTDC_NO_WARNINGS>")
if(MSVC_MP_THREAD_COUNT AND MSVC_MP_THREAD_COUNT GREATER 1)
# If a user has explicitly requested a parallel build, configure this during CMake
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/MP${MSVC_MP_THREAD_COUNT}>")
# If building with multiple threads with MSVC, delay generation of PDB files
# until the end of compilation to speed up their generation (invoke mspdbsrv once).
# This assumes /Zi is being used to generate PDBs (CMakes default)
add_compile_options("$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANG_AND_ID:CXX,MSVC>>:/Zf>")
endif()
if(MSVC_COMPRESS_PDB)
# /Zi enables PDBs - CMake seems to default to creating PDBs as the defacto way
# of handling debug symbols. As these PDBs can be very large, we attempt to compress
# them here with various settings. This disable incremental linking and can make
# stack traces more confusing.
# https://devblogs.microsoft.com/cppblog/shrink-my-program-database-pdb-file/
# First, generate comdats to allow the linker to remove unused data
add_compile_options("$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANG_AND_ID:CXX,MSVC>>:/Gy>")
# Remove unreferenced packaged functions and data from comdats
add_link_options("$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANG_AND_ID:CXX,MSVC>>:/OPT:REF>")
# Fold duplicate comdat data (1 iteration)
add_link_options("$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANG_AND_ID:CXX,MSVC>>:/OPT:ICF>")
# Generally compress the generated pdbs as they are being created
add_link_options("$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANG_AND_ID:CXX,MSVC>>:/PDBCOMPRESS>")
endif()
if(OPENVDB_CXX_STRICT)
message(STATUS "Configuring CXX warnings")
# Clang/AppleClang
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Werror>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wall>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wextra>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wconversion>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wnon-virtual-dtor>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wover-aligned>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wimplicit-fallthrough>")
add_compile_options("$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9.3.0>>:-Wimplicit-fallthrough>")
# Only check global constructors for libraries (we should really check for
# executables too but gtest relies on these types of constructors for its
# framework). nanobind also incorporates these constructors so skip it as well.
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>>>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:-Wglobal-constructors>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wno-sign-conversion>")
# GNU
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Werror>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wall>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wextra>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wcast-align>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wdisabled-optimization>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Woverloaded-virtual>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wnon-virtual-dtor>")
# Disable select warnings for the nanobind static library
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-pedantic>")
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wcast-qual>")
add_compile_options("$<$<AND:$<NOT:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wconversion>")
add_compile_options("$<$<AND:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wno-unused-variable>")
add_compile_options("$<$<AND:$<OR:$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanobind-static>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,openvdb_python>,$<STREQUAL:$<TARGET_PROPERTY:NAME>,nanovdb_python>>,$<COMPILE_LANG_AND_ID:CXX,GNU>>:-Wno-unused-but-set-parameter>")
else()
# NO OPENVDB_CXX_STRICT, suppress some warnings
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message(STATUS "Suppressing some noisy MSVC CXX warnings, "
"set OPENVDB_CXX_STRICT=ON to re-enable them.")
endif()
# Conversion from int64_t to long
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/wd4244>")
# It's not possible to use STL types in DLL interfaces in a portable and
# reliable way so disable this warning
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/wd4251>")
# Conversion from size_t to uLong
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/wd4267>")
# Non dll-interface class used as base for dll-interface class
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/wd4275>")
# Truncation from 'int' to 'bool'
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/wd4305>")
endif()
if(USE_COLORED_OUTPUT)
message(STATUS "Enabling colored compiler output")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-fcolor-diagnostics>")
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-fdiagnostics-color=always>")
endif()
###############################################################################
# Build Types
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
CACHE STRING [=[Choose the type of build. CMake natively supports the following options: None Debug Release
RelWithDebInfo MinSizeRel. OpenVDB additionally supports the following sanitizers and tools:
coverage tsan asan lsan msan ubsan]=]
FORCE)
if(CMAKE_BUILD_TYPE EQUAL coverage)
# use .gcno extension instead of .cc.gcno
# @note This is an undocumented internal cmake var and does not work
# with multi config generators
set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)
endif()
# Note that the thread, address and memory sanitizers are incompatible with each other
set(EXTRA_BUILD_TYPES coverage tsan asan lsan msan ubsan abicheck)
# Set all build flags to empty (unless they have been provided)
# DebugNoInfo - An internal build type only used by the OpenVDB CI. no optimizations, no symbols, asserts enabled
set(CMAKE_CXX_FLAGS_DebugNoInfo "" CACHE STRING "Flags used by the C++ compiler during DebugNoInfo builds.")
foreach(TYPE ${EXTRA_BUILD_TYPES})
set(CMAKE_CXX_FLAGS_${U_TYPE} "" CACHE STRING "Flags used by the C++ compiler during ${TYPE} builds.")
set(CMAKE_SHARED_LINKER_FLAGS_${U_TYPE} "" CACHE STRING "Flags used by the linker during ${TYPE} builds.")
set(CMAKE_EXE_LINKER_FLAGS_${U_TYPE} "" CACHE STRING "Flags used by the linker during ${TYPE} builds.")
endforeach()
# Init generator options - we use generator expressions to allow builds with both
# clang and GCC. Sanitizers are currently only configured for clang and GCC.
# Coverage
# --coverage uses -fprofile-arcs -ftest-coverage (compiling) and -lgcov (linking)
# @note consider -fprofile-abs-path from gcc 10
# @todo consider using clang with source analysis: -fprofile-instr-generate -fcoverage-mapping.
# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
# note that clang also works with gcov (--coverage)
# @note Ideally we'd use no optimisations (-O0) with --coverage, but a complete
# run of all unit tests takes upwards of a day without them. Thread usage also
# impacts total runtime. -Og implies -O1 but without optimisations "that would
# otherwise interfere with debugging". This still massively effects branch
# coverage tracking compared to -O0 so we should look to improve the speed of
# some of the unit tests and also experiment with clang.
add_compile_options("$<$<AND:$<CONFIG:COVERAGE>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:--coverage;-Og>")
add_link_options("$<$<AND:$<CONFIG:COVERAGE>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:--coverage>")
# ThreadSanitizer
add_compile_options("$<$<AND:$<CONFIG:TSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=thread>")
add_compile_options("$<$<AND:$<CONFIG:TSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-g;-O1>")
add_link_options("$<$<AND:$<CONFIG:TSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=thread>")
# AddressSanitize
add_compile_options("$<$<AND:$<CONFIG:ASAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=address>")
add_compile_options("$<$<AND:$<CONFIG:ASAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fno-omit-frame-pointer;-g;-O1>")
add_compile_options("$<$<AND:$<CONFIG:ASAN>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:-fsanitize-address-use-after-scope;-fno-optimize-sibling-calls>")
# -fsanitize-address-use-after-scope added in GCC 7
add_compile_options("$<$<AND:$<CONFIG:ASAN>,$<COMPILE_LANG_AND_ID:CXX,GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,7.0.0>>:-fsanitize-address-use-after-scope>")
add_link_options("$<$<AND:$<CONFIG:ASAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=address>")
# LeakSanitizer
add_compile_options("$<$<AND:$<CONFIG:LSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=leak>")
add_compile_options("$<$<AND:$<CONFIG:LSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fno-omit-frame-pointer;-g;-O1>")
add_link_options("$<$<AND:$<CONFIG:LSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=leak>")
# MemorySanitizer
add_compile_options("$<$<AND:$<CONFIG:MSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=memory>")
add_compile_options("$<$<AND:$<CONFIG:MSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fno-omit-frame-pointer;-g;-O2>")
add_compile_options("$<$<AND:$<CONFIG:MSAN>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:--fno-optimize-sibling-calls;-fsanitize-memory-track-origins=2>")
add_link_options("$<$<AND:$<CONFIG:MSAN>,$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>>:-fsanitize=memory>")
# UndefinedBehaviour
add_compile_options("$<$<AND:$<CONFIG:UBSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=undefined>")
add_link_options("$<$<AND:$<CONFIG:UBSAN>,$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>>:-fsanitize=undefined>")
# ABI Check. This build type is expected to work with the abi-dumper/abi-compliance-checker
# binaries which expect specific debug information. In particular, for GCC versions >= 11
# we have to explicitly select dwarf versions < 5 as the abi-dumper doesn't support dwarf5
# and will always incorrectly report successful ABI checks
# https://github.com/lvc/abi-dumper/issues/33
add_compile_options("$<$<CONFIG:ABICHECK>:-gdwarf-4;-g3;-ggdb;-Og>")
# CMAKE_BUILD_TYPE is ignored for multi config generators i.e. MSVS
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _isMultiConfig)
message(STATUS "CMake Build Type: ${CMAKE_BUILD_TYPE}")
endif()
if(OPENVDB_ENABLE_ASSERTS)
message(STATUS "OpenVDB asserts are ENABLED")
endif()
# Intialize extra build type targets where possible
if(NOT TARGET gcov_html)
find_program(GCOVR_PATH gcovr)
if(NOT GCOVR_PATH AND CMAKE_BUILD_TYPE STREQUAL "coverage")
message(WARNING "Unable to initialize gcovr target. coverage build types will still generate gcno files.")
elseif(GCOVR_PATH)
# init gcov commands
set(GCOVR_HTML_FOLDER_CMD ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/gcov_html)
set(GCOVR_HTML_CMD
${GCOVR_PATH} --html --html-details -r ${PROJECT_SOURCE_DIR} --object-directory=${PROJECT_BINARY_DIR}
-o gcov_html/index.html
)
# Add a custom target which converts .gcda files to a html report using gcovr.
# Note that this target does NOT run ctest or any binaries - that is left to
# the implementor of the gcov workflow. Typically, the order of operations
# would be:
# - run CMake with unit tests on
# - ctest
# - make gcov_html
add_custom_target(gcov_html
COMMAND ${GCOVR_HTML_FOLDER_CMD}
COMMAND ${GCOVR_HTML_CMD}
BYPRODUCTS ${PROJECT_BINARY_DIR}/gcov_html/index.html # report directory
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
VERBATIM
COMMENT "Running gcovr to produce HTML code coverage report."
)
# Show info where to find the report
add_custom_command(TARGET gcov_html POST_BUILD
COMMAND ;
COMMENT "Open ./gcov_html/index.html in your browser to view the coverage report."
)
endif()
endif()
-88
View File
@@ -1,88 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
Current and future version requirements for all OpenVDB dependencies,
including compilers, language features and OpenVDB's ABI.
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
###############################################################################
# Configure minimum version requirements - some are treated specially and fall
# outside of the DISABLE_DEPENDENCY_VERSION_CHECKS catch
set(MINIMUM_CXX_STANDARD 17)
# @note ABI always enforced so the correct deprecation messages are available.
# OPENVDB_USE_DEPRECATED_ABI_<VERSION> should be used to circumvent this
math(EXPR MINIMUM_OPENVDB_ABI_VERSION "${OpenVDB_MAJOR_VERSION}-2")
math(EXPR FUTURE_OPENVDB_ABI_VERSION "${OpenVDB_MAJOR_VERSION}+1")
# List of deprecated but supported OpenVDB ABIs for this version of OpenVDB
math(EXPR _PREV_ABI "${OpenVDB_MAJOR_VERSION}-1")
set(OPENVDB_DEPRECATED_ABI_LIST ${MINIMUM_OPENVDB_ABI_VERSION} ${_PREV_ABI})
unset(_PREV_ABI)
if(NOT DISABLE_DEPENDENCY_VERSION_CHECKS)
# @note Currently tracking CY2022 of the VFX platform where available
# @Note Compiler versions are not really a hard and fast rule, you just need
# a compiler with complete support for our MINIMUM_CXX_STANDARD (currently 17).
# What's usually important is that the version of libstdc++ and glibc in use
# matches. Compilers other than GCC should provide options to ensure this
# targetting e.g. --gcc-toolchain and -fgnuc-version with Clang.
set(MINIMUM_GCC_VERSION 11.2.1)
set(MINIMUM_CLANG_VERSION 5.0)
set(MINIMUM_ICC_VERSION 19)
set(MINIMUM_MSVC_VERSION 19.30) # 1928 (Visual Studio 2019 Version 16.8 + 16.9)
set(MINIMUM_BOOST_VERSION 1.80)
# Nanobind does not store the version in the CMake config file in 2.0.0.
# This issue was fixed in 2.1.0 so next time we bump the minimum version,
# we can define this.
#set(MINIMUM_NANOBIND_VERSION 2.0.0)
set(MINIMUM_IMATH_VERSION 3.1)
set(MINIMUM_OPENEXR_VERSION 3.1)
set(MINIMUM_ZLIB_VERSION 1.2.7)
set(MINIMUM_TBB_VERSION 2020.3)
set(MINIMUM_LLVM_VERSION 13.0.0)
set(MINIMUM_BLOSC_VERSION 1.17.0)
set(MINIMUM_GLFW_VERSION 3.1)
set(MINIMUM_PYTHON_VERSION 3.10)
set(MINIMUM_NUMPY_VERSION 1.23.0)
set(MINIMUM_GOOGLETEST_VERSION 1.10)
set(MINIMUM_LOG4CPLUS_VERSION 1.1.2)
set(MINIMUM_HOUDINI_VERSION 19.5)
# These always promote warnings rather than errors
set(MINIMUM_MAYA_VERSION 2017)
set(MINIMUM_DOXYGEN_VERSION 1.8.8)
endif()
# VFX 23 deprecations to transition to MINIMUM_* variables in OpenVDB 12.0.0
# @note At the time of writing, any variables that are commented out don't
# have target transitional versions.
# set(FUTURE_MINIMUM_GCC_VERSION 11.2.1)
# set(FUTURE_MINIMUM_MSVC_VERSION 19.30)
# set(FUTURE_MINIMUM_ICC_VERSION 19)
# set(FUTURE_MINIMUM_CXX_STANDARD 20)
set(FUTURE_MINIMUM_CMAKE_VERSION 3.24)
set(FUTURE_MINIMUM_OPENEXR_VERSION 3.2)
set(FUTURE_MINIMUM_BOOST_VERSION 1.82)
set(FUTURE_MINIMUM_GLFW_VERSION 3.3)
set(FUTURE_MINIMUM_LOG4CPLUS_VERSION 2.0)
# set(FUTURE_MINIMUM_NANOBIND_VERSION 2.1.0)
# set(FUTURE_MINIMUM_BLOSC_VERSION 1.17.0)
# set(FUTURE_MINIMUM_TBB_VERSION 2020.3)
set(FUTURE_MINIMUM_PYTHON_VERSION 3.11)
set(FUTURE_MINIMUM_NUMPY_VERSION 1.26.0)
# set(FUTURE_MINIMUM_HOUDINI_VERSION 20.0)
set(FUTURE_MINIMUM_LLVM_VERSION 15.0.0)
-15
View File
@@ -1,15 +0,0 @@
#################################################################################
## This file is loaded by the Leak/Address Sanitizer build for the unit tests. ##
## It can be used to ignore various errors reported by the sanitizer. This is ##
## especially useful with upstream issues (e.g. boost/tbb). For help defining ##
## suppression rules, see: ##
## https://clang.llvm.org/docs/AddressSanitizer.html ##
## The build is configured with CMAKE_BUILD_TYPE=asan or lsan ##
#################################################################################
##### Upstream #####
# Leaks from TBB init which occur due to tbb teardown issues
# https://github.com/oneapi-src/oneTBB/issues/206
# Should be fixed in oneTBB. Ignore them for now
leak:tbb::internal::task_stream<3>::initialize*
-27
View File
@@ -1,27 +0,0 @@
#################################################################################
## This file is loaded by the Undefined Behaviour Sanitizer build for the unit ##
## tests. It can be used to ignore various errors reported by the sanitizer. ##
## This is especially useful with upstream issues (e.g. boost/tbb). For help ##
## defining suppression rules, see: ##
## https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ##
## The build is configured with CMAKE_BUILD_TYPE=ubsan. ##
#################################################################################
##### Upstream #####
# Lots of warnings from TBB, ignore them
alignment:tbb/concurrent_hash_map.h
vptr:tbb/parallel_reduce.h
vptr:tbb/task.h
##### OpenVDB #####
# Some 2s complement tests, ignore the negative shifts
# @todo Should address these
shift-base:TestMultiResGrid.cc
shift-base:openvdb/math/Coord.h
##### OpenVDB AX #####
# Ignore overflows reported from old OpenSimplexNoise
signed-integer-overflow:openvdb_ax/math/OpenSimplexNoise.cc
-272
View File
@@ -1,272 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
CMake Configuration for OpenVDB Documentation
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
project(OpenVDBDocs LANGUAGES NONE)
include(GNUInstallDirs)
# If OPENVDB_DOXYGEN_HOUDINI is set, the Houdini documentation is also
# built. You can provide this module a value for Houdini_VERSION which will
# take into account any conditional compiled blocks. Whilst this doesn't
# require you to build the Houdini plugin, building from the root CMake
# with OPENVDB_BUILD_DOCS=ON and either OPENVDB_BUILD_HOUDINI_PLUGIN=ON or
# USE_HOUDINI=ON will define Houdini_VERSION. If Houdini_VERSION is not set,
# all documentation is included.
option(OPENVDB_DOXYGEN_AX "Build AX documentation" ON)
option(OPENVDB_DOXYGEN_HOUDINI "Build Houdini documentation" ON)
option(OPENVDB_DOXYGEN_NANOVDB "Build NanoVDB documentation" ON)
option(OPENVDB_DOXYGEN_INTERNAL [=[
Enable documentation of methods and classes which have been explicitly marked as internal
]=] OFF)
find_package(Doxygen REQUIRED doxygen)
if(MINIMUM_DOXYGEN_VERSION)
if(DOXYGEN_VERSION VERSION_LESS MINIMUM_DOXYGEN_VERSION)
message(WARNING "The doxygen-config doxyfile has been generated with version "
"\"${MINIMUM_DOXYGEN_VERSION}\". Found Doxygen version \"${DOXYGEN_VERSION}\". "
"Documentation may contain errors."
)
endif()
endif()
set(DOXY_FILES
openvdb/openvdb
openvdb/openvdb/io
openvdb/openvdb/math
openvdb/openvdb/points
openvdb/openvdb/points/impl
openvdb/openvdb/python/pyopenvdb.h
openvdb/openvdb/tools
openvdb/openvdb/tools/impl
openvdb/openvdb/tree
openvdb/openvdb/util
doc/build.txt
doc/changes.txt
doc/codingstyle.txt
doc/dependencies.txt
doc/doc.txt
doc/examplecode.txt
doc/faq.txt
doc/math.txt
doc/points.txt
doc/python.txt)
set(DOXYGEN_PROJECT_NAME "OpenVDB")
set(DOXYGEN_PROJECT_NUMBER "${OpenVDB_VERSION}")
set(DOXYGEN_PROJECT_BRIEF "")
set(DOXYGEN_FILE_PATTERNS *.h *h.in) # headers only
set(DOXYGEN_EXTENSION_MAPPING .in=C) # parse CMake config headers as C
set(DOXYGEN_IMAGE_PATH "doc/img")
set(DOXYGEN_RECURSIVE NO)
set(DOXYGEN_QUIET YES)
set(DOXYGEN_GENERATE_HTML YES)
set(DOXYGEN_GENERATE_MAN NO)
set(DOXYGEN_GENERATE_LATEX NO)
set(DOXYGEN_GENERATE_TODOLIST NO)
set(DOXYGEN_HTML_COLORSTYLE_HUE 4)
set(DOXYGEN_HTML_COLORSTYLE_SAT 222)
set(DOXYGEN_HTML_TIMESTAMP NO) # for simpler website diffs
set(DOXYGEN_EXTRACT_ALL YES)
set(DOXYGEN_EXTRACT_STATIC YES)
set(DOXYGEN_EXTRACT_LOCAL_CLASSES NO)
# Allow for root directory paths to be listed (e.g. openvdb/io/File.h)
# Rather than just the file names (e.g. File.h). This makes it far
# easier to navigate the docs
set(DOXYGEN_FULL_PATH_NAMES YES)
set(DOXYGEN_STRIP_FROM_PATH
"${CMAKE_SOURCE_DIR}/openvdb"
"${CMAKE_SOURCE_DIR}/openvdb_ax"
"${CMAKE_SOURCE_DIR}/nanovdb"
"${CMAKE_SOURCE_DIR}/openvdb_houdini"
"${CMAKE_SOURCE_DIR}")
set(DOXYGEN_STRIP_FROM_INC_PATH
"${CMAKE_SOURCE_DIR}/openvdb"
"${CMAKE_SOURCE_DIR}/openvdb_ax"
"${CMAKE_SOURCE_DIR}/nanovdb"
"${CMAKE_SOURCE_DIR}/openvdb_houdini")
# Shows which source files generated the respected doxygen docs
# at the bottom of each html page. Don't bother listing these.
set(DOXYGEN_SHOW_USED_FILES NO)
# When doxygen adds the source code for each header (see VERBATIM_HEADERS)
# don't remove the actual doxygen comments
set(DOXYGEN_STRIP_CODE_COMMENTS NO)
# Don't add an alpha index of all classes (it's not particularly useful)
set(DOXYGEN_ALPHABETICAL_INDEX NO)
set(DOXYGEN_DISTRIBUTE_GROUP_DOC YES)
set(DOXYGEN_HIDE_IN_BODY_DOCS YES)
set(DOXYGEN_HIDE_SCOPE_NAMES YES)
set(DOXYGEN_INLINE_INHERITED_MEMB YES)
set(DOXYGEN_MACRO_EXPANSION YES)
# @todo use dot with class diagrams for relevant classes
set(DOXYGEN_CLASS_DIAGRAMS NO)
set(DOXYGEN_ALIASES
[[ijk="(<i>i</i>,&nbsp;<i>j</i>,&nbsp;<i>k</i>)"]]
[[xyz="(<i>x</i>,&nbsp;<i>y</i>,&nbsp;<i>z</i>)"]]
[[const="<tt>const</tt>"]]
"\"vdbnamespace=openvdb::v${OpenVDB_MAJOR_VERSION}_${OpenVDB_MINOR_VERSION}\""
[["hunamespace=houdini_utils"]]
[["hvdbnamespace=openvdb_houdini"]]
# Use this command to create a link to an OpenVDB class, function, etc.
# Usage is "@vdblink{<symbol>,<text>}", where <symbol> is a fully namespace-
# qualified symbol minus the openvdb and version number namespace components
# and <text> is the text of the link.
# Example: @vdblink{tree::RootNode,root node}
[[vdblink{2}="@link @vdbnamespace::\1 \2@endlink"]]
# Deprecated; use the two-argument overload defined above.
[[vdblink="@link @vdbnamespace"]]
# Use these commands to create links to OpenVDB Houdini symbols.
# Usage is "@hulink{<symbol>,<text>}", where <symbol> is the name of
# a symbol in the houdini_utils namespace and <text> is the text of the link
# (and likewise for @hvdblink).
# Example: @hulink{ParmFactory::setDefault(),setDefault}
# These stub implementations are used when Houdini support is disabled;
# see doxygen-config-houdini for the full implementations.
[[hulink{2}="<B>\2</B>"]]
[[hvdblink{2}="<B>\2</B>"]]
)
set(DOXYGEN_PREDEFINED
"OPENVDB_VERSION_NAME=v${OpenVDB_MAJOR_VERSION}_${OpenVDB_MINOR_VERSION}"
"OPENVDB_ABI_VERSION_NUMBER=${OpenVDB_MAJOR_VERSION}"
[[__declspec(x):= __attribute__(x):=]]
# Replace the deprecated macros with doxygen deprecated comments. This ensures
# that every bit of deprecated C++ is listed in the doxygen deprecated list,
# even if it was not properly tagged
[["OPENVDB_DEPRECATED=/** \deprecated */"]]
[["OPENVDB_DEPRECATED_MESSAGE(x)=/** \deprecated x */"]]
"OPENVDB_USE_LOG4CPLUS=")
set(DOXYGEN_ENABLED_SECTIONS "")
if(OPENVDB_DOXYGEN_INTERNAL)
list(APPEND DOXYGEN_ENABLED_SECTIONS "OPENVDB_DOCS_INTERNAL")
endif()
if(OPENVDB_DOXYGEN_HOUDINI)
# Append Houdini-specific settings to the Doxygen config file.
if(Houdini_VERSION)
# Extract the components of the Houdini version number into a list.
string(REPLACE "." ";" HOUDINI_VERSION_COMPONENTS ${Houdini_VERSION})
list(GET HOUDINI_VERSION_COMPONENTS 0 HVERS_MAJOR)
list(GET HOUDINI_VERSION_COMPONENTS 1 HVERS_MINOR)
list(GET HOUDINI_VERSION_COMPONENTS 2 HVERS_PATCH)
else()
set(HVERS_MAJOR 127) # CMake treats (255 << 24) as a negative number
set(HVERS_MINOR 0)
set(HVERS_PATCH 0)
endif()
math(EXPR HVERS_INT "(((${HVERS_MAJOR} << 8) + ${HVERS_MINOR}) << 16) + ${HVERS_PATCH}")
# Append Houdini version number macros to the Doxygen config file so that
# the generated documentation reflects the API for that version
# (i.e, taking into account any conditionally compiled blocks).
list(APPEND DOXYGEN_PREDEFINED "UT_MAJOR_VERSION_INT=${HVERS_MAJOR}")
list(APPEND DOXYGEN_PREDEFINED "UT_MINOR_VERSION_INT=${HVERS_MINOR}")
list(APPEND DOXYGEN_PREDEFINED "UT_VERSION_INT=${HVERS_INT}")
list(APPEND DOXYGEN_ALIASES
[[hulink{2}="@link @hunamespace::\1 \2@endlink"]]
[[hvdblink{2}="@link @hvdbnamespace::\1 \2@endlink"]]
# Deprecated; use the two-argument overloads defined above.
[[hulink="@link @hunamespace"]]
[[hvdblink="@link @hvdbnamespace"]]
)
list(APPEND DOXYGEN_ENABLED_SECTIONS "OPENVDB_HOUDINI")
list(APPEND DOXY_FILES
doc/houdini.txt
openvdb_houdini/openvdb_houdini/AttributeTransferUtil.h
openvdb_houdini/openvdb_houdini/GEO_PrimVDB.h
openvdb_houdini/openvdb_houdini/GT_GEOPrimCollectVDB.h
openvdb_houdini/openvdb_houdini/GU_PrimVDB.h
openvdb_houdini/openvdb_houdini/GU_VDBPointTools.h
openvdb_houdini/openvdb_houdini/GeometryUtil.h
openvdb_houdini/openvdb_houdini/ParmFactory.h
openvdb_houdini/openvdb_houdini/PointUtils.h
openvdb_houdini/openvdb_houdini/SOP_NodeVDB.h
openvdb_houdini/openvdb_houdini/SOP_VDBVerbUtils.h
openvdb_houdini/openvdb_houdini/UT_VDBTools.h
openvdb_houdini/openvdb_houdini/UT_VDBUtils.h
openvdb_houdini/openvdb_houdini/Utils.h)
endif()
if(OPENVDB_DOXYGEN_AX)
set(DOXYGEN_EXTRA_PACKAGES amsmath) # for math formatting
set(DOXYGEN_FORMULA_FONTSIZE 14)
list(APPEND DOXYGEN_ENABLED_SECTIONS "OPENVDB_AX")
list(APPEND DOXY_FILES
doc/ax/ax.txt
doc/ax/axcplusplus.txt
doc/ax/axexamples.txt
doc/ax/axfunctionlist.txt
doc/ax/doc.txt
openvdb_ax/openvdb_ax
openvdb_ax/openvdb_ax/ast
openvdb_ax/openvdb_ax/codegen
openvdb_ax/openvdb_ax/compiler
openvdb_ax/openvdb_ax/grammar
openvdb_ax/openvdb_ax/grammar/generated
openvdb_ax/openvdb_ax/math
openvdb_ax/openvdb_ax/test)
endif()
if(OPENVDB_DOXYGEN_NANOVDB)
list(APPEND DOXYGEN_ENABLED_SECTIONS "NANOVDB")
list(APPEND DOXY_FILES
doc/nanovdb/doc.md
doc/nanovdb/FAQ.md
doc/nanovdb/SourceTree.md
doc/nanovdb/HowToBuild.md
doc/nanovdb/HelloWorld.md
nanovdb/nanovdb
nanovdb/nanovdb/util
nanovdb/nanovdb/examples/benchmark
nanovdb/nanovdb/examples/ex_bump_pool_buffer
nanovdb/nanovdb/examples/ex_collide_level_set
nanovdb/nanovdb/examples/ex_make_custom_nanovdb
nanovdb/nanovdb/examples/ex_make_funny_nanovdb
nanovdb/nanovdb/examples/ex_make_nanovdb_sphere
nanovdb/nanovdb/examples/ex_make_typed_grids
nanovdb/nanovdb/examples/ex_map_pool_buffer
nanovdb/nanovdb/examples/ex_modify_nanovdb_thrust
nanovdb/nanovdb/examples/ex_openvdb_to_nanovdb
nanovdb/nanovdb/examples/ex_openvdb_to_nanovdb_accessor
nanovdb/nanovdb/examples/ex_openvdb_to_nanovdb_cuda
nanovdb/nanovdb/examples/ex_raytrace_fog_volume
nanovdb/nanovdb/examples/ex_raytrace_level_set
nanovdb/nanovdb/examples/ex_read_nanovdb_sphere
nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor
nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor_cuda
nanovdb/nanovdb/examples/ex_util
nanovdb/nanovdb/examples/ex_vox_to_nanovdb
nanovdb/nanovdb/examples/ex_write_nanovdb_grids
nanovdb/nanovdb/unittest)
endif()
set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES DOXYGEN_PREDEFINED)
# Always add to build target (can't use USE_STAMP_FILE as we include
# complete directories in DOXY_FILES)
doxygen_add_docs(doc ${DOXY_FILES}
ALL WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Generating API documentation with Doxygen")
# Suppress "Installing..." messages for all but one of the hundreds of generated files.
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/html/index.html DESTINATION ${CMAKE_INSTALL_DOCDIR}/html)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR} MESSAGE_NEVER)
-2113
View File
File diff suppressed because it is too large Load Diff
-496
View File
@@ -1,496 +0,0 @@
/**
<div style="width:800px;text-align:justify;">
@page axcplusplus OpenVDB AX
@section axcdocs AX C++ Documentation
@par
The following documentation focuses on the C++ design and API of OpenVDB AX,
@b not the front end AX language. For the latter, see the
@ref ax "AX Language documentation". For more specific function API information,
search for the relevant function doxygen.
@note
These documents are actively being worked on and are subject to change. See the
API doxygen comments or contact us for more information.
@section vdbaxcontents Contents
- @ref vdbaxapiabi
- @ref vdbaxrepo
- @ref vdbaxgrammar
- @ref vdbaxast
- @ref vdbaxastscanners
- @ref vdbaxcompilerpipe
- @ref vdbaxcompilerlogging
- @ref vdbaxcompilerexe
- @ref vdbaxcompilercustomdata
- @ref vdbaxcodegen
- @ref vdbaxcompiler
- @ref vdbaxbinary
- @ref vdbaxtoaxtypes
- @ref vdbaxextend
<hr>
@section vdbaxapiabi Versioning, API and ABI
@par
AX is a self contained library which currently has a one way dependency on
OpenVDB; any downstream artifact that uses AX will need to build and link
against both OpenVDB and OpenVDB AX. There are a few important factors to be
aware of with this integration:
@par
- OpenVDB AX is tied to the OpenVDB library version. There is no explicit
OpenVDB AX version. This includes the OpenVDB namespaced API, the shared
library version suffix on relevant platforms and the OpenVDB ABI. It *may* be
possible to build OpenVDB AX against a different version of OpenVDB however
this is not explicitly supported.
- There are no ABI compatibility guarantees for OpenVDB AX components i.e. AX
components do not support the transfer of themselves as binary representations
across dynamic library boundaries to applications where AX has been compiled at
a different location in the OpenVDB repository. Support for this may change in
the future.
@par
In general, anything in the public namespace (defined as anything not labelled
"internal") comes with standard API guarantees; that is, classes and methods
will not change visible behaviour or signatures and deprecations will occur with
appropriate replacements (where necessary) prior to removal. However, due to the
nature of the project and its infancy, it's encouraged to continue reading below
into the relevant AX components. These provide a better description of their
intended public consumption and completeness.
<hr>
@section vdbaxrepo OpenVDB AX Repository
@par
The AX repository has been laid out using a modular design. Each subdirectory
encompasses a set of similar tools with a fairly consistent (one-way) dependency
diagram to other tools in the repository. The following provides a short
description of each directory, listed in this ad-hoc dependency order (from
highest to lowest):
@par
- @b grammar: Provides the flex/bison lexer/grammar rules for generating the
OpenVDB AX language, as well as the pre-generated `.c` files.
- @b ast: The definition of an AX Abstract Syntax Tree, its node types and
methods to work explicitly with them.
- @b compiler: The frontend C++ user interface for building and using AX.
- @b codegen: The backend LLVM IR code generation for AX.
@par
Additional tools include (in no particular order):
@par
- @b cmd: Command line binary tools for AX.
- @b math: Various mathematical methods, typically used by the AX
code generators when building native functions.
- @b test: Unit testing framework for AX.
@subsection vdbaxgrammar The Grammar
@par
The subdirectory @b grammar contains the rules used to generate an AX abstract
syntax tree, as defined by the @ref ax "AX Language specification." These files
do not provide an API per-se and are primarily used internally by the @b ast
module. The grammar syntax rules are specified in files with <b>.y</b> suffix
and the tokenziers are specified by the <b>.l</b> suffix. These files are designed
to work with two UNIX tools, GNU <A HREF="https://www.gnu.org/software/bison/manual/">
Bison</A> and <A HREF="https://westes.github.io/flex/manual/">Flex</A>. Together
these tools provide a workflow for developers to create develop a wide range of
language parsers. It's encouraged to visit the corresponding manuals for more
information on their use.
@par
The AX grammar is defined with a <A HREF="https://en.wikipedia.org/wiki/LR_parser">
LR parser</A>. In simplest terms, this means that the syntactical rules define a
grammar which is parsed bottom-up, left-to-right, deterministically and context
free (for the most part). These are fairly typical traits of parsers used to
define computer languages. The parser is @b not designed to be interactive, nor
reentrant (is not thread safe, each string is parsed sequentially) however such
limitations are not imposed by AX and may be removed in the future. Note that
the internal function symbols are correctly prefixed (with @b ax), so AX should
be compatible with other software that also uses Bison/Flex.
@par
The <b>.y</b> and <b>.l</b> files are typically not part of the normal build
process. Bison and Flex use them to generate compatible C/C++ code, however this
code is always pre-generated and provided with the AX repository within the
<b>grammar/generated</b> subdirectory. This C/C++ code is compiled into the AX
library. Thus, the grammar is provided for two reasons; to demonstrate how the
syntactical rules are implemented and to provide expert users the ability to
regenerate the C/C++ bindings (see @ref build "the build instructions").
Importantly, AX does not install any of the files in the grammar folder; the
parser is accessed through the @b ast module.
@subsection vdbaxast The AST
@par
The @b ast module provides:
- The complete implemenation of an @ref AST.h "AX abstract syntax tree"
- The openvdb::ax::ast::parse() method
- The @vdblink::ax::ast::Visitor AST Visitor@endlink
- AST scanners and tools
@par
All methods in this module are designed to work around an AX AST, which represents the
syntactical constructs of the AX language as a hierarchy of C++ objects (nodes).
The complete AST hierarchy is visualized by the @vdblink::ax::ast::Node doxygen
class graph for an openvdb::ax::ast::Node@endlink, which represents the top most
node in the AST. The AST API exists in a nested namespace (`openvdb::ax::ast`)
and can be used by clients for more granular control and modifications to an AST.
Importantly, the AST API contains the openvdb::ax::ast::parse() method, which
invokes the C/C++ functions built by the grammar to iteratively construct an
AST from a provided character string.
@par
A number of other tools are provided by the module to work with an AST such as
tools to re-interpret the AST back to AX compatible code, printing of the AST's
node hierarchy/layout and scanners which are able to query details from AST
branches. All these methods use the @vdblink::ax::ast::Visitor AX visitor
framework@endlink, a visitor pattern traversal class strongly influenced by
<A HREF="https://clang.llvm.org/doxygen/classclang_1_1RecursiveASTVisitor.html">
Clang's RecursiveVisitor</A>. Clients can use the AX visitor to implement their
own AST analysis or modifications (see @ref vdbaxextend).
@subsubsection vdbaxastscanners Scanners
@par
todo
@subsection vdbaxcompilerpipe The Compiler Pipeline
@par
The @b compiler subdirectory contains the bulk of the C++ API intended to be
used directly by clients of OpenVDB AX. It links together the grammar, AST and
code generation to produce AX executable objects, forming a pipeline from an
initial string of AX code to final execution across some geometry. The following
sections detail the core components to the Compiler pipeline.
@subsubsection vdbaxcompilerlogging Logging
@par
Anyone familiar with programming languages will undoubtedly be aware of the huge
variety and quantity of feedback that's presented to clients during use. This
information, when properly presented, can be invaluable and help to advise
users during their usage of the language. AX provides @vdblink::ax::Logger a
Logger class@endlink which can be used throughout the Compiler pipeline to
store and report this information. By default, this class reports all errors to
<A HREF="https://en.cppreference.com/w/cpp/io/cerr">std::cerr</A> and swallows
warnings, but can be customised depending on your needs e.g:
@par
@code{.cpp}
#include <openvdb_ax/compiler/Logger.h>
// Create a logger which sends errors and warnings to std::cerr
openvdb::ax::Logger
logs([](const std::string& msg) { std::cerr << msg << std::endl; },
[](const std::string& msg) { std::cerr << msg << std::endl; });
logs.setMaxErrors(5); // stop reporting after 5 errors
logs.setWarningsAsErrors(false); // don't count warnings as an error
logs.setPrintLines(true); // print code lines
logs.setNumberedOutput(true); // number each error/warning reported
@endcode
@par
A @vdblink::ax::Logger Logger@endlink should be passed to the relevant pipeline
methods as detailed in the following sections.
@subsubsection vdbaxcompilerexe Executables
@par
The "executable" terminology comes from the binary representation of the
compiled function which is invoked. AX executables essentially wrap the
generated function calls from the AX codegen with an efficient multi-threaded
invoke for the type of geometry being processed. The executable classes are
designed to be lightweight to store, modify and copy with a consolidated
interface for running and customising execution.
@par
There are two main types of executables; the @vdblink::ax::VolumeExecutable
VolumeExecutable@endlink, designed to work with all OpenVDB Volumes and the
@vdblink::ax::PointExecutable PointExecutable@endlink which works with OpenVDB
`PointDataGrids`. They are not expected to be created directly; instead these
objects are returned by the @vdblink::ax::Compiler AX Compiler@endlink depending
on the selected @vdblink::ax::Compiler::compile() Compiler::compile() @endlink
function.
@note
There is no inherent limitation to the design of the `VolumeExecutable` which
stops it working on `PointDataGrids` but it's not particular useful in it's
current form and can be confusing so it is explicitly disallowed.
@par
The executables are distinctly detached from the @vdblink::ax::Compiler
Compiler@endlink once they have been built and can be safely used no matter
previous or subsequent compilations of AX code. There are a variety of settings
on the executables to control runtime behaviour - below demonstrates an example
of using this API:
@par
@code{.cpp}
using namespace openvdb;
ax::Compiler compiler; // compiler
FloatGrid a;
a.setName("a");
a.tree().setValueOn({0,0,0}, 1.0f); // set single coordinate to active 1.0f
const ax::VolumeExecutable::Ptr exe1 =
compiler.compile<ax::VolumeExecutable>("f@a += 1.0f;");
exe1->execute(a); // run over active leaf voxels in parallel
ax::VolumeExecutable::Ptr exe2 =
compiler.compile<ax::VolumeExecutable>("f@a += 2.0f;");
// set to process all voxels
exe2->setValueIterator(ax::VolumeExecutable::IterType::ALL);
exe2->execute(a); // run over active and inactive leaf voxels in parallel
std::cout << a.tree().getValue({0,0,0}) << std::endl; // prints 4.0f
std::cout << a.tree().getValue({1,0,0}) << std::endl; // prints 2.0f
@endcode
@par Executable Thread Safety
The executables are responsible for launching the compiled AX kernels and may
internally use multiple threads. Multiple executables of any type can co-exist
and be executed concurrently with unique arguments. For example:
@par
@code{.cpp}
FloatGrid a1, a2; // assume both are named "a"
auto exe1 = compiler.compile<ax::VolumeExecutable>("f@a += 1.0f;");
auto exe2 = compiler.compile<ax::VolumeExecutable>("f@a += 2.0f;");
std::thread t1([&]() { exe1->execute(a1); } );
std::thread t2([&]() {
exe1->execute(a2); // safe even if exe1::execute is being used by another thread
exe2->execute(a2); // safe, can be running alongside another executable
});
@endcode
@par
This is, however, only safe depending on the access pattern of the AX code, the
iteration patterns of the executables and the grid data being fed to the
`execute` methods. When we talk about the thread safety of these classes we are
referring to the invocation of their execution method <b>with the same argument
data</b> by multiple threads, @b not how many threads the executables themselves
use (which can be configured by the `grainSize()` setting). Importantly, for a
given VDB grid or VDB Points attribute <b>"foo"</b>:
- For The @vdblink::ax::VolumeExecutable VolumeExecutable@endlink it is safe to
call @vdblink::ax::VolumeExecutable VolumeExecutable::execute@endlink @b from
multiple threads only if:
- All relevant AX kernels <b>do not write</b> to grid @b foo.
- For The @vdblink::ax::PointExecutable PointExecutable@endlink it is safe to
call @vdblink::ax::PointExecutable PointExecutable::execute@endlink @b from
multiple threads only if:
- All relevant AX kernels <b>do not write</b> to attribute @b foo.
- All relevant AX kernels <b>do not create</b> any attributes or groups.
- All relevant AX kernels <b>do not modify</b> the @b position "P" attribute.
@par
For example:
@par
@code{.cpp}
auto exe = compiler.compile<ax::VolumeExecutable>("@a = @b");
// Grid a1 and a2 called "a", b called "b". Grid b is given to both threads.
// This is safe as we guarantee b is only read from
std::thread t1([&]() { GridPtrVec v{a1,b}; exe1->execute(v); } );
std::thread t2([&]() { GridPtrVec v{a2,b}; exe1->execute(v); } );
@endcode
@par
You can use the tools provided in @ref Scanners.h to query data accesses on
AX ASTs to verify access patterns of your data.
@subsubsection vdbaxcompilercustomdata Custom Data
@par
The AX language provides two main tokens to access memory which has not been
allocated by AX itself. The first token, @b \@ (the "at" symbol), is designed to
provide read/write access to geometry attributes. The second token is the dollar
character @b $. This allows <b>read only</b> access to custom data that can be
modified in C++ i.e. outside the scope of an AX program. In the same way as the
@b \@attribute syntax, the value of this data can change without the need for AX
to re-compile the program. It is, however, solely on the C++ clients of AX to
make sure that this data is setup correctly when integrating AX into their
applications.
@par
Consider this trivial example:
@par
<!-- A -->@code{.c}
f@density = f$my_value;
// f$my_value = f@density; NOTE: writing to $ values is disallowed
@endcode
@par
When compiled, this program will attempt to read a single float type value with
the storage name "my_value". If the value cannot be found, a zero intialized
block of memory (with size of the desired type) is returned. So, with no further
setup, this will assign each value of @b density to 0.0f.
@par
The @vdblink::ax::CustomData CustomData@endlink class provides the intermediary
storage for this data between the code generation and the compiler. Clients
should use this API to create and modify custom data which will become available
to AX programs. Although the data is stored as abstract openvdb::Metadata
objects, the values are embedded into AX programs as pointers to their location
in memory. In practice this means that accessing data stored in this way is
almost as fast as accessing an AX local variable, though certain optimizations,
such as constant folding, will not apply. As previously mentioned, this also
means that the AX program does not need to be recompiled should this value need
to be changed.
@par
The @vdblink::ax::CustomData CustomData@endlink starts off detached from an
executable and thus must be provided when invoking
@vdblink::ax::Compiler::compile Compiler::compile()@endlink. It is then tied to
the AX executable for its duration. The compiler will validate the types of
all accessed data of an AX program and, if it does not exist, the data will be
created. Note that multiple executables can access the same
@vdblink::ax::CustomData CustomData@endlink instance.
@par
@code{.cpp}
using namespace openvdb;
FloatGrid density;
density.setName("density");
ax::Compiler compiler; // compiler
ax::CustomData::Ptr data(new ax::CustomData); // empty custom data
// data provided to compile is now registered with this exe. "m_value" is created
ax::VolumeExecutable::Ptr exe =
compiler.compile<ax::VolumeExecutable>("f@density = f$my_value;", data);
exe->execute(density); // my_value doesn't exist, density set to 0.0f
// Compiler::compile will have created this
assert(data->hasValue<TypedMetadata<float>>("my_value"));
// get the data in its typed storage wrapper
TypedMetadata<float>* meta = data->getValue<TypedMetadata<float>>("my_value");
meta->set(1.0f); // set the value of "my_value" to 1.0f
// don't need to re-compile
exe->execute(density); // density set to 1.0f
@endcode
@warning
Care should be taken to ensure that modifications to custom data values are
peformed outside of any calls to `execute()`. Any attempt to modify the data
whilst executables attempt to access it will result in undefined behaviour.
@subsubsection vdbaxcodegen Codegen
@par
todo
@subsubsection vdbaxcompiler The Compiler
@par
The @vdblink::ax::Compiler Compiler@endlink brings together the above
components. It is responsible setting up LLVM contexts and modules for a given
AX program, invoking the compute generators, binding custom data, performing any
necessary AX and LLVM optimisations and finally JIT compiling the program to a
callable function. The @vdblink::ax::Compiler::compile() Compiler::compile()
@endlink member functions execute the aforementioned steps and, if successful,
return a pointer to an executable.
@par
There are two main ways to invoke compilation; one with an @vdblink::ax::Logger
AX Logger@endlink and one without. The prior will either return a valid pointer
to a generated executable on success or a `nullptr` on failure. It is guaranteed
to never throw a code generation runtime error and expects the caller to either
query or setup the state of the logger to handle warnings and errors. The latter
internally creates a default logger which swallows warnings and prints all
possible errors to `std::cerr`. Note that the latter will throw a runtime error
on failure and is thus guaranteed to never return a `nullptr`.
@par
@code{.cpp}
using namespace openvdb;
ax::Compiler compiler;
std::vector<std::string> warn, err;
// custom logger to collect warnings and errors
ax::Logger logger(
[&warn]() { warn.emplace_back(msg); },
[&err]() { err.emplace_back(msg); }
);
// logger provided, exe could be null if input is invalid
auto exe = compiler.compile<ax::VolumeExecutable>("f@a = 1.0f;", logger);
// print warnings
for (cosnt auto& msg : warn) std::cout << msg << std::endl;
if (!exe) {
for (cosnt auto& msg : err) std::cout << msg << std::endl;
}
// without logger, divison by zero warning won't be reported
exe = compiler.compile<ax::VolumeExecutable>("f@a = 1.0f / 0.0f;");
// without logger, invalid AX will cause a runtime error but
// also print errors to std::cerr
try {
exe = compiler.compile<ax::VolumeExecutable>("foo");
}
catch (...) {
std::cerr << "See above error logs..." << std::endl;
}
@endcode
@warning
A single instance of the @vdblink::ax::Compiler AX Compiler@endlink uses a
uniquely constructed <A HREF="https://llvm.org/doxygen/classllvm_1_1LLVMContext.html">
LLVMContext</A>. This context is @b shared between copies of the Compiler,
however new Compilers create new LLVMContexts. It is therefor unsafe to invoke
concurrent calls to @vdblink::ax::Compiler::compile() Compiler::compile()
@endlink on Compilers which share the same underlying LLVMContext.
@par
@code{.cpp}
ax::Compiler C1, C2;
// @warning Not safe!
// std::thread t1([&]() { C1.compile<ax::VolumeExecutable>("@a;") } );
// std::thread t2([&]() { C1.compile<ax::VolumeExecutable>("@b;") } );
// the following is safe as C1 and C2 are unique instances
std::thread t1([&]() { C1.compile<ax::VolumeExecutable>("@a;") } );
std::thread t2([&]() { C2.compile<ax::VolumeExecutable>("@a;") } );
@endcode
@subsection vdbaxbinary The Command Line Binary
@par
todo
<hr>
@section vdbaxtoaxtypes OpenVDB / OpenVDB AX Types
@par
Whilst OpenVDB AX is primarily designed for OpenVDB, it has its own notion of
types. This is so that the actual AX language is able to support arithmetic that
OpenVDB geometry would perhaps otherwise not support. For example, AX supports
3x3 and 4x4 matrix types. These types are akin to the `openvdb::math::Mat` types
that exist in OpenVDB library - however, historically, these types are not
"registered Grid types" by default by OpenVDB. This means that, although you
could theoretically create an `openvdb::Mat3dGrid` OpenVDB may not support the
reading or writing of these grid types out the box. Whilst this may change in
the future, there may exist other examples of types in AX which suffer from the
same limitation of existing geometry types in OpenVDB.
@par
Native OpenVDB types are types which are @b a) registered for serialization and
@b b) compilable by the default C++ installation of OpenVDB. This is a bit
convoluted, so what does this actually mean in practice? Generally, accessing an
@b attribute in AX requires that data to exist on the underlying geometry. As
such, reading or writing to a given attribute (for example `bool@myattr`)
requires both the AX compiler @b and the underlying geometry to support the
given type. As mentioned above, there may be times where this isn't the case.
Consider the following:
@par
<!-- A -->@code{.c}
vec4i a = {1,2,3,4};
vec4i@attr = a;
@endcode
@par
Now lets assume that a notion of four `int32` values is not supported for
serialization of OpenVDB points or volumes (we assume the type can at least be
instantiated). Whilst this code may execute, serializing this data to disk may
fail due to unregistered OpenVDB types. AX does @b not register any additional
OpenVDB types. This choice is left to downstream software. In this example, to
allow for serialization of `vec4` types, some variant of the following can be
implemented in your application.
@warning
The choice to register Grid types in OpenVDB is left to the OpenVDB maintainers.
There are important consequences to registering custom types - other default
installations of OpenVDB <b>will not be able to read your files</b> unless
compiled with similar instantiations.
@par
@code{.cpp}
openvdb::initialize(); // standard init of vdb
openvdb::ax::initialize(); // standard init of ax
// Define a Vec4I grid type from the openvdb::math::Vec4<int32_t> class.
// Use a ValueConverter to ensure the grid has the same configuration as
// a standard OpenVDB grid type.
using Vec4IGrid = openvdb::BoolGrid::ValueConverter<openvdb::Vec4I>::Type;
// register this type
Vec4IGrid::registerGrid();
@endcode
<hr>
@section vdbaxextend Extending OpenVDB AX
<!--@subsection vdbaxcustomtraversal Custom AST Traversal-->
<!--@subsection vdbaxcustomtraversal Designing an Executable-->
<!--@subsection vdbaxcustomtraversal Geometry Callbacks-->
<!--@subsection vdbaxcustomtraversal Custom Code Generation-->
</div>
*/
-267
View File
@@ -1,267 +0,0 @@
/**
<div style="width:800px;text-align:justify;">
@page axexamples AX Code Examples
@section axexamplesintro AX Code Examples
@par
This page demonstrates a range of examples which use AX to manipulate OpenVDB
point and volume data and can be used as a quick start demonstration on the
capabilities of the software. These examples are constantly being updated but
do not cover all aspects of AX!
@section axexamplecontents Contents
- @ref axexamplepoints
- @ref axexamplepointbasic
- @ref axexamplepointdelete
- @ref axexamplepointdrag
- @ref axexamplepointcurlnoise
- @ref axexamplepointtransforms
- @ref axexamplevolumes
- @ref axexamplevolumeclamp
- @ref axexamplevolumevel
- @ref axexamplevolumeblend
@section axexamplepoints Points Examples
@par
These examples demonstrate how to use AX on OpenVDB points grids.
@subsection axexamplepointbasic Basic point attributes
@par
Below is a small example which demonstrates working with a few point attributes.
The @ symbol is the identifier for an AX attribute. The type of each attribute
is specified before the @ symbol and the name is specified afterwards. For
example: @b `int\@count` would imply an @b integer attribute called @b count.
@par
In this example there are three point attributes: a @b float attribute @b speed,
a @b vec3f float attribute @b velocity and a @b vec3f float attribute @b colour.
@par
This snippet uses the functions @ref axlength "length" and @ref axfit "fit" to
give points a colour between black and white based on their speed.
@par
<!-- P -->@code{.c}
// This statement writes to a new float attribute called speed and reads from a
// vector float attribute called velocity. The length function is used here to
// return the length of the point's velocity vector.
float@speed = length(vec3f@velocity);
// Points that move faster than this threshold will all be mapped to the same
// colour (white).
float fast_threshold = 6.f;
// Writing a single value to a vector will mean that all components of the
// vector are assigned the same value.
vec3f@colour = fit(float@speed, 0, fast_threshold, 0, 1);
@endcode
@par
The @b velocity attribute in this example is assumed to exist and have a range
of values to produce some visual variance in colour. The attributes @b speed and
@b colour do not need to exist before this snippet is run as the attributes are
only written to and will be created on the fly.
@par
@note
In Houdini (AX SOP) changing the name of the attribute from @b colour to @b Cd
will result in the points being given a colour in the viewport as Cd is a
special attribute.
@subsection axexamplepointdelete Deleting Points
@par
This example demonstrates a simple way of removing points from a VDB points grid.
It uses a combination of @ref axrand and @ref axdeletepoint to randomly delete
roughly half of the points in the input VDB points grid.
@par
<!-- P -->@code{.c}
float threshold = 0.5f;
// The rand function takes a seed and produces a random value between 0 and 1.
// The integer attribute id from the points is used to seed the rand function.
// If the value from rand is greater than the threshold (0.5) then delete the point.
if (rand(int64@id) > threshold) {
deletepoint();
}
@endcode
@par
The @b id attribute in this example is assumed to be a unique @b integer for
each point in the VDB points grid such that @ref axrand will receive a
different seed value per point producing a good distribution of random values.
@subsection axexamplepointdrag Applying Drag
@par
This example shows something a bit more complex: modifying a point's velocity
with a drag force and then moving the point with the modified velocity.
@par
<!-- P -->@code{.c}
float dt = 1.0f / (4.0f * 24.0f); // timestep
vec3f gravity = {0.0f, -9.81f, 0.0f}; // gravity
vec3f dV = {2.0f, 0.0f, 0.0f} - v@v; // drag
float lengthV = length(dV);
float Re = lengthV * @rad / 1.225f;
float C = 0.0f;
if (Re > 1000.0f) C = 24.0f / Re;
else C = 0.424f;
// calculate drag force
vec3f drag = 0.5f * 1.2f * C * lengthV * dV * 4.0f * 3.14f * pow(@rad, 2.0f);
// update velocity
v@v += (gravity - drag / ((4.0f / 3.0f) * 3.14f * pow(@rad, 3.0f))) * dt;
// update position
v@P += v@v * dt;
@endcode
@par
The final AX command, `v@P += v@v * dt;` writes to the position attribute of
the points @b `v\@P`. Whenever position is written to in this way, the AX
`PointExecutable` will move (re-bucket) points in PointDataGrids.
@subsection axexamplepointcurlnoise Curl Noise
@par
The following example demonstrates using various native AX functions to
calculate a position based curl noise on points in a particular group, and to
use that calculation to update point velocities.
@par
<!-- P -->@code{.c}
// Only calcualte noise and apply it to points if the current point is NOT in
// a group called "escaped". Note that the PointExecutable also has native
// support for group based execution.
if (!ingroup("escaped")) {
// Read custom data
float amplitude = $amplitude;
float persistence = $persistence;
float lacunarity = $lacunarity;
vec3f freq = vec3f$frequency;
vec3f offset = vec3f$offset;
vec3f noise = 0.0f;
// Position based curl simplex noise
for (int octave = 0; octave < int($octaves); ++octave) {
vec3f noisePos = vec3f@P * freq + offset;
noise += curlsimplexnoise(noisePos) * amplitude;
amplitude *= persistence;
freq *= lacunarity;
}
// Apply noise scaled by the current velocity length
vec3f@v += length(vec3f@v) * noise;
}
@endcode
@subsection axexamplepointtransforms Transformations
@par
AX supports 3x3 and 4x4 matrix types and various transformations. They can be
accessed via row, column operators or as a flat array and have defined
operators (such as matrix multiplication etc.). The following demonstrates
some trivial matrix math on VDB Point positions.
@par
<!-- P -->@code{.c}
// get the 4x4 identity matrix. note that scalar->matrix promotion handles
// this, so writing 'mat4f transform = 1;' has the same effect.
mat4f transform = identity4();
// set the X transform component
transform[3,0] = 5;
// pre scale the matrix. this is equal to writing: 'transform = scale * transform;'
vec3f scale = { 1,2,3 };
prescale(transform, scale);
// double the value of the scale Y component
transform[5] *= 2;
// construct a basic rotation matrix, representing 90 degree rotation around Y
float degrees = 90.0f;
float rad = radians(degrees);
mat3f rotation = {
cos(rad), 0.0f, -sin(rad),
0.0f, 1.0f, 0.0f,
sin(rad), 0.0f, cos(rad)
};
// apply the rotation and transformation to the current points position
vec3f@P *= rotation;
vec3f@P *= transform;
@endcode
<br/><hr>
@section axexamplevolumes Volume Examples
@par
These examples demonstrate how to use AX on VDB volume grids.
@subsection axexamplevolumeclamp Volume Clamping
@par
Below is a small example of reading adn writing to voxels within a VDB volume.
As with points, the @ symbol specifies an access to a named volume, with the
type of each volume preceding it and the name appearing as a suffix. For
example: `float@density` would imply a @b float volume called @b density.
@par
This snippet uses @ref axclamp function to constrain the @b density attribute
between zero and one.
@par
<!-- V -->@code{.c}
float@density = clamp(float@density, 0.f, 1.f);
@endcode
@subsection axexamplevolumevel Velocity Update
@par
AX can be used to read and write to multiple volumes. Here we have a typical
example of a eulerian velocity update which takes into account an updated
vector force and scalar mass.
@par
<!-- V -->@code{.c}
// Access the current timestep - this could instead be provided by the AX
// integration and made accessible with custom data (i/e: float$timestep)
float dt = 1.0f / 24.0f;
// read from the mass grid the corresponding (matching index space) value
float mass = float@mass;
// safe divide, in case mass is zero
float massInverse = 0.0f;
if (mass > 0.0f) massInverse = 1.0f / mass;
// update the current velocity value by scaling the corresponding force
// by the timestep and inverse mass
vec3f@vel += dt * massInverse * vec3f@force;
@endcode
@subsection axexamplevolumeblend Linear Blending
@par
Here we demonstrate how AX can be used to blend two volumes together. Note that
only the volumes which are written to are executed over. In the below code,
only @b `\@surface_a` is written to. This means that the final blended result,
stored in `surface_a`, will only be updated in `surface_a`'s topology. Should
we want a combined blend of @b non @b overlapping areas of both surface a and b,
we would need to activate a's topology with respect to b first.
@par
<!-- V -->@code{.c}
// time constants for each run.
float time = float$time;
float maxDuration = 100.0f;
// read both surface a and surface b values
float a = @surface_a; // source value
float b = @surface_b; // target value
// calculate the fractional mask value in respect to time
float mask = time / maxDuration;
// optionally scale the mask by a per index space density. if
// $enable_density_mask is true, a density grid is used to vary the blend per
// voxel
if ($enable_density_mask) mask *= @density;
// finally, clamp the mask value and update the level set value in surface a.
// Note that this may produce a no longer valid level set and might need to be
// rebuilt!
mask = clamp(mask, 0.0f, 1.0f);
@surface_a = a + (b-a) * mask;
@endcode
</div>
*/
-886
View File
@@ -1,886 +0,0 @@
/**
<div style="width:800px;text-align:justify;">
@page axfunctionlist AX Supported Functions
This page holds the full list of functions currently supported by AX. It is
usually automatically updated from the most recent output of the @ref vdbaxbinary
"vdb_ax binary's" function option.
@section axfunccontents Functions
<ul style="height: 500px; display:flex; flex-direction:column; flex-wrap:wrap;">
<li> @ref axabs "abs"</li>
<li> @ref axacos "acos"</li>
<li> @ref axacosh "acosh"</li>
<li> @ref axaddtogroup "addtogroup"</li>
<li> @ref axadjoint "adjoint"</li>
<li> @ref axargsort "argsort"</li>
<li> @ref axasin "asin"</li>
<li> @ref axasinh "asinh"</li>
<li> @ref axatan "atan"</li>
<li> @ref axatan2 "atan2"</li>
<li> @ref axatanh "atanh"</li>
<li> @ref axatof "atof"</li>
<li> @ref axatoi "atoi"</li>
<li> @ref axcbrt "cbrt"</li>
<li> @ref axceil "ceil"</li>
<li> @ref axclamp "clamp"</li>
<li> @ref axcofactor "cofactor"</li>
<li> @ref axcos "cos"</li>
<li> @ref axcosh "cosh"</li>
<li> @ref axcross "cross"</li>
<li> @ref axcurlsimplexnoise "curlsimplexnoise"</li>
<li> @ref axdegrees "degrees"</li>
<li> @ref axdeletepoint "deletepoint"</li>
<li> @ref axdeterminant "determinant"</li>
<li> @ref axdiag "diag"</li>
<li> @ref axdot "dot"</li>
<li> @ref axeuclideanmod "euclideanmod"</li>
<li> @ref axexp "exp"</li>
<li> @ref axexp2 "exp2"</li>
<li> @ref axexternal "external"</li>
<li> @ref axexternalv "externalv"</li>
<li> @ref axfabs "fabs"</li>
<li> @ref axfit "fit"</li>
<li> @ref axfloor "floor"</li>
<li> @ref axfloormod "floormod"</li>
<li> @ref axgetcoordx "getcoordx"</li>
<li> @ref axgetcoordy "getcoordy"</li>
<li> @ref axgetcoordz "getcoordz"</li>
<li> @ref axgetvoxelpws "getvoxelpws"</li>
<li> @ref axhash "hash"</li>
<li> @ref axidentity3 "identity3"</li>
<li> @ref axidentity4 "identity4"</li>
<li> @ref axingroup "ingroup"</li>
<li> @ref axinverse "inverse"</li>
<li> @ref axisfinite "isfinite"</li>
<li> @ref axisinf "isinf"</li>
<li> @ref axisnan "isnan"</li>
<li> @ref axlength "length"</li>
<li> @ref axlengthsq "lengthsq"</li>
<li> @ref axlerp "lerp"</li>
<li> @ref axlog "log"</li>
<li> @ref axlog10 "log10"</li>
<li> @ref axlog2 "log2"</li>
<li> @ref axmax "max"</li>
<li> @ref axmin "min"</li>
<li> @ref axnormalize "normalize"</li>
<li> @ref axpolardecompose "polardecompose"</li>
<li> @ref axpostscale "postscale"</li>
<li> @ref axpow "pow"</li>
<li> @ref axprescale "prescale"</li>
<li> @ref axpretransform "pretransform"</li>
<li> @ref axprint "print"</li>
<li> @ref axradians "radians"</li>
<li> @ref axrand "rand"</li>
<li> @ref axrand32 "rand32"</li>
<li> @ref axremovefromgroup "removefromgroup"</li>
<li> @ref axround "round"</li>
<li> @ref axsign "sign"</li>
<li> @ref axsignbit "signbit"</li>
<li> @ref axsimplexnoise "simplexnoise"</li>
<li> @ref axsin "sin"</li>
<li> @ref axsinh "sinh"</li>
<li> @ref axsort "sort"</li>
<li> @ref axsqrt "sqrt"</li>
<li> @ref axtan "tan"</li>
<li> @ref axtanh "tanh"</li>
<li> @ref axtrace "trace"</li>
<li> @ref axtransform "transform"</li>
<li> @ref axtranspose "transpose"</li>
<li> @ref axtruncatemod "truncatemod"</li>
</ul><hr>
@anchor axabs
@par abs
Computes the absolute value of an integer number.
@code{.c}
int64(int64 n);
int32(int32 n);
double(double n);
float(float n);
@endcode
@anchor axacos
@par acos
Computes the principal value of the arc cosine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axacosh
@par acosh
Computes the inverse hyperbolic cosine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axaddtogroup
@par addtogroup
Add the current point to the given group name, effectively setting its membership to true. If the
group does not exist, it is implicitly created. This function has no effect if the point
already belongs to the given group.
@code{.c}
void(string);
@endcode
@anchor axadjoint
@par adjoint
Returns the adjoint of a 3x3 matrix. That is, the transpose of its cofactor matrix.
@code{.c}
mat3d(mat3d input);
mat3f(mat3f input);
@endcode
@anchor axargsort
@par argsort
Returns a vector of the indexes that would sort the input vector.
@code{.c}
vec3i(vec3d v);
vec3i(vec3f v);
vec3i(vec3i v);
vec4i(vec4d v);
vec4i(vec4f v);
vec4i(vec4i v);
@endcode
@anchor axasin
@par asin
Computes the principal value of the arc sine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axasinh
@par asinh
Computes the inverse hyperbolic sine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axatan
@par atan
Computes the principal value of the arc tangent of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axatan2
@par atan2
Computes the arc tangent of y/x using the signs of arguments to determine the correct quadrant.
@code{.c}
double(double y; double x);
float(float y; float x);
@endcode
@anchor axatanh
@par atanh
Computes the inverse hyperbolic tangent of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axatof
@par atof
Parses the string input, interpreting its content as a floating point number and returns its value
as a double.
@code{.c}
double(i8* str);
@endcode
@anchor axatoi
@par atoi
Parses the string input interpreting its content as an integral number, which is returned as a value
of type int.
@code{.c}
int32(i8* str);
@endcode
@anchor axcbrt
@par cbrt
Computes the cubic root of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axceil
@par ceil
Computes the smallest integer value not less than arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axclamp
@par clamp
Clamps the first argument to the minimum second argument value and maximum third argument value
@code{.c}
double(double in; double min; double max);
float(float in; float min; float max);
int64(int64 in; int64 min; int64 max);
int32(int32 in; int32 min; int32 max);
@endcode
@anchor axcofactor
@par cofactor
Returns the cofactor matrix of a 3x3 matrix. That is, the matrix of its cofactors.
@code{.c}
mat3d(mat3d input);
mat3f(mat3f input);
@endcode
@anchor axcos
@par cos
Computes the cosine of arg (measured in radians).
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axcosh
@par cosh
Computes the hyperbolic cosine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axcross
@par cross
Returns the length of the given vector
@code{.c}
vec3d(vec3d a; vec3d b);
vec3f(vec3f a; vec3f b);
vec3i(vec3i a; vec3i b);
@endcode
@anchor axcurlsimplexnoise
@par curlsimplexnoise
Generates divergence-free 3D noise, computed using a curl function on Simplex Noise.
@code{.c}
vec3d(vec3d pos);
vec3d(double pos; double; double);
@endcode
@anchor axdegrees
@par degrees
Converts the number of radians to degrees.
@code{.c}
double(double radians);
float(float radians);
@endcode
@anchor axdeletepoint
@par deletepoint
Delete the current point from the point set. Note that this does not stop AX execution - any
additional AX commands will be executed on the point and it will remain accessible until the
end of execution.
@code{.c}
void();
@endcode
@anchor axdeterminant
@par determinant
Returns the determinant of a matrix.
@code{.c}
double(mat3d mat);
float(mat3f mat);
double(mat4d mat);
float(mat4f mat);
@endcode
@anchor axdiag
@par diag
Create a diagonal matrix from a vector, or return the diagonal components of a matrix as a vector.
@code{.c}
vec3d(mat3d vec);
vec3f(mat3f vec);
vec4d(mat4d vec);
vec4f(mat4f vec);
mat3d(vec3d mat);
mat3f(vec3f mat);
mat4d(vec4d mat);
mat4f(vec4f mat);
@endcode
@anchor axdot
@par dot
Computes the dot product of two vectors.
@code{.c}
double(vec3d a; vec3d b);
float(vec3f a; vec3f b);
int32(vec3i a; vec3i b);
@endcode
@anchor axeuclideanmod
@par euclideanmod
Euclidean modulo, where by the result of the division operator on (dividend / divisor) is floored or
ceiled depending on its sign, guaranteeing that the return value is always positive. The
remainder is thus calculated with D - d * (d < 0 ? ceil(D/d) : floor(D/d)). This is NOT equal
to a%b in AX. See truncatemod(), floormod().
@code{.c}
double(double dividend; double divisor);
float(float dividend; float divisor);
int64(int64 dividend; int64 divisor);
int32(int32 dividend; int32 divisor);
@endcode
@anchor axexp
@par exp
Computes e (Euler's number, 2.7182818...) raised to the given power arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axexp2
@par exp2
Computes 2 raised to the given power arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axexternal
@par external
Find a custom user parameter with a given name of type 'float' in the Custom data provided to the AX
compiler. If the data can not be found, or is not of the expected type 0.0f is returned.
@code{.c}
float(string str);
@endcode
@anchor axexternalv
@par externalv
Find a custom user parameter with a given name of type 'vector float' in the Custom data provided to
the AX compiler. If the data can not be found, or is not of the expected type { 0.0f, 0.0f,
0.0f } is returned.
@code{.c}
vec3f(string str);
@endcode
@anchor axfabs
@par fabs
Computes the absolute value of a floating point value arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axfit
@par fit
Fit the first argument to the output range by first clamping the value between the second and third
input range arguments and then remapping the result to the output range fourth and fifth
arguments
@code{.c}
double(double value; double omin; double omax; double nmin; double nmax);
float(float value; float omin; float omax; float nmin; float nmax);
double(int64 value; int64 omin; int64 omax; int64 nmin; int64 nmax);
double(int32 value; int32 omin; int32 omax; int32 nmin; int32 nmax);
@endcode
@anchor axfloor
@par floor
Computes the largest integer value not greater than arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axfloormod
@par floormod
Floored modulo, where the result of the division operator on (dividend / divisor) is floored. The
remainder is thus calculated with D - d * floor(D/d). This is the implemented modulo % operator
of AX. This is equal to the python % implementation. See trucnatemod(), euclideanmod().
@code{.c}
double(double dividend; double divisor);
float(float dividend; float divisor);
int64(int64 dividend; int64 divisor);
int32(int32 dividend; int32 divisor);
@endcode
@anchor axgetcoordx
@par getcoordx
Returns the current voxel's X index value in index space as an integer.
@code{.c}
int32();
@endcode
@anchor axgetcoordy
@par getcoordy
Returns the current voxel's Y index value in index space as an integer.
@code{.c}
int32();
@endcode
@anchor axgetcoordz
@par getcoordz
Returns the current voxel's Z index value in index space as an integer.
@code{.c}
int32();
@endcode
@anchor axgetvoxelpws
@par getvoxelpws
Returns the current voxel's position in world space as a vector float.
@code{.c}
vec3f();
@endcode
@anchor axhash
@par hash
Return a hash of the provided string.
@code{.c}
int64(string str);
@endcode
@anchor axidentity3
@par identity3
Returns the 3x3 identity matrix
@code{.c}
mat3f();
@endcode
@anchor axidentity4
@par identity4
Returns the 4x4 identity matrix
@code{.c}
mat4f();
@endcode
@anchor axingroup
@par ingroup
Return whether or not the current point is a member of the given group name. This returns false if
the group does not exist.
@code{.c}
bool(string);
@endcode
@anchor axinverse
@par inverse
Return the inverse of a 3x3 matrix.If the matrix is singular, returns the input matrix.
@code{.c}
mat3d(mat3d input);
mat3f(mat3f input);
@endcode
@anchor axisfinite
@par isfinite
Returns whether the value is finite i.e. not infinite or NaN. For matrix and vector types will
return false if any element is not finite.
@code{.c}
bool(vec2d);
bool(vec2f);
bool(vec3d);
bool(vec3f);
bool(vec4d);
bool(vec4f);
bool(mat3f);
bool(mat3d);
bool(mat4f);
bool(mat4d);
bool(double arg);
bool(float arg);
@endcode
@anchor axisinf
@par isinf
Returns whether the value is inf. For matrix and vector types will return true if any element is
inf.
@code{.c}
bool(vec2d);
bool(vec2f);
bool(vec3d);
bool(vec3f);
bool(vec4d);
bool(vec4f);
bool(mat3f);
bool(mat3d);
bool(mat4f);
bool(mat4d);
bool(double arg);
bool(float arg);
@endcode
@anchor axisnan
@par isnan
Returns whether the value is NaN (not-a-number).
@code{.c}
bool(vec2d);
bool(vec2f);
bool(vec3d);
bool(vec3f);
bool(vec4d);
bool(vec4f);
bool(mat3f);
bool(mat3d);
bool(mat4f);
bool(mat4d);
bool(double arg);
bool(float arg);
@endcode
@anchor axlength
@par length
Returns the length of the given vector
@code{.c}
double(vec2d v);
float(vec2f v);
double(vec2i v);
double(vec3d v);
float(vec3f v);
double(vec3i v);
double(vec4d v);
float(vec4f v);
double(vec4i v);
@endcode
@anchor axlengthsq
@par lengthsq
Returns the squared length of the given vector
@code{.c}
double(vec2d v);
float(vec2f v);
int32(vec2i v);
double(vec3d v);
float(vec3f v);
int32(vec3i v);
double(vec4d v);
float(vec4f v);
int32(vec4i v);
@endcode
@anchor axlerp
@par lerp
Performs bilinear interpolation between the values. If the amount is outside the range 0 to 1, the
values will be extrapolated linearly. If amount is 0, the first value is returned. If it is 1,
the second value is returned. This implementation is guaranteed to be monotonic.
@code{.c}
double(double a; double b; double amount);
float(float a; float b; float amount);
@endcode
@anchor axlog
@par log
Computes the natural (base e) logarithm of arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axlog10
@par log10
Computes the common (base-10) logarithm of arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axlog2
@par log2
Computes the binary (base-2) logarithm of arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axmax
@par max
Returns the larger of the given values.
@code{.c}
double(double a; double b);
float(float a; float b);
int64(int64 a; int64 b);
int32(int32 a; int32 b);
@endcode
@anchor axmin
@par min
Returns the smaller of the given values.
@code{.c}
double(double a; double b);
float(float a; float b);
int64(int64 a; int64 b);
int32(int32 a; int32 b);
@endcode
@anchor axnormalize
@par normalize
Returns the normalized result of the given vector.
@code{.c}
vec3d(vec3d v);
vec3f(vec3f v);
vec3d(vec3i v);
vec4d(vec4d v);
vec4f(vec4f v);
vec4d(vec4i v);
@endcode
@anchor axpolardecompose
@par polardecompose
Decompose an invertible 3x3 matrix into its orthogonal (unitary) matrix and symmetric matrix
components. If the determinant of the unitary matrix is 1 it is a rotation, otherwise if it is
-1 there is some part reflection.
@code{.c}
bool(mat3d input; mat3d unitary; mat3d symmetric);
bool(mat3f input; mat3f unitary; mat3f symmetric);
@endcode
@anchor axpostscale
@par postscale
Post-scale a given matrix by the provided vector.
@code{.c}
void(mat4d transform; vec3d vec);
void(mat4f transform; vec3f vec);
@endcode
@anchor axpow
@par pow
Computes the value of the first argument raised to the power of the second argument.
@code{.c}
double(double base; double exp);
float(float base; float exp);
double(double base; int32 exp);
@endcode
@anchor axprescale
@par prescale
Pre-scale a given matrix by the provided vector.
@code{.c}
void(mat4d transform; vec3d vec);
void(mat4f transform; vec3f vec);
@endcode
@anchor axpretransform
@par pretransform
Return the transformed vector by transpose of this matrix. This function is equivalent to
pre-multiplying the matrix.
@code{.c}
vec3d(mat3d vec; vec3d mat);
vec3f(mat3f vec; vec3f mat);
vec3d(mat4d vec; vec3d mat);
vec3f(mat4f vec; vec3f mat);
vec4d(mat4d vec; vec4d mat);
vec4f(mat4f vec; vec4f mat);
@endcode
@anchor axprint
@par print
Prints the input to the standard output stream. Warning: This will be run for every element.
@code{.c}
void(double n);
void(float n);
void(int64 n);
void(int32 n);
void(string n);
void(vec2i n);
void(vec2f n);
void(vec2d n);
void(vec3i n);
void(vec3f n);
void(vec3d n);
void(vec4i n);
void(vec4f n);
void(vec4d n);
void(mat3f n);
void(mat3d n);
void(mat4f n);
void(mat4d n);
@endcode
@anchor axradians
@par radians
Converts the number of degrees to radians.
@code{.c}
double(double degrees);
float(float degrees);
@endcode
@anchor axrand
@par rand
Creates a random number based on the provided seed. The number will be in the range of 0 to 1. The
same number is produced for the same seed. Note that if rand is called without a seed the
previous state of the random number generator is advanced for the currently processing element.
This state is determined by the last call to rand() with a given seed. If rand is not called
with a seed, the generator advances continuously across different elements which can produce
non-deterministic results. It is important that rand is always called with a seed at least once
for deterministic results.
@code{.c}
double();
double(double seed);
double(int64 seed);
@endcode
@anchor axrand32
@par rand32
Creates a random number based on the provided 32 bit seed. The number will be in the range of 0 to
1. The same number is produced for the same seed. NOTE: This function does not share the same
random number generator as rand(). rand32() may provide a higher throughput on some
architectures, but will produce different results to rand(). NOTE: If rand32 is called without
a seed the previous state of the random number generator is advanced for the currently
processing element. This state is determined by the last call to rand32() with a given seed. If
rand32 is not called with a seed, the generator advances continuously across different elements
which can produce non-deterministic results. It is important that rand32 is always called with
a seed at least once for deterministic results.
@code{.c}
double();
double(double seed);
double(int32 seed);
@endcode
@anchor axremovefromgroup
@par removefromgroup
Remove the current point from the given group name, effectively setting its membership to false.
This function has no effect if the group does not exist.
@code{.c}
void(string);
@endcode
@anchor axround
@par round
Computes the nearest integer value to arg (in floating-point format), rounding halfway cases away
from zero.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axsign
@par sign
Implements signum, determining if the input is negative, zero or positive. Returns -1 for a negative
number, 0 for the number zero, and +1 for a positive number. Note that this function does not
check the sign of floating point +/-0.0 values. See signbit().
@code{.c}
int32(double n);
int32(float n);
int32(int64 n);
int32(int32 n);
@endcode
@anchor axsignbit
@par signbit
Determines if the given floating point number input is negative. Returns true if arg is negative,
false otherwise. Will return true for -0.0, false for +0.0
@code{.c}
bool(double n);
bool(float n);
@endcode
@anchor axsimplexnoise
@par simplexnoise
Compute simplex noise at coordinates x, y and z. Coordinates which are not provided will be set to
0.
@code{.c}
double(double x);
double(double x; double y);
double(double x; double y; double z);
double(vec3d pos);
@endcode
@anchor axsin
@par sin
Computes the sine of arg (measured in radians).
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axsinh
@par sinh
Computes the hyperbolic sine of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axsort
@par sort
Returns the sorted result of the given vector.
@code{.c}
vec3d(vec3d v);
vec3f(vec3f v);
vec3i(vec3i v);
vec4d(vec4d v);
vec4f(vec4f v);
vec4i(vec4i v);
@endcode
@anchor axsqrt
@par sqrt
Computes the square root of arg.
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axtan
@par tan
Computes the tangent of arg (measured in radians).
@code{.c}
double(double n);
float(float n);
@endcode
@anchor axtanh
@par tanh
Computes the hyperbolic tangent of the input.
@code{.c}
double(double arg);
float(float arg);
@endcode
@anchor axtrace
@par trace
Return the trace of a matrix, the sum of the diagonal elements.
@code{.c}
double(mat3d mat);
float(mat3f mat);
double(mat4d mat);
float(mat4f mat);
@endcode
@anchor axtransform
@par transform
Return the transformed vector by the provided matrix. This function is equivalent to
post-multiplying the matrix, i.e. vec * mult.
@code{.c}
vec3d(vec3d vec; mat3d mat);
vec3f(vec3f vec; mat3f mat);
vec3d(vec3d vec; mat4d mat);
vec3f(vec3f vec; mat4f mat);
vec4d(vec4d vec; mat4d mat);
vec4f(vec4f vec; mat4f mat);
@endcode
@anchor axtranspose
@par transpose
Returns the transpose of a matrix
@code{.c}
mat3d(mat3d mat);
mat3f(mat3f mat);
mat4d(mat4d mat);
mat4f(mat4f mat);
@endcode
@anchor axtruncatemod
@par truncatemod
Truncated modulo, where the result of the division operator on (dividend / divisor) is truncated.
The remainder is thus calculated with D - d * trunc(D/d). This is equal to the C/C++ %
implementation. This is NOT equal to a%b in AX. See floormod(), euclideanmod().
@code{.c}
double(double dividend; double divisor);
float(float dividend; float divisor);
int64(int64 dividend; int64 divisor);
int32(int32 dividend; int32 divisor);
@endcode
</div>
*/
-47
View File
@@ -1,47 +0,0 @@
/**
<div style="width:800px;text-align:justify;">
@page openvdbax OpenVDB AX
@section axoverview Overview
@par
<b>OpenVDB AX</b> is an open source C++ library that provides a powerful and
easy way of interacting with OpenVDB volume and point data. The software strives
to provide a concise, fast, highly parallalisable and portable solution to
performing custom manipulation of OpenVDB data via an expression language: AX.
AX expressions are JIT-compiled and used in combination with a multi-threaded
execution framework, specifically designed for VDB, that in many cases rival
custom C++ operators.
@b OpenVDB AX is maintained by the
<A HREF="https://www.aswf.io/">Academy Software Foundation&nbsp;(ASWF)</A>.
It was originally developed at <A HREF="https://www.dneg.com/">DNEG</A>
primarily by:
- Nick Avramoussis
- Richard Jones
Other notable contributors include:
- Francisco Gochez
- Matthew Warner
- Dan Bailey
- Todd Keeler
- James Bird
- Harry Biddle
@subsection docs Documentation
@par
The doxygen documentation provide information on both AX as a language and the
developer documentation for OpenVDB AX as a C++ API. There are two main sections:
@par
- The @subpage ax "AX Language Documentation" provides useful information for front-end users looking for documentation on the AX Language.
- The @subpage axcplusplus "OpenVDB AX Documentation" provides API and other C++ specific software information for developers.
@par
Some additional quick links to useful subsections of the documentation are also
provided:
@par
- @subpage axexamples "Code Examples" for examples of OpenVDB AX in action.
- @subpage axfunctionlist "AX Functions" for a list of all available AX functions.
- @subpage build "Building OpenVDB" and @subpage dependencies "OpenVDB Dependencies" for information on building OpenVDB and <b>OpenVDB AX</b>.
</div>
*/
-72
View File
@@ -1,72 +0,0 @@
#!/bin/bash
BINARY=$1
if [ -z $BINARY ]; then
BINARY=vdb_ax
fi
echo $BINARY
# Generates a doxygen function.txt file using the available vdb_ax binary
# Add the doxygen header for the functions file
echo -n "/**
<div style=\"width:800px;text-align:justify;\">
@page axfunctionlist AX Supported Functions
This page holds the full list of functions currently supported by AX. It is
usually automatically updated from the most recent output of the @ref vdbaxbinary
\"vdb_ax binary's\" function option.
@section axfunccontents Functions
<ul style=\"height: 500px; display:flex; flex-direction:column; flex-wrap:wrap;\">
" > functions.txt
# 1) Create the contents list (reference links to each function)
# Get all the function names
$BINARY functions --list-names > tmp.txt
# Remove commans
tr -d , < tmp.txt > tmp2.txt
# Add new lines between names
tr ' ' '\n' < tmp2.txt > tmp.txt
# Remove empty lines (created by the vdb_ax binary wrapping output)
sed '/^$/d' tmp.txt > tmp2.txt
# Append doxygen references to each funciton
sed -e 's/^\(.*\)/\t<li> @ref ax\1 \"\1\"<\/li>/' tmp2.txt >> functions.txt
# End the function list and add a line break
echo -n "</ul><hr>
" >> functions.txt
# 2) Add all function descriptions and signatures from the binary
# First add a new line - this is for the next sed call which looks for a new
# line followed by the function name
echo "" > tmp.txt
$BINARY functions --list >> tmp.txt
echo "" >> tmp.txt
# look for functions such:
# \n
# functionname
# |
# and wrap the name in anchors and paragraphs
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/\n\([a-z0-9]\+\)\n|/\n@anchor ax\1\n@par \1/g' tmp.txt
# Remove all "| -" which exist before the function help
sed -i 's/| - //g' tmp.txt
# Replace |\n with @code{.c}
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/|\n/@code{.c}\n/g' tmp.txt
# Append semicolons to functions
sed -i 's/| - \(.*\)/\1;/g' tmp.txt
# Replace ;\n\n with ;\n:@endcode\n\n
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/;\n\n/;\n@endcode\n\n/g' tmp.txt
# Remove left over pipes
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/| //g' tmp.txt
# Combine
cat tmp.txt >> functions.txt
echo -n "</div>
*/" >> functions.txt
# cleanup
rm tmp.txt tmp2.txt
-103
View File
@@ -1,103 +0,0 @@
#!/bin/bash
BINARY=$1
if [ -z $BINARY ]; then
BINARY=vdb_ax
fi
# Generates a houdini html function file using the available vdb_ax binary
# Add the header for the file
echo -n "
<style>
.axsignature {
position: relative;
color: #888; }
.axname {
color: black; }
.axstring {
color: #c39c79; }
.axvec {
color: #8d31ae; }
.axmat {
color: #60bc8f; }
.axint {
color: #91a835; }
.axfloat {
color: #06C; }
.axdouble {
color: #06C; }
.axvoid {
color: #ccc; }
</style>
Function ||
Description ||
Signatures ||
" > functions.txt
# Echo out the full descriptions
echo "" > tmp.txt
$BINARY functions --list >> tmp.txt
echo "" >> tmp.txt
# Get a list of names
names=$($BINARY functions --list-names)
names="${names//$'\n'/}"
# For each line in the full function file, see which function we're processing
# and update each signature with the function name
found=""
new_data=""
while IFS= read -r line; do
# Scan for a function switch
for name in $names; do
name="${name//$','/}"
if [[ "$name" == "$line" ]]; then
found=$name
break
fi
done
# If processing a function signature, add the function name
if [[ $line == "| -"*"("* ]]; then
line=$(sed 's/(/'" $found"'(/g' <<<"$line")
fi
new_data+=$line"\n"
done < tmp.txt
echo -e "$new_data" > tmp.txt
# look for functions such:
# \n
# functionname
# |
# and wrap the name in code and format the end
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/\n\([a-z0-9]\+\)\n|/\n<p><code>\1<\/code><\/p> |/g' tmp.txt
# # Remove all "| -" which exist before the function help
sed -i 's/| - /\t/g' tmp.txt
# Replace pipes with tabs
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/| /\t/g' tmp.txt
# # # Replace |\n with " |\n"
sed -i -e ':a' -e 'N' -e '$!ba' -e 's/\n|\n/ |\n/g' tmp.txt
# # add usage sig
sed -i 's/| - \(.*\)/\t\t<div class="usage item"><code class="axsignature">\1<\/code><\/div>/g' tmp.txt
# Format parms
sed -i 's/\(void\)/<span class="axvoid">\1<\/span>/g' tmp.txt
sed -i 's/\(bool\)/<span class="axbool">\1<\/span>/g' tmp.txt
sed -i 's/\(int32\)/<span class="axint">\1<\/span>/g' tmp.txt
sed -i 's/\(int64\)/<span class="axint">\1<\/span>/g' tmp.txt
sed -i 's/\(float\)/<span class="axfloat">\1<\/span>/g' tmp.txt
sed -i 's/\(double\)/<span class="axdouble">\1<\/span>/g' tmp.txt
sed -i 's/\(string\)/<span class="axstring">\1<\/span>/g' tmp.txt
sed -i 's/\(vec[234][ifd]\)/<span class="axvec">\1<\/span>/g' tmp.txt
sed -i 's/\(mat[234][ifd]\)/<span class="axmat">\1<\/span>/g' tmp.txt
sed -i 's/ \([a-z]\+\)(/ <span class="axname">\1<\/span>(/g' tmp.txt
# Combine
cat tmp.txt >> functions.txt
# cleanup
rm tmp.txt
-672
View File
@@ -1,672 +0,0 @@
/**
@page build Building OpenVDB
@section buildContents Contents
- @ref buildIntroduction
- @ref buildCmakeStructure
- @ref buildDependencies
- @ref buildMixingDepInstalls
- @ref buildBloscSupport
- @ref buildZLibSupport
- @ref buildVCPKG
- @ref buildComponents
- @ref buildGuide
- @ref buildBuildTypes
- @ref buildBuildHouMaya
- @ref buildBuildHou
- @ref buildBuildMaya
- @ref buildBuildStandalone
- @ref buildUsingOpenVDB
- @ref buildTroubleshooting
<!-- - @ref buildContents -->
------------------------------------------------------------------------------
@section buildIntroduction Introduction
[CMake](https://cmake.org/) is a cross-platform family of tools designed to
help build software.
CMake doesn't *actually* build the project but instead generates the files
required for your toolchain, for example makefiles that serve as input to
[GNU Make](https://www.gnu.org/software/make/).
CMake support ensures a high level of
flexibility and pre-compile verification to the build process, making it much
easier to control and customize the installation process for a wider range of
platforms.
CMake also makes it easier to automatically find and handle dependencies.
If you're completely new to CMake, you may find it useful to read over the
brief [introduction to CMake](https://cmake.org/runningcmake/) and the CMake
structure section below. However the [build guide](@ref buildGuide) runs
through the build process step by step.
@section buildCmakeStructure CMake Structure
CMake will configure a set of build files which represent the commands and
dependencies for the OpenVDB components you wish to install. Finding and
handling these dependencies on different platforms comprises the majority
of the complexity involved in writing CMake. In general, software which uses
CMake is expected to provide their own configuration files which dependent
software will locate and use. Not all of OpenVDB's dependencies provide CMake
support and therefore do not deploy with CMake configurations that OpenVDB can
use. OpenVDB provides a set of `FindModules` in the `cmake` folder for finding
these various dependencies e.g. `FindBlosc.cmake`. These are designed such
that they can theoretically be used by any project that needs to locate the
given library and are invoked by the `find_package()` call. For more
information on FindModules and locating packages with CMake, see the following
CMake documentation:
- [Using Packages with CMake](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#using-packages)
- [Calling find_package()](https://cmake.org/cmake/help/latest/command/find_package.html)
The other type of file provided by OpenVDB are `OpenVDBSetupX.cmake` includes.
These are primarily designed to configure the building of OpenVDB components
against supported DCC's (Houdini/Maya) by locating their installations and
setting various CMake variables for subsequent `find_package()` dependency
calls. They also represent packages which already provide their own CMake
modules, but additionally provide the same input variable interface as OpenVDB's
other `Find` Modules.
@subsection buildDependencies Locating Dependencies
Each CMake FindModule provides a description of the possible inputs which can
be provided to help drive the search for OpenVDB dependencies (as well as the
resulting outputs). They have been homogenized such that these variables
follow a set convention, typically followed by most CMake projects. For a
given FindModule e.g. `FindBlosc.cmake`:
- FindXxx.cmake provides the module interface where Xxx becomes the library
name
- Invoked with the called `find_package( Xxx )`
.
- @b Inputs - The following variables can be used to help drive the search
path on first runs of CMake (i.e. these variables are not
[cached](https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry)).
They are listed in priority order. Note that the prefix is always capitalized.
- @b Xxx_ROOT - Preferred installation prefix. The given dependency is
expected to follow a folder structure `Xxx_ROOT/include` and `Xxx_ROOT/lib`
exist. Note that unlike the above, this is the case matching name of the
find package .i.e. Blosc_ROOT, TBB_ROOT etc.
- @b XXX_INCLUDEDIR / @b XXX_LIBRARYDIR - Preferred include and library
directories
- @b SYSTEM_LIBRARY_PATHS - A list of paths appended to all include and lib
searches.
- @b XXX_USE_STATIC_LIBS - Only search for static libraries for the given
dependency. If OFF, the shared library is prioritized, falling back
to the static library. This is OFF by default.
- @b DISABLE_CMAKE_SEARCH_PATHS - The above variables are custom to the
OpenVDB project. CMake itself implements its own search system to try and
find the given libraries and packages. When ON, this variable
disables CMake's inbuilt search, guaranteeing that only the above user
provided paths are searched. See [CMakes Search Procedure](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure)
for more information. This is OFF by default (and thus CMake's search
is enabled).
.
- @b Outputs The following variables are always set if the project is found:
- @b Xxx_FOUND - True if the headers and library was found and exists
- @b Xxx_VERSION - The library version
- @b Xxx_INCLUDE_DIRS - A list of paths to all required include directories
- @b Xxx_RELEASSE_LIBRARY_DIRS - A list of paths to all required release library directories
- @b Xxx_DEBUG_LIBRARY_DIRS - A list of paths to all required debug library directories
- @b Xxx_RELEASE_LIBRARIES - A list of libraries needed to use the release version of Xxx
- @b Xxx_DEBUG_LIBRARIES - A list of libraries needed to use the debug version of Xxx
- Each module produces an [imported target](https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries)
in the form @b Xxx::xxx, and may generate multiple imported targets if multiple
components are found.
@subsection buildMixingDepInstalls Mixing Dependency Installations
There may be a situation where you use a package manager to install some
dependencies, use a DCC such as Maya to provide others and manually build and
install others from source. Care must be taken when providing CMake with these
locations to ensure that the correct files are used. Incorrect use of the above
variables can lead to difficult to diagnose build and runtime errors.
As an example, let's assume we have a manual installation of TBB (either through
a Maya installation or a manual installation from source) and we want to use
this with other dependencies installed through a package manager such as
homebrew. As homebrew copies all headers and libraries it installs to a
`<homebrew>/include` `<homebrew>/lib` directory structure, it can be tempting
to set @b Xxx_ROOT variables to points to the `<homebrew>` folder. However you
may already have an existing installation of TBB through your package manager,
potentially installed by as a dependency of a completely unrelated piece of
software. Whilst CMake may report to you the correct include/lib path, this can
end up being hidden at compile time through these types of shared installations.
You should not rely on the dependency order of the CMake build system - instead,
it's important that you try to use the explicit directory paths where possible.
For example homebrew will install each piece of software to
`<homebrew>/Cellar/<dep_name>/<dep_version>`, where the subsequent include and
library directories can be passed to @b XXX_INCLUDEDIR and @b XXX_LIBRARYDIR
respectively.
In summary try to stick to a single installation workflow and, if in doubt,
provide direct include/lib paths to isolated software locations.
@subsection buildBloscSupport Blosc Support
Blosc is an optional dependency of all OpenVDB components. The documented
build steps below treat blosc as a required dependency. There are two reasons
for this:
- Blosc produces significantly smaller `.vdb` files
- If Blosc is disabled, you will not be able to read or use any `.vdb` files
that were created using blosc compression. This includes OpenVDB files from
Houdini.
See the note in the [known issues list](@ref depKnownIssues) regarding supported
versions of blosc.
@subsection buildZLibSupport ZLIB Support
ZLIB is an optional dependency of all OpenVDB components. The documented build
steps below treat ZLib as a required dependency.
You can disable ZLib using `-D USE_ZLIB=OFF` if Blosc is also disabled using `-D USE_BLOSC=OFF`.
@subsection buildVCPKG Building Dependencies using VCPKG
It is recommended to set the VCPKG_DEFAULT_TRIPLET=x64-windows environment
variable to use 64-bit libraries by default as even on a 64-bit Windows OS,
VCPKG builds and installs 32-bit libraries by default.
@section buildComponents OpenVDB Components
The following table lists all targets (mainly library and binary components)
which can be built through the CMake build system. They can be set when using
CMake from the command line with `-D VAR=ON/OFF` or with a CMake gui:
Component | Description | CMake Variable | Default |
------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------- | ---------- |
OpenVDB Core Library | The Core OpenVDB shared/static library | OPENVDB_BUILD_CORE | ON |
OpenVDB Print | Command line binary for displaying information about OpenVDB files | OPENVDB_BUILD_BINARIES / OPENVDB_BUILD_VDB_PRINT | ON / ON |
OpenVDB LOD | Command line binary for generating volume mipmaps from an OpenVDB grid | OPENVDB_BUILD_BINARIES / OPENVDB_BUILD_VDB_LOD | ON / OFF |
OpenVDB Render | Command line binary for ray-tracing OpenVDB grids | OPENVDB_BUILD_BINARIES / OPENVDB_BUILD_VDB_RENDER | ON / OFF |
OpenVDB View | Command line binary for displaying OpenVDB grids in a GL viewport | OPENVDB_BUILD_BINARIES / OPENVDB_BUILD_VDB_VIEW | ON / OFF |
OpenVDB Python | Python module for OpenVDB C++ Python bindings | OPENVDB_BUILD_PYTHON_MODULE | OFF |
OpenVDB UnitTests | OpenVDB's Unit Test suite | OPENVDB_BUILD_UNITTESTS | OFF |
OpenVDB Houdini Plugin | The OpenVDB Houdini shared library and OpenVDB Nodes | OPENVDB_BUILD_HOUDINI_PLUGIN | OFF |
OpenVDB Maya Plugin | The Maya OpenVDB Nodes | OPENVDB_BUILD_MAYA_PLUGIN | OFF |
OpenVDB AX Library | The OpenVDB AX library | OPENVDB_BUILD_AX | OFF |
OpenVDB AX Binary | Command line binary for running OpenVDB AX code | OPENVDB_BUILD_AX_BINARIES | OFF |
OpenVDB AX Grammar | Allows for re-generation of AX grammar, typically not required | OPENVDB_BUILD_AX_GRAMMAR | OFF |
OpenVDB AX Unit Tests | OpenVDB AX's Unit Test suite | OPENVDB_BUILD_AX_UNITTESTS | OFF |
NanoVDB | NanoVDB headers | OPENVDB_BUILD_NANOVDB | OFF |
NanoVDB Tools | NanoVDB command line tools | NANOVDB_BUILD_TOOLS | OFF |
NanoVDB Examples | NanoVDB example binaries and benchmarks | NANOVDB_BUILD_EXAMPLES / NANOVDB_BUILD_BENCHMARK | OFF / OFF |
NanoVDB Unit Tests | NanoVDB Unit Test suite | NANOVDB_BUILD_UNITTESTS | OFF |
Documentation | The OpenVDB doxygen documentation | OPENVDB_BUILD_DOCS | OFF |
@section buildGuide Building With CMake
@subsection buildBuildTypes Build Types
The first step is to decide what type of OpenVDB build you're after. This
primarily boils down to three main options:
- A standalone OpenVDB build (no Houdini/Maya plugins)
- OpenVDB for [Houdini](https://www.sidefx.com/)
- OpenVDB for [Maya](https://www.autodesk.co.uk/products/maya/overview)
Each option provides various benefits. Apart from the support for either the
Houdini or Maya OpenVDB plugins, the latter two options can make it easier for
new users to install the range of OpenVDB dependencies without having to worry
about using a package manager or manually installing for source. You'll still
be able to build and use all components of OpenVDB with these methods. However
depending on the DCC (Digital Content Creation) software's version, you may
find that some features of the Core library are restricted to ensure
compatibility. For more information of building OpenVDB against a Houdini or
Maya installation, see [here](@ref buildBuildHouMaya).
Developers may wish to build a standalone version of OpenVDB to take advantage
of newer dependencies and newer library features. See
[here](@ref buildBuildStandalone) for more information.
@b Note: Blosc and ZLib are treated as required dependencies in these install
instructions. See the [blosc support](@ref buildBloscSupport) and
[zlib support](@ref buildZLibSupport) sections for more information.
@subsection buildBuildHouMaya Building Against Houdini/Maya
Building against a DCC reduces the list of dependencies you need to provide.
You should not mix between Houdini and Maya libraries and should not attempt
to build the Maya plugin using Houdini libraries and vice-versa. Additionally,
it's a good idea to read the above section on
[mixing dependency installations](@ref buildMixingDepInstalls).
DCC | Supported Version | OpenVDB ABI |
-------- | ----------------- | ----------- |
Houdini | 20.0 | 10 |
Houdini | 20.5 | 11 |
@subsection buildBuildHou Building Against Houdini
Houdini ships with a number of libraries that OpenVDB requires. When downloading
Houdini, take note of the file version information. The version you install will
determine the compiler version you should try and use to build OpenVDB. For
example, for @b Linux Houdini 17.5, with a file name of
`houdini-17.5.219-linux_x86_64_gcc6.3.tar.gz`, GCC 6.3 should be used. You
will need to install some of the following dependencies depending on which
OpenVDB components you wish to build.
Package | Description | OpenVDB Components |
-------------- | --------------------------------------------------------------- | ------------------ |
CMake | Cross-platform family of tools designed to help build software | All |
C++17 Compiler | Matching Houdini compiler and version | All |
Boost | Components: iostreams | All |
GoogleTest | A unit testing framework module for C++ | Unit Tests |
CppUnit | A unit testing framework module for C++ | Unit Tests (AX) |
GLFW | Simple API for OpenGL development | OpenVDB View |
Doxygen | Documentation generation from C++ | Documentation |
Log4cplus | An optional dependency for improved OpenVDB Logging | Optional (All) |
nanobind | C++/python bindings | Optional (Python) |
NumPy | Scientific computing with Python | Optional (Python) |
LLVM | Target-independent code generation | OpenVDB AX |
At a minimum a matching C++17 compiler and CMake will be required. See
the full [dependency list](@ref dependencies) for help with downloading and
installing the above software. Note that as Blosc and ZLib are provided as part
of the Houdini installation `USE_BLOSC` and `USE_ZLIB` should be left `ON`.
With the necessary dependencies installed, create and enter a directory for
cmake to write to. It's generally useful to create this in the location you've
extracted the OpenVDB repository. It will house CMake's generated build files.
@code{.sh}
mkdir build
cd build
@endcode
Now you can call CMake by providing the absolute or relative path to the root
of the OpenVDB source tree along with the following options:
Required:
- @b Houdini_ROOT =`/path/to/houdini/install` # Path to Houdini Install
- @b USE_HOUDINI =`ON` # Force all components to build against Houdini
- @b OPENVDB_BUILD_HOUDINI_PLUGIN =`ON` # Required for building the Houdini Plugin.
Optional:
- @b [CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
=`/path/to/install/dir` # The location you wish to install OpenVDB to. See
the link for default values.
- @b OPENVDB_HOUDINI_INSTALL_PREFIX =`/path/to/install/dir` # The location to
install the Houdini plugin to. Defaults to directories defined by Houdini:
- Linux: `$ENV{HOME}/houdiniX.X`
- Mac: `$ENV{HOME}/Library/Preferences/houdini/X.X`
- Windows: `$ENV{HOMEDRIVE}$ENV{HOMEPATH}\Documents\houdiniX.X`
- @b USE_DEFAULT_HOUDINI_INSTALL =`ON` # Use the above default locations if
@b OPENVDB_HOUDINI_INSTALL_PREFIX is not specified. If `OFF`, uses the value
of @b CMAKE_INSTALL_PREFIX.
- @b BOOST_ROOT =`/path/to/boost/install` # Path to boost. May not be required,
CMake may find it automatically
For example on MacOS and where the build folder has been created inside the
OpenVDB source root:
@code
cmake -D BOOST_ROOT=/path/to/boost/install \
-D Houdini_ROOT=/Applications/Houdini/Houdini17.0.506/ \
-D USE_HOUDINI=ON \
../
@endcode
After the CMake build files have been successfully generated, run the build
tool within the build directory to compile the project. On UNIX, you can
typically incoke `make` directly:
@code
make -j4
@endcode
Where the value of the `j` argument is the number of CPU threads to use for a
multi-threaded build. On Windows, you can leverage CMake's build tool to invoke
the selected builder (usually msbuild):
@code
cmake --build .
@endcode
Finally, once a successful build has completed, you can install all files.
@code
cmake --build . --target install # or simply `make install`
@endcode
See the [troubleshooting](@ref buildTroubleshooting) section for help with
CMake and Make errors.
@subsection buildBuildMaya Building Against Maya
Supported versions of maya only ship with TBB.
Package | Description | OpenVDB Components |
-------------- | --------------------------------------------------------------- | -------------------------------- |
CMake | Cross-platform family of tools designed to help build software | All |
C++17 Compiler | Matching Houdini compiler and version | All |
Boost | Components: iostreams | All |
ZLIB | Compression library for disk serialization compression | All |
Blosc | Recommended dependency for improved disk compression | All* |
GoogleTest | A unit testing framework module for C++ | Unit Tests |
CppUnit | A unit testing framework module for C++ | Unit Tests (AX) |
GLFW | Simple API for OpenGL development | OpenVDB View |
Doxygen | Documentation generation from C++ | Documentation |
OpenEXR | EXR serialization support | OpenVDB Render |
Imath | Used half precision floating points and EXR serialization support | Optional (All) |
Log4cplus | An optional dependency for improved OpenVDB Logging | Optional (All) |
nanobind | C++/python bindings | Optional (Python) |
NumPy | Scientific computing with Python | Optional (Python) |
LLVM | Target-independent code generation | OpenVDB AX |
* See [blosc support](@ref buildBloscSupport)
At a minimum, boost, a matching C++17 compiler, ZLIB, blosc and CMake will be
required. See the full [dependency list](@ref dependencies) for help with
downloading and installing the above software.
With the necessary dependencies installed, create and enter a directory for
cmake to write to. It's generally useful to create this in the location you've
extracted the OpenVDB repository. It will house CMake's generated build files.
@code{.sh}
mkdir build
cd build
@endcode
Now you can call CMake by providing the absolute or relative path to the root
of the OpenVDB source tree along with the following options:
Required:
- @b Maya_ROOT =`/path/to/maya/install` # Path to Maya Install
- @b USE_MAYA =`ON` # Force all components to build against Maya
Optional:
- @b [CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
=`/path/to/install/dir` # The location you wish to install OpenVDB to. See
the link for default values.
- @b OPENVDB_MAYA_INSTALL_PREFIX =`/path/to/install/dir` # The location to
install the Maya plugin to. Defaults to the value of `${CMAKE_INSTALL_PREFIX}/maya${Maya_VERSION}`
- @b BOOST_ROOT =`/path/to/boost/install` # Path to boost. May not be required,
CMake may find it automatically
For example on MacOS and where the build folder has been created inside the
OpenVDB source root:
@code
cmake -D BOOST_ROOT=/path/to/boost/install \
-D Maya_ROOT=/Applications/Autodesk/maya2019/ \
-D USE_MAYA=ON \
../
@endcode
As the Maya plugin is disabled by default, you may also want to add
`-D OPENVDB_BUILD_MAYA_PLUGIN=ON` to the command. The
[components](@ref buildComponents) section shows which targets are enabled by
default.
After the CMake build files have been successfully generated, run the build
tool within the build directory to compile the project. On UNIX, you can
typically incoke `make` directly:
@code
make -j4
@endcode
Where the value of the `j` argument is the number of CPU threads to use for a
multi-threaded build. On Windows, you can leverage CMake's build tool to invoke
the selected builder (usually msbuild):
@code
cmake --build .
@endcode
Finally, once a successful build has completed, you can install all files.
@code
cmake --build . --target install # or simply `make install`
@endcode
@b Note: The Maya OpenVDB Visualize Node is @b only compatible with Legacy
OpenGL support. You can enable this in Maya by navigating to
`Windows->Settings/Preferences->Preferences->Display` and changing
`Rendering Engine` to OpenGL - Legacy.
See the [troubleshooting](@ref buildTroubleshooting) section for help with
CMake and Make errors.
@subsection buildBuildStandalone Building Standalone
It's recommended you first visit the [dependency list page](@ref dependencies)
before attempting to run CMake on a standalone build. With the necessary
dependencies installed, create and enter a directory for cmake to write to.
It's generally useful to create this in the location you've extracted the
OpenVDB repository. It will house CMake's generated build files.
@code{.sh}
mkdir build
cd build
@endcode
Now you can call CMake by providing the absolute or relative path to the root
of the OpenVDB source tree. Below are some common options you may want to
provide:
- @b [CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
=`/path/to/install/dir` # The location you wish to install OpenVDB to. See
the link for default values.
- @b Xxx_ROOT =`/path/to/Xxx/` # Give CMake a path to where a package has been
installed or simply to where your prefered package is installed if it cannot
locate it.
For example, a typical first attempt at generating the build files may look as
follows:
@code{.sh}
cmake -D CMAKE_INSTALL_PREFIX=$HOME/openvdb ../
@endcode
See the [components](@ref buildComponents) section to find which targets are
available, their corresponding CMake flags and their default values.
After the CMake build files have been successfully generated, run the build
tool within the build directory to compile the project. On UNIX, you can
typically incoke `make` directly:
@code
make -j4
@endcode
Where the value of the `j` argument is the number of CPU threads to use for a
multi-threaded build. On Windows, you can leverage CMake's build tool to invoke
the selected builder (usually msbuild):
@code
cmake --build .
@endcode
Finally, once a successful build has completed, you can install all files.
@code
cmake --build . --target install # or simply `make install`
@endcode
See the [troubleshooting](@ref buildTroubleshooting) section for help with
CMake and Make errors.
@section buildUsingOpenVDB Building With OpenVDB
This section is for users wishing to use a build of OpenVDB in their own
applications with CMake.
The following assumes that OpenVDB was installed with `OPENVDB_BUILD_CORE=ON`
and `OPENVDB_INSTALL_CMAKE_MODULES=ON`. Don't worry if you didn't specify
these options directly, they both default to `ON`. This ensures that OpenVDB
has installed the required CMake modules that your application will need to
use.
@b Note: Typically, projects provide a @b Config-file rather than a
@b Find-module for downstream use. OpenVDB currently provides a @b Find-module.
This may change in the future. Further information
[here](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#using-packages).
You can add the below CMake snippet to your main `CMakeLists.txt` to bring in
OpenVDB as a dependency:
@code{.cmake}
cmake_minimum_required(VERSION 3.20)
list(APPEND CMAKE_MODULE_PATH "/location/of/openvdb/install/lib/cmake/OpenVDB")
find_package(OpenVDB REQUIRED)
target_link_libraries(myapp OpenVDB::openvdb)
@endcode
`myapp` in the above is a CMake target, usually created with `add_library()`
or `add_executable()`. You can optionally provide `CMAKE_MODULE_PATH` as a
`-D` argument to the cmake command line instead of specifying it in your
`CMakeLists.txt`.
Note that the `FindOpenVDB.cmake` module relies on the other `FindModules`
provided in the OpenVDB installation to find it's own dependencies. This may
require you to provide additional dependency locations for OpenVDB's
dependencies. See [Locating Dependencies](@ref buildDependencies) or the below
troubleshooting for more information.
------------------------------------------------------------------------------
@section buildTroubleshooting Troubleshooting
If after reading this guide you're unable to find your specific issue below,
please get in touch or [file an issue](https://github.com/AcademySoftwareFoundation/openvdb/issues)
with the OpenVDB TSC.
@b Note: If running into issues when changing CMake settings/dependency paths,
try clearing the designated CMake build directory and running your `cmake`
command again.
@subsection troubleshoot1 CMake Error ... Could NOT find XXX (missing: ... )
It's fairly typical that CMake may fail to find some dependencies on first
runs, especially if you've manually compiled from source your own
dependencies. Analyzing any dependency errors will help with running further
invocations of cmake. The [Locating Dependencies](@ref buildDependencies)
section details the variable format required to point CMake to the correct
locations. Alternatively, with interactive cmake systems such as `ccmake` or
CMake GUI, variables which are not found will be shown, allowing you to
provide them directly.
As an example, earlier versions of
[Threading Building Blocks (TBB)](https://www.threadingbuildingblocks.org/)
do not come with CMake modules or
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) modules.
For OpenVDB to locate TBB, you typically need to provide this location
manually:
@code{.sh}
cmake -D CMAKE_INSTALL_PREFIX=$HOME/openvdb -D TBB_ROOT=/path/to/tbb/install ../
@endcode
Note that this is also equivalent to:
@code{.sh}
cmake -D CMAKE_INSTALL_PREFIX=$HOME/openvdb \
-D TBB_INCLUDEDIR=/path/to/tbb/install/include \
-D TBB_LIBRARYDIR=/path/to/tbb/install/lib \
../
@endcode
@subsection troubleshoot2 CMake Error ... Could NOT find XXX (Found unsuitable version: ... )
By default, OpenVDB sets a number of minimum version requires for its
dependencies. These can be found in the root CMakeList.txt or in the
[dependency table](@ref dependencies). These minimum versions either track
the oldest supported [VFX Reference Platform](https://www.vfxplatform.com/) or
are otherwise required for compatibility. Although not recommended, you can
bypass these checks with `-D DISABLE_DEPENDENCY_VERSION_CHECKS=ON` if necessary.
Note that using older or untested dependencies may produce undesired behavior.
Older versions in particular are not supported by OpenVDB.
@b Note: Boost will produce a version error in the format `Detected version of
Boost is too old.`
@subsection troubleshoot3 CMake warnings/errors in FindBoost.cmake
There are a variety of potential warnings and errors that may arise from the
version compatibility of Boost and CMake. These are related to how both Boost
and CMake have historically been kept in sync. A common warning and error
combination is:
@code{.sh}
CMake Warning at ... Imported targets not available for Boost version XXXXXX
...
Target "..." links to target "Boost::XXX" but the target
was not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
@endcode
OpenVDB uses [imported targets](https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries)
for all its dependencies. For imported Boost compatibility, the following
versions of CMake are required:
- Boost 1.80 requires CMake 3.24.2 or newer.
- Boost 1.81 requires CMake 3.25.2 or newer.
- Boost 1.82 requires CMake 3.27.0 or newer.
- Boost 1.83 requires CMake 3.27.4 or newer.
Use the above list to identify the version of CMake you require for your version
of Boost. Note that this may be implemented into the OpenVDB CMake in the future.
@subsection troubleshoot4 Detected VCPKG toolchain is using a mismatching triplet for OpenVDB build artifacts
If you are on Windows and using vcpkg, builds of OpenVDB should usually only
build the static OR shared library depending on your vcpkg triplet. This is
related to how libraries link against the Windows CRT. In vcpkg, static triplets,
such as @b x64-windows-static, will use the @b MultiThreaded (/MT) flag and
dynamic triplets, such as @b x64-windows, will use the @b MultiThreadedDLL (/MD)
flag. These flags @b must match throughout all software artifacts in your
toolchain (regardless if you are using vcpkg or not).
This warning is shown when OpenVDB detects you using either a dynamic or static
VCPKG toolchain on Windows, but have the opposite core library variant enabled.
By default, the static build of OpenVDB links against the @b MultiThreaded
(/MT) CRT and the dynamic library links against the @b MultiThreadedDLL (/MD)
CRT. As OpenVDB configures both by default, it is typical that you may want
to disable one or the other depending on your needs.
Note that you can provide a value for `CMAKE_MSVC_RUNTIME_LIBRARY` which is a
native CMake variable to override any CRT selection done by OpenVDB.
For more information, see the following articles:
Description of CRT selection: https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
In depth descriptopn of the CRT on Windows: https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features
Related errors: https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2038
`CMAKE_MSVC_RUNTIME_LIBRARY` docs: https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html
@subsection troubleshoot5 Unexpected value for the Windows CRT with target build artifacts.
On Windows, it is typical for static builds to link to static libraries and
dynamic builds to link to dynamic library variants. This is not related to the
libraries themselves, rather it is due to the way that all libraries used within
a specific toolchain must use the same version of the CRT. The rule of thumb is
to configure static builds against the static CRT and dynamic builds against
the dynamic CRT.
This warning is shown if you have provided a value for the CMake variable
`CMAKE_MSVC_RUNTIME_LIBRARY`, but this value is the opposite of what's expected
for a target library.
Note that there are some cases where it makes sense to link static builds of
OpenVDB against the dynamic (/MD) CRT. However, unless you are confident in your
usage, it is strongly encouraged to match the selection against your desired
build type.
For more information, see the following articles:
Description of CRT selection: https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
In depth descriptopn of the CRT on Windows: https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features
Related errors: https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2038
`CMAKE_MSVC_RUNTIME_LIBRARY` docs: https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html
@subsection troubleshoot6 error LNK2038: mismatch detected for 'RuntimeLibrary'
A build artifact of OpenVDB has been linked against a dependency which uses a
different version of the Window CRT. See the [above section](@ref troubleshoot5)
on dealing with CRT selection for static and dynamic library builds on Windows.
*/
-4571
View File
File diff suppressed because it is too large Load Diff
-309
View File
@@ -1,309 +0,0 @@
/**
@page codingStyle Coding Style
@section Introduction
This document details the coding practices that are used in the OpenVDB
codebase. Contributed code should conform to these guidelines to maintain
consistency and maintainability. If there is a rule that you would like
clarified, changed, or added, please send a note to openvdb-dev@lists.aswf.io.
@section sStyleContents Contents
- @ref sNamingConventions
- @ref sNamespaceConventions
- @ref sClassConventions
- @ref sClassMethods
- @ref sClassInstanceVariables
- @ref sClassStaticVariables
- @ref sLocalVariablesAndArguments
- @ref sConstants
- @ref sEnumerationNames
- @ref sEnumerationValues
- @ref sTypedefs
- @ref sGlobalVariables
- @ref sGlobalFunctions
- @ref sBooleans
- @ref sPractices
- @ref sGeneral
- @ref sFormatting
- @ref sIncludeStatements
- @ref sComments
- @ref sPrimitiveTypes
- @ref sMacros
- @ref sClasses
- @ref sConditionalStatements
- @ref sNamespaces
- @ref sExceptions
- @ref sTemplates
- @ref sMiscellaneous
@section sNamingConventions Naming Conventions
@subsection sNamespaceConventions Namespaces
-# Lowercase words, keep simple and short (e.g., @c tools, @c tree).
-# Use @c internal (or @c detail) or <TT><I>module</I>_internal</TT>
for symbols such as templates that must be defined in header files
but that are implementation details not intended for public use.
@subsection sClassConventions Classes and Structs
-# Mixed case; first letter uppercase (e.g., @c AffineMap, @c TreeIterator)
-# Do not use a prefix.
@subsection sClassMethods Class Methods
-# Mixed case; first letter lowercase (e.g., <TT>getAccessor()</TT>, <TT>gridType()</TT>)
-# Accessor methods that return a member variable by reference or a primitive type
by value are just the variable name (e.g., <TT>Grid::tree()</TT>).
-# Accessor methods that involve construction of objects or other computations are
@c get + the variable name (e.g., <TT>Grid::getAccessor()</TT>).
-# Simple mutators are @c set + the variable name (e.g., <TT>Grid::setTree(tree);</TT>).
@subsection sClassInstanceVariables Class Instance Variables
-# Mixed case; always prefixed by @c m (e.g., @c mTree, @c mTransform)
-# The @c m prefix may be omitted for members of <TT>struct</TT>s
used in the public API (e.g., <TT>struct Color { float r, g, b; }</TT>).
@subsection sClassStaticVariables Class Static Variables
-# Mixed case; always prefixed by @c s (e.g., @c sInitialized)
@subsection sLocalVariablesAndArguments Local Variables and Arguments
-# Use mixed case with an initial lower case letter (e.g., @c ijk, @c offset,
@c range, @c rhsValue).
@subsection sConstants Constants
-# All uppercase; words separated by underscores. If not in a namespace or
local to a source file, then prefixed with the library name in all caps
(e.g., @c HALF_FLOAT_TYPENAME_SUFFIX, @c ZIP_COMPRESSION_LEVEL)
@subsection sEnumerationNames Enumeration Names
-# Mixed case; first letter uppercase (e.g., @c GridClass, @c VecType)
@subsection sEnumerationValues Enumeration Values
-# With @c enum, all uppercase with words separated by underscores
(e.g., @c GRID_LEVEL_SET, @c VEC_INVARIANT) and with a common prefix
-# With <TT>enum class</TT>, mixed case with the first letter uppercase
(e.g., @c GridClass::Unknown, @c GridClass::LevelSet)
@subsection sTypedefs Typedefs
-# Mixed case; first letter uppercase (e.g., @c ConstPtr, @c ValueType)
-# Do not use a prefix.
@subsection sGlobalVariables Global Variables
-# Mixed case; always prefixed by @c g (e.g., @c gRegistry)
-# In general, try to use class static data instead of globals.
@subsection sGlobalFunctions Global Functions
-# Mixed case; always prefixed by @c g (e.g., <TT>gFunc()</TT>).
-# In general, try to use class static members instead of global functions.
@subsection sBooleans Booleans
-# When naming boolean functions and variables, use names that read as a
condition (e.g., <TT>if (grid.empty())</TT>,
<TT>if (matrix.isInvertible())</TT>).
@section sPractices Practices
@subsection sGeneral General
-# Code must compile without any warning messages at the default warning level.
-# Prefer the C++ Standard Library to the C Standard Library.
-# Restrict variables to the smallest scopes possible, and avoid defining
local variables before giving them values. Prefer declarations inside
conditionals: <TT>if (Grid::Ptr grid = createGrid()) { ... }</TT> instead of
<TT>Grid::Ptr grid = createGrid(); if (grid) { ... }</TT>
-# For new files, be sure to use the right license boilerplate per our license
policy.
@subsection sFormatting Formatting
-# Indentation is 4 spaces. Do not use tabs.
-# Lines are no more than 100 characters long.
-# Use Unix-style carriage returns ("\n") rather than Windows/DOS ones ("\r\n").
-# Do not leave debug <TT>printf</TT>s or other debugging code lying around.
-# Leave a blank line between a group of variable declarations and other code.
-# Leave a space after the keywords @c if, @c switch, @c while, @c do, @c for,
and @c return.
-# Leave a space on each side of binary operators such as @c +, @c -, @c *, @c /, @c &&,
and @c ||. For clarity in mathematical situations, you may omit the spaces on
either side of @c * and @c / operators to emphasize their precedence over @c + and @c -.
-# Do not leave a space between any dereferencing operator
(such as @c *, @c &, @c [], @c ->, or @c .) and its operands.
-# In parameter lists, leave a space after each comma.
-# Do not leave a space after an opening parenthesis or before a closing
parenthesis.
-# Parentheses should be used to clarify operator precedence in expressions.
-# Do not leave a space before an end-of-statement semicolon.
-# Do not use literal tabs in strings or character constants. Rather, use
spaces or "\t".
-# If a parameter list is too long, break it between parameters. Group related
parameters on lines if appropriate.
-# Modified spacing is allowed to vertically align repetitive expressions.
-# Always begin numeric constants with a digit (e.g., 0.001 not .001).
-# Use K&R-style brace placement in public code.
-# You may leave off braces for simple, single line flow control statements.
-# The return type in a function definition should go on a line by itself.
@subsection sIncludeStatements Include Statements
-# Always use double quotes ("") to include header files that live in the same
directory as your source code.
-# Use angle brackets (<>) to include header files from outside a file&rsquo;s
directory.
-# Do not use absolute paths in include directives.
-# If there is a header corresponding to a given source file, list it first,
followed by other local headers, library headers and then system headers.
@subsection sHeaderFiles Header Files
-# Header files have a <TT>.h</TT> extension.
-# All header files should be bracketed by @c \#ifdef "guard" statements.
-# In class definitions, list public, then protected, then private members.
-# List methods before variables.
-# Fully prototype all public functions and use descriptive naming for each
argument.
-# Declare every function defined in a header but outside a class definition
explicitly as @c inline.
-# Prefer forward declarations to @c \#include directives in headers.
-# Do not take advantage of indirect inclusion of header files.
-# Do not use anonymous namespaces in header files.
@subsection sSourceFiles Source Files
-# Source files have a <TT>.cc</TT> extension.
-# Properly prototype all file static functions with usefully named arguments.
-# Whenever possible, put variables and functions in an anonymous namespace.
-# Avoid global variables.
@subsection sComments Comments
-# Use @c // style comments instead of / * * / style, even for multi-line
comments.
-# Use multi-line comments to describe following paragraphs of code.
-# Use end-of-line comments to describe variable declarations or to clarify a
single statement.
-# Large blocks of code should be commented out with <TT>\#if 0</TT> and @c \#endif.
-# Do not leave obsolete code fragments within comments as an historical trail.
-# Document public code with Doxygen comments, formatted as follows:
@verbatim
/// @brief Create a new grid of type @c GridType classified as a "Level Set",
/// i.e., a narrow-band level set.
///
/// @param voxelSize the size of a voxel in world units
/// @param halfWidth the half width of the narrow band in voxel units
///
/// @details The voxel size and the narrow band half width define the grid's
/// background value as halfWidth*voxelWidth. The transform is linear
/// with a uniform scaling only corresponding to the specified voxel size.
///
/// @note It is generally advisable to specify a half-width of the narrow band
/// that is larger than one voxel unit, otherwise zero crossings are not guaranteed.
template<typename GridType>
typename GridType::Ptr createLevelSet(
Real voxelSize = 1.0, Real halfWidth = LEVEL_SET_HALF_WIDTH);
@endverbatim
@subsection sPrimitiveTypes Primitive Types
-# Avoid writing code that is dependent on the bit size of primitive values,
but when specific bit sizes are required, use explicitly-sized types such as
@c int32_t or @c uint64_t.
@subsection sMacros Macros
-# Avoid macros for constants. Use global static constants instead. (Local
static constants are not guaranteed to be initialized in a thread-safe manner.)
-# Avoid macro functions. Use @c inline and templates instead.
@subsection sClasses Classes
-# Constructors that can be called with only one argument should be prefixed
with the @c explicit keyword to avoid unintended type conversions.
-# Never call virtual methods from destructors.
-# If you have a copy constructor, make sure you have an assignment operator.
-# If you have an assignment operator, you probably need a copy constructor.
-# If you have data members that are pointers to dynamically allocated memory,
make sure you have a copy constructor and an assignment operator, both of
which do the right thing with that memory.
-# Classes which are to be subclassed always have a virtual destructor, even if
it is empty.
-# Check against self assignment and return <TT>*this</TT> in assignment
operators.
-# Declare methods as @c const wherever possible.
-# Declare object-valued input arguments as const references wherever
possible. Primitives may be passed by value, however.
-# Arithmetic, logical, bitwise, dereference, and address of operators should
only be used when their semantics are clear, obvious, and unambiguous.
-# The application operator [ () ] is allowed for functors.
-# Conversion operators should be avoided.
-# Never return const references to stack allocated or implicitly computed
objects.
-# If a class does not have a copy constructor and/or assignment operator,
consider creating a private unimplemented copy constructor and/or assignment
operator to prevent automatically generated versions from being used.
@subsection sConditionalStatements Conditional Statements
-# For test expressions, use a form that indicates as clearly as possible the
types of operands by avoiding implicit casts.
-# Assignments that occur within conditional statements must have no effect in
the enclosing scope.
-# Allow for arithmetic imprecision when comparing floating point values.
-# In switch statements, always comment fallthroughs and empty cases.
@section sNamespaces Namespaces
-# Namespaces should be used whenever possible.
-# Avoid pulling in entire namespaces with @c using directives
(e.g., <TT>using namespace std;</TT>).
-# @c using declarations are allowed for individual symbols (e.g.,
<TT>using std::vector;</TT>), but they should never appear in a header file.
-# Define global operators in the namespace of their arguments.
-# Namespaces are not indented.
@subsection sExceptions Exceptions
-# Appropriate use of exceptions is encouraged.
-# Methods should declare all exceptions they might throw using comments,
but not exception specifications.
-# Throw scope local exception instances, not pointers or references or globals.
-# Catch exceptions by reference.
-# Never allow an exception to escape from a destructor.
@subsection sTemplates Templates
-# Use @c typename rather than @c class when declaring template type parameters.
@subsection sMiscellaneous Miscellaneous
-# Don&rsquo;t use pointers to run through arrays of non-primitive types. Use explicit array indexing, iterators or generic algorithms instead.
-# Use C++ casts (<TT>static_cast&lt;int&gt;(x)</TT> or <TT>int(x)</TT>),
not C casts (<TT>(int)x</TT>).
-# Multiple variables of the same data type may be declared on the same line
if closely related.
-# Library code must never deliberately terminate the application in response
to an error condition.
-# Avoid using malloc/free when new/delete can be used instead.
-# Avoid @c goto.
-# Avoid \"magic numbers\". Use named constants when necessary.
-# If you use typeid/typeinfo, be aware that although all runtimes support
<TT>typeinfo::name()</TT>, the format of the string it returns varies
between compilers and even for a given compiler the value is not guaranteed
to be unique.
*/
-198
View File
@@ -1,198 +0,0 @@
/**
@page dependencies Dependencies
@section depContents Contents
- @ref depComponents
- @ref depDependencyTable
- @ref depKnownIssues
- @ref depInstallingDependencies
- @ref depUsingAptGet
- @ref depUsingHomebrew
<!-- - @ref depContents -->
------------------------------------------------------------------------------
@b Note: The dependency information on this page details a complete
requirements list for building OpenVDB as a @b standalone package. If you wish
to use OpenVDB with a supported 3rd party DCC (Houdini/Maya), make sure you've
first read the [Building OpenVDB](@ref build) information.
------------------------------------------------------------------------------
There are a number of optional and required dependencies necessary when
building different components of OpenVDB. Below you'll find a full list of all
dependencies, any minimum/recommended version requirements and some guides for
getting these dependencies installed. You'll also find information on any
known issues with particular software. Please report any issues not listed
here to the OpenVDB TSC.
Note that OpenVDB is production tested against the [VFX Reference Platform]
(https://www.vfxplatform.com/). Not all dependencies exist in the VFX
Reference Platform, but for those that do, their specified versions are
@b always recommended.
@section depComponents OpenVDB Components
Component | Requirements | Optional
----------------------- | ----------------------------------------------- | --------
OpenVDB Core Library | CMake, C++17 compiler, TBB::tbb | Blosc, ZLib, Log4cplus, Imath::Imath, Boost::iostream
OpenVDB Print | Core Library dependencies | -
OpenVDB LOD | Core Library dependencies | -
OpenVDB Render | Core Library dependencies | OpenEXR, Imath::Imath, libpng
OpenVDB View | Core Library dependencies, OpenGL, GLFW3, GLEW* | -
OpenVDB Python | Core Library dependencies, Python, nanobind | NumPy
OpenVDB AX | Core Library dependencies, LLVM | Bison, Flex
NanoVDB | - | Core Library, CUDA, TBB, Blosc, ZLib
OpenVDB UnitTests | Core Library dependencies, GoogleTest | CppUnit**
OpenVDB Documentation | Doxygen | -
- @b * GLEW is only required for building the vdb_view binary on Windows.
- @b ** CppUnit is only required for building the AX unit tests.
- @b Note - Bison and Flex are only required for re-generation of the AX
grammar which is not typically necessary for the majority of users.
@subsection depDependencyTable Dependency Table
Package | Minimum | Recommended | Description | apt-get | Homebrew | Source
-------------- | ------- | ----------- | ----------------------------------------------------------------- | ------- | -------- | ------
CMake | 3.20 | Latest | Cross-platform family of tools designed to help build software | Y | Y | https://cmake.org
GCC | 11.2.1 | 11.2.1 | C++ 17 Compiler: The GNU Compiler Collection | Y | Y | https://www.gnu.org/software/gcc
Clang | 5.0 | Latest | C++ 17 Compiler: A C language family frontend for LLVM | Y | Y | https://clang.llvm.org
Intel ICC | 19 | Latest | C++ 17 Compiler: Intels C++ Compiler | Y | Y | https://software.intel.com/en-us/c-compilers
MSVC | 19.30 | 19.30 | C++ 17 Compiler: Microsoft Visual C++ Compiler | Y | Y | https://visualstudio.microsoft.com/vs
Imath | 3.1 | Latest | Half precision floating points | Y | Y | http://www.openexr.com
OpenEXR | 3.1 | Latest | EXR serialization support | Y | Y | http://www.openexr.com
TBB | 2020.3 | 2020.3 | Threading Building Blocks - template library for task parallelism | Y | Y | https://www.threadingbuildingblocks.org
ZLIB | 1.2.7 | Latest | Compression library for disk serialization compression | Y | Y | https://www.zlib.net
Boost | 1.80 | 1.82 | Components: iostreams | Y | Y | https://www.boost.org
LLVM | 13.0.0 | 15.0.0* | Target-independent code generation | Y | Y | https://llvm.org/
Bison | 3.7.0 | 3.7.0 | General-purpose parser generator | Y | Y | https://www.gnu.org/software/gcc
Flex | 2.6.4 | 2.6.4 | Fast lexical analyzer generator | Y | Y | https://github.com/westes/flex
Python | 3.10 | 3.11 | The python interpreter and libraries | Y | Y | https://www.python.org
nanobind | 2.0.0 | 2.1.0 | C++/python bindings | Y | Y | https://nanobind.readthedocs.io
NumPy | 1.23.0 | 1.26.0 | Scientific computing with Python | Y | Y | http://www.numpy.org
GoogleTest | 1.10 | Latest | A unit testing framework module for C++ | Y | Y | https://github.com/google/googletest
CppUnit | 1.10 | Latest | A unit testing framework module for C++ | N | Y | https://freedesktop.org/wiki/Software/cppunit
Blosc | 1.17.0* | 1.17.0 | Recommended dependency for improved disk compression | Y | Y | https://github.com/Blosc/c-blosc/releases
Log4cplus | 1.1.2 | Latest | An optional dependency for improved OpenVDB Logging | Y | Y | https://github.com/log4cplus/log4cplus
libpng | - | Latest | Library for manipulating PNG images | Y | Y | http://www.libpng.org/pub/png/libpng.html
GLFW | 3.1 | > 3.3 | Simple API for OpenGL development | Y | Y | https://www.glfw.org
OpenGL | 3.2 | Latest | Environment for developing portable graphics applications | Y | Y | https://www.opengl.org
GLEW | 1.0.0 | Latest | A cross-platform OpenGL extension loading library. | Y | Y | http://glew.sourceforge.net
CUDA | - | Latest | Parallel computing platform for graphical processing units. | Y | N | https://developer.nvidia.com/cuda-downloads
Doxygen | 1.8.8 | 1.8.11 | Documentation generation from C++ | Y | Y | http://www.doxygen.nl
- @b * See the note in [known issues](@ref depKnownIssues) regarding supported blosc/llvm versions.
@subsection depKnownIssues Known Issues
- @b LLVM >= 15. LLVM has recently changed their IR pointer data types to be
completely opaque. Some support is provided in LLVM 15 but tests with AX show
that this is extremely unstable. AX currently only supports LLVM versions up
until 14.X.X. See https://llvm.org/docs/OpaquePointers.html for more details.
- @b GLFW: Crash with GLFW 3.2.1 when used with EGL on Linux. OpenVDB View may
segfault on closure. Fixed in GLFW 3.3
- @b Blosc: OpenVDB has historically used an old version of blosc (1.5.0) to
serialize .vdb files. OpenVDB has moved to a new blosc version minimum of
1.17.0. We have tested a range of blosc versions and found that the following
versions are NOT compatible with OpenVDB caches written using blosc 1.5.0.
Additionally these versions of blosc may generally not be compatible with OpenVDB
itself. Avoid using these versions and upgrade to the new minimum of 1.17.0 where
possible.
- All versions from 1.11.0 through to, but excluding, 1.14.0.
- Versions 1.16.0 and 1.16.1.
For more information see:
- https://www.blosc.org/posts/new-forward-compat-policy/
- https://github.com/Blosc/c-blosc/issues/260
- https://github.com/Blosc/c-blosc/issues/261
@section depInstallingDependencies Installing Dependencies
This section details a number of ways to get you up and running with the
required OpenVDB dependencies.
@subsection depUsingAptGet Using UNIX apt-get
You can use apt to automatically install required packages. Note that different
Ubuntu distributions will have different versions available. You can use apt
pinning to request newer versions of specific package from later distributions
if the required version isn't available by default (see
[man apt_preferences](https://linux.die.net/man/5/apt_preferences)). For
example, the below settings will request TBB specifically from Ubuntu 22.04
(Jammy).
@code{.sh}
Package: libtbb-dev
Pin: release n=jammy
Pin-Priority: 990
@endcode
Alternatively you can install any missing dependencies manually or through
other package managers.
@code{.sh}
#!/bin/bash
# Core library
apt-get install cmake # CMake
apt-get install libtbb-dev # TBB
apt-get install zlibc # zlib
apt-get install libboost-iostreams-dev # Boost::iostream
apt-get install libblosc-dev # Blosc
# AX
apt-get install llvm-15-dev # LLVM
# Python
apt-get install python-dev # Python
apt-get install python-numpy # NumPy
pip install nanobind # nanobind
# Optional
apt-get install libpng-dev # libpng
apt-get install libopenexr-dev # OpenEXR
apt-get install liblog4cplus-dev # Log4cplus
apt-get install googletest # GoogleTest
apt-get install libcppunit-dev # CppUnit
# vdb_view
apt-get install libglfw3-dev # GLFW
# Documentation
apt-get install doxygen # doxygen
# CUDA for NanoVDB
apt-get install nvidia-cuda-toolkit # CUDA
@endcode
@subsection depUsingHomebrew Using Homebrew
[Homebrew](https://brew.sh/) is a package manager for UNIX systems and is
an alternative to apt-get or manual installation from source.
@code{.sh}
#!/bin/bash
# Core library
brew install cmake # CMake
brew install tbb # TBB
brew install zlib # zlib
brew install boost # Boost
brew install c-blosc # blosc
# AX
brew install llvm # LLVM
# Python
brew install python # Python
brew install numpy # NumPy
brew install nanobind # nanobind
# Unit Tests
brew install gtest # GoogleTest
brew install cppunit # CppUnit
# vdb_view
brew install glfw # GLFW
# vdb_render
brew install openexr # OpenEXR
brew install libpng # libpng
# Documentation
brew install doxygen # Doxygen
@endcode
*/
-547
View File
@@ -1,547 +0,0 @@
/**
@mainpage OpenVDB
The @b OpenVDB library comprises a hierarchical data structure and a suite
of tools for the efficient manipulation of sparse, possibly time-varying,
volumetric data discretized on a three-dimensional grid. It is based on
VDB, which was developed by Ken Museth at DreamWorks Animation, and it
offers an effectively infinite 3D index space, compact storage (both in
memory and on disk), fast data access (both random and sequential), and
a collection of algorithms specifically optimized for the data structure
for common tasks such as filtering, CSG, compositing, sampling and
voxelization from other geometric representations. The technical details
of VDB are described in the paper <A href="http://www.museth.org/Ken/Publications.html">&ldquo;VDB:&nbsp;High-Resolution Sparse Volumes with Dynamic Topology&rdquo;</A>.
@b OpenVDB is maintained by the
<A HREF="https://www.aswf.io/">Academy Software Foundation&nbsp;(ASWF)</A>.
It was originally developed at
<A HREF="https://www.dreamworksanimation.com/">DreamWorks Animation</A>,
primarily by
- Ken Museth
- Peter Cucka
- Mihai Ald&eacute;n
- David Hill
See the @subpage changes "Release Notes" for what&rsquo;s new in this version
of @b OpenVDB.
See the @subpage dependencies "Dependencies" page for @b OpenVDB requirements.
See @subpage build "Building OpenVDB" for information on building @b OpenVDB.
See the @subpage overview "Overview" for an introduction to the library.
See @subpage transformsAndMaps "Transforms and Maps" for more
discussion of the transforms used in @b OpenVDB.
See the @subpage faq "FAQ" for frequently asked questions about @b OpenVDB.
See the @subpage codeExamples "Cookbook" to get started using @b OpenVDB.
See @subpage points "OpenVDB Points" to store point data using @b OpenVDB.
See @subpage python "Using OpenVDB in Python" to get started with the
@b OpenVDB Python module.
@if OPENVDB_AX
See @subpage openvdbax "OpenVDB AX" for the AX documentation.
@endif
@if OPENVDB_HOUDINI
See the @subpage houdini "Houdini Cookbook" for help on implementing Houdini nodes.
@endif
@if NANOVDB
See @subpage NanoVDB_MainPage "NanoVDB" for the NanoVDB documentation.
@endif
Contributors, please familiarize yourselves with our
@subpage codingStyle "coding standards".
<a href="../code_coverage/index.html">Code Coverage</a>
@page overview OpenVDB Overview
@section Contents
- @ref secOverview
- @ref secTree
- @ref subsecTreeConfig
- @ref secSparsity
- @ref subsecValues
- @ref subsecInactive
- @ref secSpaceAndTrans
- @ref subsecVoxSpace
- @ref subsecWorSpace
- @ref subsecTrans
- @ref secGrid
- @ref secToolUtils
- @ref secIterator
- @ref subsecTreeIter
- @ref subsecNodeIter
- @ref subsecValueAccessor
- @ref subsecTraversal
<!-- - @ref secRegistry -->
@section secOverview Introduction
This document is a high-level summary of the terminology and basic
components of the OpenVDB library and is organized around two key
motivating concepts. First, OpenVDB is designed specifically to
work efficiently with sparse volumetric data locally sampled at a high
spatial frequency, although it will function well for dense volumetric
data. From this follows the need for a memory efficient representation of
this sparsity and the need for fast iterators (and other tools) that
respect sparsity. Second, data storage is separated from data
interpretation. OpenVDB uses unit-less three-dimensional integer
coordinates to address the sparse data, but introduces a unit-less
continuous index space for interpolation, along with a transform to
place the data in physical space.
When manipulating data in OpenVDB, the three essential objects are
(1)&nbsp;the @vdblink::tree::Tree Tree@endlink, a B-tree-like
three-dimensional data structure;
(2)&nbsp;the @vdblink::math::Transform Transform@endlink, which relates
voxel indices @ijk to physical locations @xyz in
@ref subsecWorSpace &ldquo;world&rdquo; space; and
(3)&nbsp;the @vdblink::Grid Grid@endlink, a container
that associates a @b Tree with a @b Transform and additional metadata.
For instancing purposes (i.e., placing copies
of the same volume in multiple locations), the same tree may be referenced
(via smart pointers) by several different <B>Grid</B>s, each having a
unique transform.
We now proceed to discuss the @b Tree and ideas of sparsity in some
detail, followed by a briefer description of the different spaces and
transforms as well as some of the tools that act on the sparse data.
@section secTree The Tree
In OpenVDB the @b Tree data structure exists to answer the question
<I>What value is stored at location @ijk in three-dimensional index
space?</I> Here <I>i</I>, <I>j</I> and <I>k</I> are arbitrary signed 32-bit
integers, and the data type of the associated value (<TT>float</TT>,
<TT>bool</TT>, vector, etc.) is the same for all @ijk. While the @b Tree
serves the same purpose as a large three-dimensional array, it is a
specially designed data structure that, given sparse unique values,
minimizes the overall memory footprint while retaining fast access times.
This is accomplished, as the name suggests, via a tree-based acceleration
structure comprising a @vdblink::tree::RootNode RootNode@endlink,
@vdblink::tree::LeafNode LeafNode@endlink<B></B>s and usually one or more
levels of @vdblink::tree::InternalNode InternalNode@endlink<B></B>s
with prescribed branching factors.
@subsection subsecTreeConfig Tree Configuration
The tree-based acceleration structure can be configured in various ways,
but with the restriction that for a given tree all the <B>LeafNode</B>s
are at the same depth. Conceptually, the @b RootNode and
<B>InternalNode</B>s increasingly subdivide the three-dimensional index
space, and the <B>LeafNode</B>s hold the actual unique voxels.
The type of a @b Tree encodes both the type of the data to be
stored in the tree (<TT>float</TT>, <TT>bool</TT>, etc.) and the
tree&rsquo;s node configuration. In practice a four-level (root,
internal, internal, leaf) configuration is standard, and several
common tree types are defined in openvdb.h. For example,
@code
using FloatTree = tree::Tree4<float, 5, 4, 3>::Type;
using BoolTree = tree::Tree4<bool, 5, 4, 3>::Type;
@endcode
These predefined tree types share the same branching factors, which dictate
the number of children of a given node.
The branching factors (5,&nbsp;4,&nbsp;3) are specified as base two
logarithms and should be read backwards from the leaf nodes up the tree.
In the default tree configuration, each @b LeafNode holds a
three-dimensional grid of 2<SUP>3</SUP> voxels on a side (i.e., an
8&times;8&times;8 voxel grid). Internally, the @b LeafNode is said
to be at &ldquo;level&nbsp;0&rdquo; of the tree.
At &ldquo;level&nbsp;1&rdquo; of this tree is the first @b InternalNode,
and it indexes a 2<SUP>4</SUP>&times;2<SUP>4</SUP>&times;2<SUP>4</SUP>
= 16&times;16&times;16 grid, each entry of which is either a @b LeafNode
or a constant value that represents an 8&times;8&times;8 block of
voxels. At &ldquo;level&nbsp;2&rdquo; is the second @b InternalNode in this
configuration; it in turn indexes a
2<SUP>5</SUP>&times;2<SUP>5</SUP>&times;2<SUP>5</SUP> = 32&times;32&times;32
grid of level-1 <B>InternalNode</B>s and/or values,
and so the @b InternalNode at level&nbsp;2 subsumes a three-dimensional
block of voxels of size 32&times;16&times;8 = 4096 on a side. Unlike
the <B>InternalNode</B>s and <B>LeafNode</B>s, the @b RootNode
(&ldquo;level&nbsp;3&rdquo; for the default configuration) is not explicitly
restricted in the number of children it may have, so the overall index space is
limited only by the range of the integer indices, which are 32-bit by default.
@section secSparsity Sparse Values and Voxels
Like a tree&rsquo;s node configuration, the type of data held by a tree is
determined at compile time. Conceptually the tree itself
employs two different notions of data sparsity to reduce the memory footprint
and at the same time accelerate access to its contents. The first is largely
hidden from the user and concerns ways in which large regions of uniform values
are compactly represented, and the second allows for fast sequential iteration,
skipping user-specified &ldquo;uninteresting&rdquo; regions (that may
or may not have uniform values).
@subsection subsecValues Tile, Voxel, and Background Values
Although the data in a tree is accessed and set on a per-voxel level
(i.e., the value at @ijk) it need not be internally stored in that way.
To reduce the memory footprint and accelerate data access, data values are
stored in three distinct forms internal to the tree: <B>voxel values</B>,
<B>tile values</B>, and a <B>background value</B>. A voxel value is a unique
value indexed by the location of a voxel and is stored in the @b LeafNode
responsible for that voxel. A tile value is a uniform value assigned to all
voxels subsumed by a given node. (For example, a tile Value belonging to an
@b InternalNode at level&nbsp;1 is equivalent to a constant-value cube of
voxels of the same size, 8&times;8&times;8, as a @b LeafNode.)
The tile value is returned when a request is made for the data associated
with any @ijk location within the uniform tile. The background value is
a unique value (stored at the root level) that is returned when accessing
any @ijk location that does not resolve to either a tile or a @b LeafNode.
@subsection subsecInactive Active and Inactive Voxels
Any voxel or tile can be classified as either @b active or @b inactive.
The interpretation of this state is application-specific, but generally
active voxels are &ldquo;interesting&rdquo; and inactive somehow less so.
The locations of active values may be sparse in the overall voxel topology, and
OpenVDB provides @ref secIterator "iterators" that access active values only
(as well as iterators over inactive values, all values, and general topology).
An example of active vs. inactive: the voxels used to store the distance
values of a narrow-band level set (i.e., close to a given surface) will be
marked as active while the other (&ldquo;far&rdquo;) voxel locations will be
marked as inactive and will generally represent regions of space with
constant distance values (e.g., two constant distance values of opposite sign
to distinguish the enclosed inside region from the infinite outside or
background embedding).
The @vdblink::tree::Tree::prune() prune@endlink method replaces
with tile values any nodes that subsume voxels with the same values
and active states.
The resulting tree represents the same volume, but more sparsely.
@section secSpaceAndTrans Coordinate Systems and Transforms
The sampled data in the tree is accessed using signed <B>index coordinates</B>
@ijk, but associating each indicial coordinate with a specific physical
location is the job of a @b Transform.
A simple linear transform assumes a lattice-like structure with a fixed
physical distance&nbsp;&Delta; between indices, so that
@xyz = (&Delta;<I>i</I>,&nbsp;&Delta;<I>j</I>,&nbsp;&Delta;<I>k</I>).
@subsection subsecVoxSpace Index Space
To simplify transformations between physical space and lattice index
coordinates, a continuous generalization of the index lattice points called
<B>index space</B> is used.
For example, index space coordinate (1.0, 1.0, 1.0) corresponds to the same
point as (1,1,1) in the index lattice, but (1.5,1.0,1.0) also has meaning as
halfway between the index coordinates (1,1,1) and (2,1,1). Index space can
be used in constructing interpolated data values: given an arbitrary
location in physical space, one can use a transform to compute the point in
index space (which need not fall on an exact integer index) that maps to that
location and locally interpolate from values with neighboring index
coordinates.
@subsection subsecWorSpace World Space
The interpretation of the data in a tree takes place in <B>world
space</B>. For example, the tree might hold data sampled at discrete
physical locations in world space. @b Transform methods such as
@vdblink::math::Transform::indexToWorld() indexToWorld@endlink
and its inverse @vdblink::math::Transform::worldToIndex() worldToIndex@endlink
may be used to relate coordinates in the two continuous spaces. In
addition, methods such as @vdblink::math::Transform::worldToIndexCellCentered()
worldToIndexCellCentered@endlink actually return lattice points.
@subsection subsecTrans Transforms and Maps
A @vdblink::math::Transform Transform @endlink provides a context for
interpreting the information held in a tree by associating a location
in world space with each entry in the tree.
The actual implementation of the @b Transform is managed by a
@vdblink::math::MapBase Map@endlink object, which is an
encapsulation of a continuous, mostly invertible function of three
variables. A @b Map is required to provide
@vdblink::math::MapBase::applyMap() applyMap@endlink and
@vdblink::math::MapBase::applyInverseMap() applyInverseMap@endlink
methods to relate locations in its domain to its range and vice versa.
A @b Map is also required to provide information about its local derivatives.
For more on these classes, see the
@subpage transformsAndMaps "Transforms and Maps" page.
@section secGrid The Grid
For many applications, it might not be necessary ever to operate directly on
trees, though there are often significant performance improvements to be
gained by exploiting the tree structure.
The @vdblink::Grid Grid@endlink, however, is the preferred interface through
which to manage voxel data, in part because a grid associates with a tree
additional and often necessary information that is not accessible through
the tree itself.
A @vdblink::Grid Grid@endlink contains smart pointers to a
@vdblink::tree::Tree Tree@endlink object and a
@vdblink::math::Transform Transform@endlink object, either or both of which
might be shared with other grids.
As mentioned above, the transform provides for the interpretation of voxel
locations. Other grid metadata, notably the <B>grid class</B>, the
<B>vector type</B> and the world&nbsp;space/local space toggle, affect
the interpretation of voxel values.
OpenVDB is particularly well-suited (though by no means exclusively so)
to the representation of <B>narrow-band level sets</B> and
<B>fog volumes</B>.
A narrow-band level set is represented by three distinct regions of voxels:
an @b outside (or background) region of inactive voxels having a constant,
positive distance from the level set surface; an @b inside region of inactive
voxels having a constant, negative distance; and a thin band of active voxels
(normally three voxels wide on either side of the surface) whose values are
signed distances.
Similarly, a fog volume is represented by an outside region of inactive
voxels with value zero, an inside region of active voxels with value one,
and a thin band of active voxels, with values typically varying linearly
between zero and one, that separates the inside from the outside.
Identifying a grid as a level set or a fog volume, by setting its
@vdblink::GridClass grid class@endlink with
@vdblink::Grid::setGridClass() setGridClass@endlink, allows tools to invoke
alternative implementations that are better-suited or better-optimized
for those classes.
For example, resampling (in particular, scaling) a level set should normally
not be done without updating its signed distance values.
The @vdblink::tools::resampleToMatch() resampleToMatch@endlink tool
automatically recomputes signed distances for grids that are identified
as level sets.
(The lower-level @vdblink::tools::GridResampler GridResampler@endlink does not,
but it is optimized for level set grids in that it transforms only voxels
in the narrow band and relies on
@vdblink::Grid::signedFloodFill() signed flood fill@endlink to reconstruct
the inside and outside regions.)
Other tools whose behavior is affected by the grid class include the
@vdblink::tools::divergence() divergence@endlink operator (which has an
alternative implementation for @ref sStaggered "staggered velocity" grids),
the @vdblink::tools::volumeToMesh() volume to mesh@endlink converter, and
the @vdblink::tools::fillWithSpheres() sphere packing@endlink tool.
In addition, a number of level-set-specific tools, such as the
@vdblink::tools::LevelSetTracker level set tracker@endlink, throw
exceptions when invoked on grids that are not identified as level sets.
It is important, therefore, to set a grid&rsquo;s class appropriately.
When a vector-valued grid is transformed or resampled, it is often necessary
for the transform to be applied not just to voxel locations but also to
voxel values.
By default, grids are identified as &ldquo;world-space&rdquo;, meaning that
if the grid is vector-valued, its voxel values should be transformed.
Alternatively, voxel values of grids identified as
&ldquo;local-space&rdquo;, via
@vdblink::Grid::setIsInWorldSpace() setIsInWorldSpace@endlink, do not
undergo transformation.
A world-space grid&rsquo;s @vdblink::VecType vector type@endlink, specified
with @vdblink::Grid::setVectorType() setVectorType@endlink, may be invariant,
covariant or contravariant, which determines how transforms are applied
to the grid&rsquo;s voxel values (for details see, for example,
<A HREF="http://en.wikipedia.org/wiki/Covariance_and_contravariance_of_vectors">
<I>Covariance and contravariance of vectors</I></A>&nbsp;[Wikipedia]).
The @vdblink::tools::transformVectors() transformVectors@endlink tool can be
used to apply a transform to a grid&rsquo;s voxel values, and it handles all
of the supported vector types.
A grid can optionally be assigned @vdblink::Grid::setName() name@endlink and
@vdblink::Grid::setCreator() creator@endlink strings.
These are purely informational, though it might be desirable to name grids
so as to easily select which ones to read from files that contain multiple
grids.
In the absence of grid names, or at least of unique names, OpenVDB&rsquo;s
file I/O routines recognize an ordinal suffix:
&ldquo;<TT>[0]</TT>&rdquo; refers to the first unnamed grid,
&ldquo;<TT>[1]</TT>&rdquo; refers to the second, and so on, and
&ldquo;<TT>density[0]</TT>&rdquo; and &ldquo;<TT>density[1]</TT>&rdquo;
refer to the first and second grids named &ldquo;density&rdquo;.
Also of interest for file I/O is a grid&rsquo;s
&ldquo;@vdblink::Grid::setSaveFloatAsHalf() save float as half@endlink&rdquo;
setting, which allows it to be written more compactly using 16-bit
floating point values rather than full-precision values.
Finally, during file output certain statistics are computed and stored
as per-grid metadata.
These include the grid&rsquo;s index-space active voxel bounding box,
its active voxel count and its memory usage in bytes.
This information can also be
@vdblink::io::File::readAllGridMetadata() retrieved@endlink
efficiently from a file.
@section secToolUtils Utilities and Tools
OpenVDB provides utility functions and classes for the manipulation of grids
and the data they hold.
Tools such as those found in GridOperators.h compute vector quantities from
scalar data or vice-versa.
Other tools perform filtering (Filter.h and LevelSetFilter.h) and
interpolation (Interpolation.h) as well as sampling (GridTransformer.h),
compositing and constructive solid geometry (Composite.h), and other
transformations (ValueTransformer.h).
OpenVDB also supports advanced finite difference computations through
a variety of local support stencils (Stencils.h).
@section secIterator Iterators
OpenVDB provides efficient, often multithreaded, implementations of a large
variety of morphological, filtering and other algorithms that address common
data manipulation tasks on three-dimensional grids. For more specialized
tasks, OpenVDB provides lower-level data accessors that enable fast
iteration over all or selected voxels and over the elements of a @b Tree.
These take several forms: iterator classes of various types, functor-based
@b visitor methods, and the
@vdblink::tree::ValueAccessor ValueAccessor@endlink,
an accelerator for indexed @ijk voxel lookups.
Iterator classes follow a fairly consistent naming scheme. First, the
@b CIter and @b Iter suffixes denote @const and non-@const iterators, i.e.,
iterators that offer, respectively, read-only and read/write access to the
underlying tree or node. Second, iterators over tile and voxel values are
denoted either @b On, @b Off or @b All, indicating that they visit only
active values, only inactive values, or both active and inactive values.
So, for example, @b Tree::ValueOnCIter is a read-only iterator over all
active values (both tile and voxel) of a tree, whereas
@b LeafNode::ValueAllIter is a read/write iterator over all values, both
active and inactive, of a single leaf node.
OpenVDB iterators are not STL-compatible in that one can always request
an iterator that points to the beginning of a collection of elements (nodes,
voxels, etc.), but one usually cannot request an iterator that points to the
end of the collection. (This is because finding the end might require a
full tree traversal.) Instead, all OpenVDB iterators implement a @b test
method that returns @c true as long as the iterator is not exhausted and
@c false as soon as it is. Typical usage is as follows:
@code
using GridType = openvdb::FloatGrid;
GridType grid = ...;
for (GridType::ValueOnCIter iter = grid.cbeginValueOn(); iter.test(); ++iter) ...
@endcode
or more compactly
@code
for (auto iter = grid.cbeginValueOn(); iter; ++iter) ...
@endcode
Note that the naming scheme for methods that return &ldquo;begin&rdquo;
iterators closely mirrors that of the iterators themselves.
That is, @b Grid::cbeginValueOn returns a @c const iterator to the first
of a grid&rsquo;s active values, whereas @b LeafNode::beginValueAll returns
a non-<TT>const</TT> iterator to the first of a leaf node&rsquo;s values,
both active and inactive.
(@c const overloads of <B>begin</B>* methods are usually provided, so that if
the @b Grid is itself @c const, <B>Grid::begin</B>* will actually return a
@c const iterator. This makes it more convenient to use these methods in
templated code.)
Finally, note that modifying the tree or node over which one is iterating
typically does not invalidate the iterator, though it might first need
to be incremented to point to the next existing element (for example,
if one deletes a child node to which the iterator is currently pointing).
@subsection subsecTreeIter Tree Iterators
@anchor treeValueIterRef
@par Tree::ValueIter
Tree-level value iterators traverse an entire tree, visiting each value
(tile or voxel) exactly once. (It is also possible to restrict the
traversal to minimum and maximum levels of the tree.) In addition to the
methods common to all OpenVDB iterators, such as @b test and @b next,
a @b Tree::ValueIter provides methods that return the depth in the tree of
the node within which the iterator is pointing (the root node has depth&nbsp;0)
and the @ijk axis-aligned bounding box of the tile or voxel to which it is
pointing, and methods to get and set both the value and the active state of
the tile or voxel. See the
@vdblink::tree::TreeValueIteratorBase TreeValueIteratorBase @endlink
class for the complete list.
@anchor treeLeafIterRef
@par Tree::LeafIter
By convention in OpenVDB, voxels in the narrow band of a narrow-band
level set are stored only at the leaf level of a tree, so to facilitate the
implementation of level set algorithms that operate on narrow-band voxels,
OpenVDB provides an iterator that visits each @b LeafNode in a tree exactly
once.
See the @vdblink::tree::LeafIteratorBase LeafIteratorBase@endlink class
for details, and also the related
@vdblink::tree::LeafManager LeafManager@endlink acceleration structure.
@anchor treeNodeIterRef
@par Tree::NodeIter
A node iterator traverses a tree in depth-first order, starting from its
root, and visits each node exactly once. (It is also possible to restrict
the traversal to minimum and maximum node depths&mdash;see the
@vdblink::tree::NodeIteratorBase NodeIteratorBase @endlink class for details.)
Like the tree-level value iterator, the node iterator provides methods
that return the depth in the tree of the node to which the iterator
is pointing (the root node has depth&nbsp;0) and the @ijk axis-aligned
bounding box of the voxels subsumed by the node and all of its children.
@par
Naturally, a node iterator also provides access to the node to which it is
pointing, but this is complicated somewhat by the fact that nodes of the
various types (@b RootNode, @b InternalNode and @b LeafNode) do not inherit
from a common base class. For efficiency, OpenVDB generally avoids class
inheritance and virtual functions in favor of templates, allowing the
compiler to optimize away function calls. In particular, each node type is
templated on the type of its children, so even two <B>InternalNode</B>s at
different levels of a tree have distinct types. As a result, it is
necessary to know the type of the node to which a node iterator is pointing
in order to request access to that node. See the
@ref sNodeIterator "Cookbook" for an example of how to do this.
@subsection subsecNodeIter Node Iterators
Less commonly used than tree-level iterators (but found in the
implementations of some of the narrow-band level set algorithms referred to
@ref treeLeafIterRef "above") are node-level iterators. A node
<B>value iterator</B> visits the values (active, inactive or both) stored in
a single @b RootNode, @b InternalNode or @b LeafNode, whereas a node
<B>child iterator</B> visits the children of a single root or internal node.
(Recall that non-leaf nodes store either a tile value or a child node at
each grid position.)
@subsection subsecValueAccessor Value Accessor
When traversing a grid by @ijk index in a spatially coherent pattern,
such as when iterating over neighboring voxels, request a
@vdblink::tree::ValueAccessor ValueAccessor@endlink from the grid
(with @vdblink::Grid::getAccessor() Grid::getAccessor@endlink)
and use the accessor&rsquo;s
@vdblink::tree::ValueAccessor::getValue() getValue@endlink and
@vdblink::tree::ValueAccessor::setValue() setValue@endlink methods, since
these will usually be significantly faster (a factor of three is typical)
than accessing voxels directly in the grid&rsquo;s tree.
The accessor records the sequence of nodes
visited during the most recent access; on the next access, rather than
traversing the tree from the root node down, it performs an inverted
traversal from the deepest recorded node up. For neighboring voxels, the
traversal need only proceed as far as the voxels&rsquo; common ancestor node,
which more often than not is the first node in the sequence.
Multiple accessors may be associated with a single grid. In fact, for
multithreaded, read-only access to a grid, it is recommended that each
thread be assigned its own accessor. A thread-safe, mutex-locked accessor
is provided (see @vdblink::tree::ValueAccessorRW ValueAccessorRW@endlink),
but the locking negates much of the performance benefit of inverted traversal;
and because it is the accessor object that is thread-safe, not the grid,
concurrent reads and writes are not safe unless all threads share a single
accessor.
All accessors associated with a grid must be cleared after any operation that
removes nodes from the grid&rsquo;s tree, such as pruning, CSG or compositing.
For those and other built-in operations, this is done automatically via
a callback mechanism, but developers must be careful to call
@vdblink::tree::Tree::clearAllAccessors() Tree::clearAllAccessors@endlink
whenever deleting nodes directly.
@subsection subsecTraversal Tree Traversal
<I>To be written</I>
*/
-2073
View File
File diff suppressed because it is too large Load Diff
-235
View File
@@ -1,235 +0,0 @@
/**
@page faq Frequently Asked Questions
@section sFAQContents Contents
- @ref sWhatIsVDB
- @ref sWhatLicense
- @ref sWhatCLA
- @ref sWhyUseVDB
- @ref sVersionNumbering
- @ref sGeneralizedOctree
- @ref sLevelSet
- @ref sCustomizeVDB
- @ref sAdaptiveGrid
- @ref sMeaningOfVDB
- @ref sAccessor
- @ref sValue
- @ref sState
- @ref sVoxel
- @ref sTile
- @ref sBackground
- @ref sThreadSafe
- @ref sMaxRes
- @ref sCompareVDB
- @ref sReplaceDense
- @ref sContribute
@section sWhatIsVDB What is OpenVDB?
OpenVDB is a library comprising a compact hierarchical data structure and a
suite of tools for the efficient manipulation of sparse, possibly time-varying,
volumetric data discretized on a three-dimensional grid. It is based on
VDB, which was developed by Ken Museth at DreamWorks Animation, and it
offers an effectively infinite 3D index space, compact storage (both in
memory and on disk), fast data access (both random and sequential), and
a collection of algorithms specifically optimized for the data structure
for common tasks such as filtering, constructive solid geometry (CSG),
discretization of partial differential equations, voxelization of polygons,
skinning of particles, volumetric compositing and sampling. The technical
details of VDB are described in the paper
<a href="http://www.museth.org/Ken/Publications.html" target="_blank">"VDB: High-Resolution Sparse Volumes with Dynamic Topology"</a>.
@section sWhatLicense What license is OpenVDB distributed under?
OpenVDB is released under the Apache License Version 2.0, which is a
free, open source software license developed and maintained by the Apache Software
Foundation. For more information about this license, see
<a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License, Version 2</a>.
@section sWhatCLA Is there a Contributor License Agreement for OpenVDB?
Yes, developers who wish to contribute code to be considered for inclusion
in the OpenVDB distribution must first be authorized under a signed Contributor
License Agreement. The signature and authorization process is managed via
the Linux Foundation's EasyCLA system, to handle the different CLAs depending
on whether you are contributing on your own behalf or on behalf of your
employer. The EasyCLA process will begin the first time you submit a PR
to the project.
@section sWhyUseVDB Why should I use OpenVDB?
The typical reasons to adopt OpenVDB are if you are <b>storing sparse
data</b> and/or if you are performing <b>sparse computations</b>. OpenVDB
is also effectively unbounded, which makes it very convenient for
applications where the topology of the data is dynamic or unknown. Unlike
many existing sparse data structures, OpenVDB is also optimized for
numerical simulations, multithreaded volume compositing, near real-time
boolean CSG operations, fast random and sequential data access and
voxelization of points and polygons.
@section sVersionNumbering What is the version numbering system for OpenVDB?
We currently use a <I>major.minor.patch</I> version numbering system,
and with every release of OpenVDB we change one or more of the three numbers.
The patch number is incremented for new features and bug fixes that change
neither the API nor the file format of the library nor the ABIs of the @b Grid
class or its constituent classes (@b Tree, @b Transform, @b Metadata,
@b io::StreamMetadata, etc.).
The minor version is incremented for releases that change the API without
changing the @b Grid ABI, and for releases that change the file format
in such a way that older files can still be read.
The major version is incremented when the @b Grid ABI changes, or when the
file format changes in a non-backward-compatible way (which should be rare).
No release of OpenVDB guarantees ABI compatibility across the entire library,
but rather only for the @b Grid and its constituent classes, and primarily
to allow third-party app plugins compiled against different versions of
the library to coexist and exchange data.
@section sCustomizeVDB Can I customize the configuration of OpenVDB?
Yes! OpenVDB is specifically developed to be highly customizable. That is,
the user can define the sizes of all the nodes at each level of a tree as
well as the number of tree levels and the data type of values stored in the
tree. However, note that since OpenVDB makes extensive use of C++
templating, configurations are fixed at compile time rather than at run
time. This is a fundamental design characteristic of OpenVDB, and it leads
to very high performance, thanks to techniques like inlining and template
metaprogramming.
@section sGeneralizedOctree Is OpenVDB merely a generalized octree or N-tree?
No! While OpenVDB can conceptually be configured as a (height-balanced)
octree, it is much more than an octree or N-tree. Whereas octrees and
N-trees have fixed branching factors of respectively two and N in each
coordinate direction, OpenVDB&rsquo;s branching factors typically vary between
tree levels and are only limited to be powers of two. To understand why
and also learn about other unique features of OpenVDB, refer to the
paper in <i>ACM&nbsp;Transactions on Graphics</i>.
@section sLevelSet Is OpenVDB primarily for level set applications?
No! Don&rsquo;t let the fact that OpenVDB can represent and operate so well on
level sets mislead you into thinking that it is limited to or even focusing
on this special type of sparse volumetric application. OpenVDB was developed
for general-purpose volumetric processing and numerical simulation, and we
have even had success using it for volumetric applications that traditionally
call for blocked or dense grids. However, the fact remains that narrow-band
level sets play an essential role in many volumetric applications, and this
explains why OpenVDB includes so many tools and algorithms specifically
for level sets.
@section sAdaptiveGrid Is OpenVDB an adaptive grid?
Let&rsquo;s first stress that the term "adaptive grid" is somewhat ambiguous.
Some use it to mean a grid that can store data sampled at adaptive voxel sizes
typically derived from a so-called "refinement oracle", whereas others mean
multiple grids with different fixed voxel sizes all sampling the same data.
An example of the former is an octree and of the latter is a mipmap.
Since OpenVDB stores both data values and child nodes at each level of
the tree, it is adaptive only in the first sense, not the second.
The level of adaptivity or refinement between the tree levels is defined
by the branching factors of the nodes, which are fixed at compile time.
@section sMeaningOfVDB What does "VDB" stand for?
Over the years VDB has been interpreted to mean different things, none of
which are very descriptive: "Voxel Data Base", "Volumetric Data Blocks",
"Volumetric Dynamic B+tree", etc. In early presentations of VDB we even used
a different name, "DB+Grid", which was abandoned to emphasize its
distinction from similarly named, but different, existing sparse data
structures like DT-Grid or DB-Grid. The simple truth is that "VDB" is just a
name. :-)
@section sAccessor Why are there no coordinate-based access methods on the grid?
It might surprise you that the @b Grid class doesn&rsquo;t directly provide
access to voxels via their @ijk coordinates.
Instead, the recommended procedure is to ask the grid for a "value accessor",
which is an accelerator object that performs bottom-up tree traversal using
cached information from previous traversals.
Caching greatly improves performance, but it is inherently not thread-safe.
However, a single grid may have multiple value accessors, so each thread
can safely be assigned its own value accessor.
Uncached&mdash;and therefore slower, but thread-safe&mdash;random access
is possible through a grid&rsquo;s tree, for example with a call like
<tt>grid.tree().getValue(ijk)</tt>.
@section sValue How and where does OpenVDB store values?
OpenVDB stores voxel data in a tree with a fixed maximum height (chosen
at compile time), with a root node that has a dynamic branching factor,
with internal nodes that have fixed branching factors, and with leaf nodes
of fixed dimensions. Values can be stored in nodes at all levels of
the tree. Values stored in leaf nodes correspond to individual voxels;
all other values correspond to "tiles" (see below).
@section sState What are active and inactive values?
Every value in a grid has a binary state that we refer to as its
"active state".
The interpretation of this binary state is application-specific, but
typically an active (on) value is "interesting" in some sense, and an
inactive (off) value is less interesting or uninteresting.
For example, the values in a narrow-band level set are all active, and
values outside the narrow band are all inactive.
Active states of values are stored in very compact bit masks that
support sparse iteration, so visiting all active (or inactive) values
in a grid can be done very efficiently.
@section sVoxel How are voxels represented in OpenVDB?
Values stored in nodes of type @b LeafNode (which, when they exist,
have a fixed depth), correspond to individual voxels.
These are the smallest addressable units of index space.
@section sTile What are tiles?
Values stored in nodes of type @b RootNode or @b InternalNode correspond to
regions of index space with a constant value and active state and with
power of two dimensions. We refer to such regions as "tiles". By
construction, tiles have no child nodes.
@section sBackground What is the background value?
A tree&rsquo;s background value is the value that is returned whenever
one accesses a region of index space that is not explicitly represented by
voxels or tiles in the tree. Thus, you can think of the background value
as the default value associated with an empty tree.
Note that the background value is always inactive!
@section sThreadSafe Is OpenVDB thread-safe?
Yes and no. If you&rsquo;re asking if OpenVDB can safely be used in a
multithreaded application then the answer is a resounding yes.
In fact, many of the tools included in OpenVDB are multithreaded (using
Intel&rsquo;s Threading Building Blocks library).
However, like virtually all data structures that employ caching and
allocate-on-insert, certain operations in OpenVDB are not thread-safe
in the general sense.
In particular, it is not safe to retrieve voxels from a grid while
another thread is inserting voxels.
For multithreaded insertion operations we typically assign a separate grid
to each thread and then merge the grids as threads terminate.
This technique works remarkably well: because OpenVDB
is sparse and hierarchical, merging is very efficient.
For more details, please consult the @subpage codeExamples and
Appendix&nbsp;B in the <i>Transactions on Graphics</i> paper.
@section sMaxRes Is OpenVDB unbounded?
Yes, to within available memory and the 32-bit precision of the coordinates
used to index voxels. And OpenVDB supports signed coordinates, unlike most
existing sparse data structures, so there are almost no restrictions on the
available grid resolution or the index range of OpenVDB grids.
@section sCompareVDB How does OpenVDB compare to existing sparse data structures?
OpenVDB is very different from existing sparse data structures that you are
likely to have heard of. Foremost it is hierarchical (unlike DT-Grid and
Field3D), supports simulations and dynamic topology (unlike GigaVoxels), is
effectively unbounded (unlike Field3D), and offers fast random and sequential
voxel access.
@section sReplaceDense Does OpenVDB replace dense grids?
This depends a lot on your application of dense grids and your configuration
of OpenVDB.
Clearly, if you are storing or processing sparse data, OpenVDB
will offer a smaller memory footprint and faster (sparse) data processing.
However, even in some cases where both data and computation are dense, OpenVDB
can offer benefits like improved CPU cache performance due to its underlying
blocking and hierarchical tree structure.
Exceptions are of course algorithms that expect dense data to be laid out
linearly in memory, or applications that use very small grids.
The simple truth is only a benchmark comparison can tell you the preferred
data structure, but for what it&rsquo;s worth it is our experience that
for the volumetric applications we encounter in production, OpenVDB is
almost always superior.
@section sContribute How can I contribute to OpenVDB?
If you have bug reports or ideas for improvements or new features,
please contact us! If you want to contribute code, please see our
<a href="http://www.openvdb.org/license/index.html" target="_blank">License page</a>.
*/
-577
View File
@@ -1,577 +0,0 @@
/**
@page houdini Houdini Cookbook
This cookbook provides code snippets that illustrate the use of some new
tools that simplify the construction of operators in Houdini.
It also shows how to write operators that use OpenVDB.
@section sHoudiniContents Contents
- @ref sUIConstruction
- @ref sParmFactory
- @ref sOpFactory
- @ref sScopedInputLock
- @ref sOpenVDBOperators
- @ref sListOfIncomingGrids
- @ref sIteratingOverGrids
- @ref sProcessingTypedGrids
@section sUIConstruction General operator construction
This section gives usage examples for some general helper classes
that aid in the construction of Houdini operators.
These helper classes are independent of OpenVDB and can be used in the
implementation of any type of operator.
@subsection sParmFactory ParmFactory and ParmList
The @hulink::ParmFactory ParmFactory@endlink provides a simplified
interface to define the parameters of an operator.
Invoking the @hulink::ParmFactory::get() get@endlink method on a
@b ParmFactory produces a new @b PRM_Template describing a single parameter.
For example,
@code
#include <houdini_utils/ParmFactory.h>
...
PRM_Template groupParm =
houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
.setTooltip("Specify a subset of the input VDB grids to be processed.")
.setDocumentation(
"The subset of VDB grids to be processed"
" (see [specifying volumes|/model/volumes#group] for details"
" on selecting grids)")
.setChoiceList(&houdini_utils::PrimGroupMenu)
.get();
PRM_Template toleranceParm =
houdini_utils::ParmFactory(PRM_FLT_J, "tolerance", "Pruning Tolerance")
.setDefault(0.01)
.setRange(PRM_RANGE_RESTRICTED, 0, PRM_RANGE_UI, 1)
.get();
@endcode
Note that, using a @b ParmFactory, one need only specify those
attributes of a parameter (@b setDefaults, @b setTooltip, etc.)
that have non-default values.
By default, a parameter&rsquo;s tooltip is used to describe the parameter
on the Help page for its operator.
More detailed documentation in Houdini&rsquo;s
<A HREF="http://www.sidefx.com/docs/houdini/help/format">wiki markup</A>
format can be added with @hulink::ParmFactory::setDocumentation()
setDocumentation@endlink, as in the example above.
Call @b setDocumentation with a null pointer or with an empty string
to exclude a parameter from the Help page.
@b ParmFactory objects may be added directly to a
@hulink::ParmList ParmList@endlink, which among other things ensures that
the list of templates is properly null-terminated.
Typically, the @b ParmList is populated at the time the operator is registered,
as in the following example:
@code
#include <houdini_utils/ParmFactory.h>
void
newSopOperator(OP_OperatorTable* table)
{
houdini_utils::ParmList parms;
// Define a string-valued group name pattern parameter and add it to the list.
parms.add(houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
.setTooltip("Specify a subset of the input VDB grids to be processed.")
.setChoiceList(&houdini_utils::PrimGroupMenu));
// Define a menu of verbosity levels.
parms.add(houdini_utils::ParmFactory(PRM_ORD, "verbose", "Verbosity")
.setDefault(PRMoneDefaults)
.setChoiceListItems(PRM_CHOICELIST_SINGLE, {
"quiet", "Quiet", // token, label
"verbose", "Verbose",
"verbose2", "More Verbose",
}));
// Define a menu from a dynamically-constructed list of items.
{
std::vector<std::string> items;
for (int i = 0; i < openvdb::NUM_GRID_CLASSES; ++i) {
openvdb::GridClass cls = openvdb::GridClass(i);
items.push_back(openvdb::GridBase::gridClassToString(cls)); // token
items.push_back(openvdb::GridBase::gridClassToMenuName(cls)); // label
}
parms.add(houdini_utils::ParmFactory(PRM_ORD, "gridclass", "Grid Class")
.setDefault(PRMzeroDefaults)
.setChoiceListItems(PRM_CHOICELIST_SINGLE, items));
}
...
}
@endcode
@subsection Switchers
The @b ParmList provides a convenient way of defining switchers (tab menus):
@code
parms.beginSwitcher("switcher");
parms.addFolder("Tree Topology");
parms.add(houdini_utils::ParmFactory(PRM_HEADING, "nodes", "Nodes"));
parms.add(houdini_utils::ParmFactory(PRM_TOGGLE, "viewnodes", "View"));
...
parms.addFolder("Isosurface");
parms.add(houdini_utils::ParmFactory(PRM_HEADING, "surfacing", "Surfacing"));
parms.add(houdini_utils::ParmFactory(PRM_TOGGLE, "extractmesh", "Extract Mesh"));
...
parms.endSwitcher();
@endcode
The above generates the following UI:
@image html tabmenu.png
Switchers can also be nested:
@code
parms.beginSwitcher("switcher");
parms.addFolder("A");
parms.beginSwitcher("nested_switcher");
parms.addFolder("1");
parms.addFolder("2");
parms.addFolder("3");
parms.endSwitcher();
parms.addFolder("B");
...
parms.endSwitcher();
@endcode
@subsection Multi-Parms
Multi-parms are dynamically-sized parameters that consist of a variable
number of child instances.
Each child instance is defined by a second @b ParmList that itself consists
of multiple parameters.
These parameters&rsquo; tokens must include a @c # character, which is
typically placed at the end of the token.
@code
houdini_utils::ParmList parms;
...
// Build the multi-parm's parameter list.
houdini_utils::ParmList multiParms;
multiParms.add(houdini_utils::ParmFactory(PRM_STRING, "gridname#", "Grid name")
.setTooltip("Specify a name for this grid."));
...
// Create the multi-parm itself.
parms.add(houdini_utils::ParmFactory(PRM_MULTITYPE_LIST, "gridlist", "Grids")
.setMultiparms(multiParms)
.setDefault(PRMoneDefaults));
...
@endcode
The above generates the following UI:
@image html multiparm.png
A multi-parm&rsquo;s parameters are accessed by iterating through each
child instance:
@code
UT_String gridNameStr;
for (int i = 1, N = evalInt("gridlist", 0, 0); i <= N; ++i) {
evalStringInst("gridname#", &i, gridNameStr, 0, time);
...
}
@endcode
Note that evaluating the multi-parm gives the number of child instances,
and that the instances are numbered starting from one.
@subsection sOpFactory OpFactory
The @hulink::OpFactory OpFactory@endlink is used in conjunction with a
@hulink::ParmList ParmList@endlink to register a new operator by adding it
to the @b OP_OperatorTable.
Among other things, the @b OpFactory ensures that the operator&rsquo;s
type name follows a consistent naming scheme, that its Help URL is set
correctly and that its inputs are labeled.
Continuing with the earlier @b newSopOperator example,
@code
#include <houdini_utils/ParmFactory.h>
void
newSopOperator(OP_OperatorTable* table)
{
...
// Register this operator.
houdini_utils::OpFactory(houdini_utils::OpPolicy(), "My SOP",
MySOP::factory, parms, *table)
.addInput("VDB grids to process") // input 0
.addOptionalInput("Reference geometry"); // input 1
}
@endcode
The first argument to the @b OpFactory constructor is an instance of the
@hulink::OpPolicy OpPolicy@endlink class (or a subclass thereof).
@b OpPolicy objects allow for customization of certain behaviors of
the @b OpFactory.
The base class specifies a policy for converting an English
operator name like <tt>"My SOP"</tt>, which appears in menus and other
UI elements, into an operator type name.
The default policy is simply to call @b UT_String::forceValidVariableName
on the English name.
If the policy does not specify the URL of a Help page, or if the
@b OpFactory is constructed without an @b OpPolicy, then documentation
for the operator in Houdini&rsquo;s
<A HREF="http://www.sidefx.com/docs/houdini/help/format">wiki markup</A>
format can be provided with @hulink::OpFactory::setDocumentation()
setDocumentation@endlink.
By default, documentation for the operator&rsquo;s parameters is generated
automatically and appended to the text provided with @b setDocumentation.
When a particular @b OpPolicy is to be used to register multiple operators,
it might be convenient to subclass @b OpFactory itself and provide a
constructor that automatically initializes the base class with the desired
policy.
If an operator ever needs to be renamed, call
@hulink::OpFactory::addAlias() OpFactory::addAlias@endlink
with the old name. This will help to ensure that scene files in which
the operator was saved with the old name can still be read:
@code
houdini_utils::OpFactory("My Renamed SOP", MySOP::factory, parms, *table)
.addInput("VDB grids to process")
.addAlias("My SOP"); // old name
@endcode
If the operator name changed as a result of an @b OpPolicy change, supply
the old operator type name directly, with
@hulink::OpFactory::addAliasVerbatim() addAliasVerbatim@endlink:
@code
houdini_utils::OpFactory(houdini_utils::MyNewOpPolicy(), "My SOP",
MySOP::factory, parms, *table)
.addAliasVerbatim("My_Old_SOP_Type"); // old operator type name
@endcode
Among other @b OpFactory features,
@hulink::OpFactory::setObsoleteParms() OpFactory::setObsoleteParms@endlink
accepts an additional @b ParmList of parameters that are no longer in use
but that might still exist in older scene files:
@code
#include <houdini_utils/ParmFactory.h>
void
newSopOperator(OP_OperatorTable* table)
{
// This boolean "draw" parameter has been replaced with a multi-state
// "drawmode" parameter.
houdini_utils::ParmList obsoleteParms;
obsoleteParms.add(houdini_utils::ParmFactory(PRM_TOGGLE, "draw", "Draw"));
houdini_utils::ParmList parms;
parms.add(houdini_utils::ParmFactory(PRM_ORD, "drawmode", "Draw")
.setChoiceListItems(PRM_CHOICELIST_SINGLE, {
"none", "Don't Draw",
"wireframe", "Draw Wireframe",
"shaded", "Draw Shaded",
}));
// Register this operator.
houdini_utils::OpFactory("My SOP", MySOP::factory, parms, *table)
.addInput("Input geometry")
.setObsoleteParms(obsoleteParms);
}
@endcode
Override @b OP_Node::resolveObsoleteParms to convert the values of
obsolete parameters into values of current parameters where appropriate.
@subsection sScopedInputLock ScopedInputLock
A @hulink::ScopedInputLock ScopedInputLock@endlink locks the inputs to
an operator and then automatically unlocks them when it (the lock
object) goes out of scope, even if an exception is thrown.
@code
#include <houdini_utils/ParmFactory.h>
OP_ERROR
MySOP::cookMySop(OP_Context& context)
{
try {
houdini_utils::ScopedInputLock lock(*this, context);
//
// do cook work
//
} catch (std::exception& e) {
addError(SOP_MESSAGE, e.what());
}
return error();
}
@endcode
@section sOpenVDBOperators OpenVDB SOP construction
OpenVDB SOPs are derived from the @hvdblink::SOP_NodeVDB SOP_NodeVDB@endlink
base class which, among other things, adds guide geometry and node-specific
info text.
@code
#include <houdini_utils/ParmFactory.h>
#include <openvdb_houdini/Utils.h>
#include <openvdb_houdini/SOP_NodeVDB.h>
#include <UT/UT_Interrupt.h>
class SOP_DW_OpenVDBTemplate: public openvdb_houdini::SOP_NodeVDB
{
public:
SOP_DW_OpenVDBTemplate(OP_Network*, const char* name, OP_Operator*);
~SOP_DW_OpenVDBTemplate() override {};
static OP_Node* factory(OP_Network*, const char* name, OP_Operator*);
// Return true for a given input if the connector to the input
// should be drawn dashed rather than solid.
int isRefInput(unsigned idx) const override { return (idx == 1); }
protected:
OP_ERROR cookVDBSop(OP_Context&) override;
bool updateParmsFlags() override;
};
@endcode
@subsection sListOfIncomingGrids Selecting grids
A typical SOP will have at least one group name parameter for each of
its inputs. These parameters should be defined as follows (note the
use of spare data to specify the input):
@code
houdini_utils::ParmList parms;
// Define a string-valued group name pattern parameter.
parms.add(houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
.setTooltip("Specify a subset of the input VDB grids to be processed.")
.setChoiceList(&houdini_utils::PrimGroupMenu));
// Define a group name parameter associated with this operator's second input.
parms.add(houdini_utils::ParmFactory(PRM_STRING, "group", "Group")
.setTooltip("Specify a subset of the input VDB grids to be processed.")
.setChoiceList(&houdini_utils::PrimGroupMenu)
.setSpareData(&SOP_Node::theSecondInput));
@endcode
Associated with each parameter is a menu of primitive group names.
Users can select one or more groups from the menu, or create new groups
on the fly using Houdini&rsquo;s <tt>\@<i>attr</i>=<i>value</i></tt> syntax.
For example, entering <tt>\@name="density*"</tt> as the group name
creates a new group comprising all input primitives whose name begins
with <tt>density</tt>. Entering <tt>\@vdb_value_type=float</tt>
creates a new group of input grid primitives whose data type is @c float.
Users may enter multiple space-separated group names or grouping expressions.
@subsection sIteratingOverGrids Iterating over grids
In @b cookMySOP, the string value of a group parameter
is used to construct a @b GA_PrimitiveGroup.
(SOP_NodeVDB provides a convenience method,
@hvdblink::SOP_NodeVDB::matchGroup() SOP_NodeVDB::matchGroup@endlink,
to simplify this step and to handle errors in a standard way.)
The @b GA_PrimitiveGroup so constructed may be iterated over using
either a @hvdblink::VdbPrimCIterator VdbPrimCIterator@endlink, for
read-only access, or a @hvdblink::VdbPrimIterator VdbPrimIterator@endlink,
for read/write access:
@code
OP_ERROR
MySOP::cookVDBSOP(OP_Context& context)
{
try {
houdini_utils::ScopedInputLock lock(*this, context);
const fpreal time = context.getTime();
// This does a deep copy of native Houdini primitives
// but only a shallow copy of VDB grids.
duplicateSource(0, context);
// Get the group of grids to process.
UT_String groupStr;
evalString(groupStr, "group", 0, time);
const GA_PrimitiveGroup* group = matchGroup(*gdp, groupStr.toStdString());
// Get other UI parameters.
int verbose = evalInt("verbose", 0, time);
UT_AutoInterrupt progress("Processing VDB grids");
// For each VDB primitive in the selected group...
for (openvdb_houdini::VdbPrimIterator it(gdp, group); it; ++it) {
if (progress.wasInterrupted()) {
throw std::runtime_error("processing was interrupted");
}
GU_PrimVDB* vdbPrim = *it;
// Optionally get the primitive's name (or, if the name is empty,
// the primitive's index).
const UT_String gridName = it.getPrimitiveNameOrIndex();
// If this primitive's grid is shared with other primitives, make
// a deep copy of it. If the grid is not going to be modified
// in place (or when using GEOvdbProcessTypedGrid()--see below),
// skip this step.
vdbPrim->makeGridUnique();
openvdb_houdini::Grid& grid = vdbPrim->getGrid();
// Process the grid.
// (Your code goes here.)
// In cases where it is not possible to process the primitive's
// grid in place, replace the grid with a new grid:
// openvdb_houdini::GridPtr outputGrid = ...;
// vdbPrim->setGrid(*outputGrid);
}
} catch (std::exception& e) {
addError(SOP_MESSAGE, e.what());
}
return error();
}
@endcode
@subsection sProcessingTypedGrids Processing grids of different types
Recall that a @b Grid is a container for a transform, metadata and a
@b Tree, and that the @b Tree holds voxel data of a specific type
(@c bool, @c float, @c vec3s, etc.).
Whenever possible, try to write generic grid processing code.
That is, write code that can handle grids of more than one type
(@c int, @c float and @c double, say, instead of just @c float)
or, ideally, grids of arbitrary type.
Writing generic code can be tricky, but convenience functions
exist to make the job easier.
Use @b GEOvdbProcessTypedGrid to call a method or methods on
a primitive&rsquo;s grid, regardless of its type:
@code
MyGridProcessor proc; // functor (see explanation below)
// Call a method on the primitive's grid, regardless of the grid's type.
// Note that by default, GEOvdbProcessTypedGrid() calls makeGridUnique()
// on the primitive if it is non-const.
GEOvdbProcessTypedGrid(*vdbPrim, proc);
@endcode
@b GEOvdbProcessTypedGrid accepts a primitive and a functor
(an object for which the call operator,
<tt>operator()()</tt>, is defined).
The functor&rsquo;s call operator must be templated on a single type
(the grid type) and must accept a single argument (a reference to a grid
of the template type).
The operator&rsquo;s return value is ignored, so it&rsquo;s best to
declare it @c void.
The following is a simple example of a functor that satisfies these conditions:
@code
struct PruneOp
{
template<typename GridT>
void operator()(GridT& grid) const { grid.prune(); }
};
@endcode
@b PruneOp can call the @b prune method on a grid of any type, but it&rsquo;s
necessary to know the specific type, because @b prune takes an optional
tolerance argument whose type is the type of the grid&rsquo;s voxel values.
(Note that grids also have a @b pruneGrid method that doesn&rsquo;t require
knowledge of the voxel value type.)
Because a functor is an object, it can have member variables.
This makes it possible for the functor to process more than one grid
at a time, even though it gets called with only one grid.
This example shows how one might compute the CSG union of two level set
grids, <i>A</i> and <i>B</i>, of the same type:
@code
#include <openvdb/tools/Composite.h> // for csgUnion()
struct CSGUnionOp
{
// Pointer to the B grid
// (non-const, because CSG operations modify both the A and B grids)
openvdb_houdini::Grid* bGridBase;
template<typename GridT>
void operator()(GridT& aGrid) const
{
// Cast the generic B grid pointer to point to a grid of
// the same type as the A grid.
if (GridT* bGrid = UTvdbGridCast<GridT>(bGridBase)) {
// Compute the union, storing the result in the A grid
// and emptying the B grid.
openvdb::tools::csgUnion(aGrid, *bGrid);
}
}
};
OP_ERROR
MySOP::cookVDBSop(OP_Context& context)
{
...
// Retrieve the A and B grids from primitives on the input detail(s)
// (non-const, because CSG operations modify both the A and B grids).
openvdb_houdini::Grid
&aGrid = aPrim->getGrid(),
&bGrid = bPrim->getGrid();
// CSG operations require the A and B grids to have the same type.
if (aGrid.type() != bGrid.type()) {
addError(SOP_MESSAGE, "grids have different types");
} else {
CSGUnionOp proc;
// Hand the functor a generic pointer to the B grid
// (whose concrete type we don't know yet).
proc.bGridBase = &bGrid;
// Apply the CSG operation, overwriting grid A (and emptying grid B).
if (!GEOvdbProcessTypedGrid(*aPrim, proc)) {
addError(SOP_MESSAGE, "failed to compute CSG union");
}
...
}
}
@endcode
Certain operations might make sense only for grids with scalar or with
vector voxel values.
Variants of @b GEOvdbProcessTypedGrid exist to handle those cases.
For example, @b GEOvdbProcessTypedGridScalar and @b GEOvdbProcessTypedGridVec3
invoke a functor only on grids of scalar or 3-vector types, respectively,
and they return @c false for and ignore grids of all other types.
<!--
To do:
- iterating over multiple inputs
- VDB source nodes
-->
*/
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

-422
View File
@@ -1,422 +0,0 @@
/**
@page transformsAndMaps Transforms and Maps
@section sMathContents Contents
- @ref sTransforms
- @ref sLinearTransforms
- @ref sFrustumTransforms
- @ref sCellVsVertex
- @ref sVoxels
- @ref sStaggered
- @ref sMaps
- @ref sGettingMat4
- @ref sCostOfMaps
- @ref sGradientAndMaps
@section sTransforms Transforms in OpenVDB
The OpenVDB @vdblink::tree::Tree Tree@endlink is a sparse representation
of a three-dimensional array of voxels, each element of which is addressed via
discrete, three-dimensional index space coordinates, typically in the form of
a @vdblink::math::Coord Coord@endlink.
For example, the following code retrieves the floating-point value of
a voxel with index coordinates&nbsp;(1,&nbsp;2,&nbsp;3):
@code
openvdb::FloatGrid grid = ...;
openvdb::FloatGrid::Accessor accessor = grid.getAccessor();
openvdb::Coord ijk(1,2,3);
float value = accessor.getValue(ijk);
@endcode
A @vdblink::math::Transform Transform@endlink relates index space coordinates
to world space coordinates that give a spatial context for the
discretized data.
Translation from index coordinates @ijk to world space coordinates @xyz is
done with a call to the
@vdblink::math::Transform::indexToWorld() indexToWorld@endlink
method, and from world space coordinates to index space coordinates with
a call to @vdblink::math::Transform::worldToIndex() worldToIndex@endlink:
@code
// Create a linear transform that scales i, j and k by 0.1
openvdb::math::Transform::Ptr linearTransform =
openvdb::math::Transform::createLinearTransform(0.1);
// Compute the location in world space that is the image of (1,2,3).
// The result will be (0.1, 0.2, 0.3).
openvdb::Coord ijk(1,2,3);
openvdb::Vec3d worldSpacePoint = linearTransform->indexToWorld(ijk);
// Compute the location in index space that is the pre-image of (0.1, 0.2, 0.3).
// The result will be (1.0, 2.0, 3.0).
openvdb::Vec3d indexSpacePoint = linearTransform->worldToIndex(worldSpacePoint);
@endcode
In the above example, there are two things to notice.
First, world space locations are specified as three-dimensional,
double-precision, floating-point vectors, and second, @b worldToIndex
does not return discrete coordinates, but rather a floating-point vector.
This is a reflection of the fact that not every location in a continuous
world space, i.e., not every @xyz, is the image of discrete integral
coordinates @ijk.
@subsection sLinearTransforms Linear Transforms
Currently two different types of transforms are supported: linear and
frustum transforms.
A linear transform can be composed of scale, translation, rotation, and shear;
essentially those things that can be mathematically represented by an
invertible, constant-coefficient, 3&times;3 matrix and a translation
(mathematically, an affine map).
An essential feature of a linear transformation is that it treats all regions
of index space equally: a small box in index space about origin @ijk=(0,0,0)
is mapped (sheared, scaled, rotated, etc.) in just the same way that
a small box about any other index point is mapped.
@code
// Create a linear transform from a 4x4 matrix (identity in this example).
openvdb::math::Mat4d mat = openvdb::math::Mat4d::identity();
openvdb::math::Transform::Ptr linearTransform =
openvdb::math::Transform::createLinearTransform(mat);
// Rotate the transform by 90 degrees about the X axis.
// As a result the j-index will now map into the -z physical direction,
// and the k-index will map to the +y physical direction.
linearTransform->preRotate(openvdb::math::pi<double>()/2.0, openvdb::math::X_AXIS);
@endcode
@subsection sFrustumTransforms Frustum Transforms
The frustum transform is a nonlinear transform that treats different
index points differently.
And while the linear transform can be applied to any point in index
or world space, the frustum transform is designed to operate on a subset
of space. Specifically, it transforms a given box in index space to
a tapered box in world space that is a frustum of a rectangular pyramid.
@code
// Create the bounding box that will be mapped by the transform into
// the shape of a frustum.
// The points (0,0,0), (100,0,0), (0,50,0) and (100,50,0) will map to
// the corners of the near plane of the frustum, while the corners
// of the far plane will be the images of (0,0,120), (100,0,120),
// (0,50,120) and (100,50,120).
const openvdb::math::BBoxd bbox(/*min=*/openvdb::math::Vec3d(0,0,0),
/*max=*/openvdb::math::Vec3d(100,50,120));
// The far plane of the frustum will be twice as big as the near plane.
const double taper = 2;
// The depth of the frustum will be 10 times the x-width of the near plane.
cosnt double depth = 10;
// The x-width of the frustum in world space units
const double xWidth = 100;
// Construct a frustum transform that results in a frustum whose
// near plane is centered on the origin in world space.
openvdb::math::Transform::Ptr frustumTransform =
openvdb::math:::Transform::createFrustumTransform(
bbox, taper, depth, xWidth);
// The frustum shape can be rotated, scaled, translated and even
// sheared if desired. For example, the following call translates
// the frustum by 10,15,0 in world space:
frustumTransform->postTranslate(openvdb::math::Vec3d(10,15,0));
// Compute the world space image of a given point within
// the index space bounding box that defines the frustum.
openvdb::Coord ijk(20,10,18);
openvdb::Vec3d worldLocation = frustumTransform->indexToWorld(ijk);
@endcode
@subsection sCellVsVertex Cell-Centered vs. Vertex-Centered Transforms
When partitioning world space with a regular grid, two popular
configurations are cell-centered and vertex-centered grids. This is really
a question of interpretation and transforms.
The cell-centered interpretation imagines world space as divided
into discrete cells (e.g., cubes) centered on the image of the
index-space lattice points.
So the physical location @xyz that is the image (result of @b indexToWorld)
of a lattice point @ijk is the center of a cube.
In the vertex-centered approach, the images of the lattice points form the
vertices of cells, so the location @xyz would be a corner, not the
center, of a cube.
The link between transforms and cell-centered or vertex-centered
partitioning of world space is tenuous.
It boils down to this: the &ldquo;first&rdquo; cell vertex often is aligned
with the origin.
In the cell-centered case, when the cells are cubes of length &Delta;
on a side, the transform @xyz = (&Delta;<I>i</I> + &Delta;/2,
&Delta;<I>j</I> + &Delta;/2, &Delta;<I>k</I> + &Delta; /2)
will place the center of the first cube (i.e., the image of (0,0,0))
at the world space location of (&Delta;/2,&nbsp;&Delta;/2,&nbsp;&Delta;/2),
and the cube will have walls coincident with the <I>x</I>=0, <I>y</I>=0
and <I>z</I>=0 planes.
Using the OpenVDB transforms to create a so-called cell-centered transform
could be done like this:
@code
// -- Constructing a uniform, cell-centered transform --
// The grid spacing
const double delta = 0.1;
// The offset to cell-center points
const openvdb::math::Vec3d offset(delta/2., delta/2., delta/2.);
// A linear transform with the correct spacing
openvdb::math::Transform::Ptr transform =
openvdb::math:::Transform::createLinearTransform(delta);
// Add the offset.
transform->postTranslate(offset);
@endcode
In contrast, for the vertex-centered partitions of space the first
vertex is just the image of the first lattice point @ijk = (0,0,0),
and the transform would lack the offset used in the cell-centered case;
so it would simply be
@xyz = (&Delta;<I>i</I>,&nbsp;&Delta;<I>j</I>,&nbsp;&Delta;<I>k</I>).
@code
// -- Constructing a uniform, vertex-centered transform --
// The grid spacing
const double delta = 0.1;
// A linear transform with the correct spacing
openvdb::math::Transform::Ptr transform =
openvdb::math:::Transform::createLinearTransform(delta);
@endcode
@subsection sVoxels Voxel Interpretations
A similar and often related concept to cell- and vertex-centered
partitioning of world space is the idea of a voxel.
A voxel historically refers to the volumetric equivalent of a pixel
and as such implies a small region of world space.
A voxel could, for instance, be the image under transform of a vertex-centered
(or cell-centered) box in index space.
In this way the voxel can be seen as a generalization of regular grid cells.
The interpretation of data stored in a grid can be related to the concept
of a voxel but need not be.
An application might interpret the grid value indexed by @ijk as the
spatial average of a quantity in a defined world-space voxel centered
on the image of that lattice point.
But in other situations the value stored at @ijk might be a discrete sample
taken from a single point in world space.
The @vdblink::math::Transform Transform@endlink class does include
methods such as @vdblink::math::Transform::voxelSize() voxelSize@endlink
and @vdblink::math::Transform::voxelVolume() voxelVolume@endlink that suppose
a particular interpretation of a voxel.
They assume a voxel that is the image of a vertex-centered cube in index space,
so the @b voxelSize methods return the lengths of line segments in world space
that connect vertices:
@code
openvdb::Coord ijk(0,0,0);
openvdb::Coord tmp0(1,0,0), tmp1(0,1,0), tmp2(0,0,1);
openvdb::math::Vec3d size;
size.x() = (xform.indexToWorld(ijk + tmp0) - xform.indexToWorld(ijk)).length();
size.y() = (xform.indexToWorld(ijk + tmp1) - xform.indexToWorld(ijk)).length();
size.z() = (xform.indexToWorld(ijk + tmp2) - xform.indexToWorld(ijk)).length();
// The voxelSize() for the voxel at (0,0,0) is consistent with
// the computation above.
assert(xform.voxelSize(ijk) == size);
@endcode
In the case where the transform is linear, the result of @b voxelSize
will be independent of the actual location @ijk, but the voxel size for a
nonlinear transform such as a frustum will be spatially varying.
The related @b voxelVolume can not in general be computed from the
@b voxelSize, because there is no guarantee that a general transform
will convert a cube-shaped voxel into another cube.
As a result, @b voxelVolume actually returns the determinant of the
transform, which will be a correct measure of volume even if the voxel
is sheared into a general parallelepiped.
@subsection sStaggered Staggered Velocity Grids
Staggered velocity data is often used in fluid simulations, and the
relationship between data interpretation and transforms is
somewhat peculiar when using a vector grid to hold
staggered velocity data.
In this case the lattice point @ijk identifies a cell in world space
by mapping to the cell&rsquo;s center, but each element of the velocity
vector is identified with a different face of the cell.
The first element of the vector is identified with the image of the
(<I>i</I>&minus;1/2,&nbsp;<I>j</I>,&nbsp;<I>k</I>) face, the second element
with (<I>i</I>,&nbsp;<I>j</I>&minus;1/2,&nbsp;<I>k</I>), and
the third element with (<I>i</I>,&nbsp;<I>j</I>,&nbsp;<I>k</I>&minus;1/2).
@section sMaps Maps in OpenVDB Transforms
The actual work of a @vdblink::math::Transform Transform@endlink is performed
by an implementation object called a @vdblink::math::MapBase Map@endlink.
The @b Map in turn is a polymorphic object whose derived types are designed to
optimally represent the most common transformations.
Specifically, the @vdblink::math::Transform Transform@endlink holds a
@vdblink::math::MapBase MapBase@endlink pointer to a derived type that
has been simplified to minimize calculations.
When the transform is updated by prepending or appending a linear operation
(e.g., with @vdblink::math::Transform::preRotate() preRotate@endlink),
the implementation map is recomputed and simplified if possible.
For example, in many level-set-oriented applications the transform between
index space and world space is simply a uniform scaling of the index points,
i.e., @xyz = (&Delta;<I>i</I>,&nbsp;&Delta;<I>j</I>,&nbsp;&Delta;<I>k</I>),
where &Delta; has some world space units.
For transforms such as this, the implementation is a
@vdblink::math::UniformScaleMap UniformScaleMap@endlink.
@code
// Create a linear transform that scales i, j and k by 0.1
openvdb::math::Transform::Ptr linearTransform =
openvdb::math::Transform::createLinearTransform(0.1);
// Create an equivalent map.
openvdb::math::UniformScaleMap uniformScale(0.1);
// At this time the map holds a openvdb::math::UniformScaleMap.
assert(linearTransform->mapType() == openvdb::math::UniformScaleMap::type());
openvdb::Coord ijk(1,2,3);
// Applying the transform...
openvdb::math::Vec3d transformResult = linearTransform->indexToWorld(ijk);
// ...is equivalent to applying the map.
openvdb::math::Vec3d mapResult = uniformScale.applyMap(ijk);
assert(mapResult == transformResult);
@endcode
There are specialized maps for a variety of common linear transforms:
pure translation (@vdblink::math::TranslationMap TranslationMap@endlink),
uniform scale (@vdblink::math::UniformScaleMap UniformScaleMap@endlink),
uniform scale and translation
(@vdblink::math::UniformScaleTranslateMap UniformScaleTranslateMap@endlink),
non-uniform scale (@vdblink::math::ScaleMap ScaleMap@endlink), and
non-uniform scale and translation
(@vdblink::math::ScaleTranslateMap ScaleTranslateMap@endlink).
A general affine map (@vdblink::math::AffineMap AffineMap@endlink) is used
for all other cases (those that include non-degenerate rotation or shear).
@subsection sGettingMat4 An Equivalent Matrix Representation
The matrix representation used within OpenVDB adheres to the minority
convention of right-multiplication of the matrix against a vector:
@code
// Example matrix transform that scales, next translates,
// and finally rotates an incoming vector
openvdb::math::Mat4d transform = openvdb::math::Mat4d::identity();
transform.preScale(openvdb::math::Vec3d(2,3,2));
transform.postTranslate(openvdb::math::Vec3d(1,0,0));
transform.postRotate(openvdb::math::X_AXIS, openvdb::math::pi<double>()/3.0);
// Location of a point in index space
openvdb::math::Vec3d indexSpace(1,2,3);
// Apply the transform by right-multiplying the matrix.
openvdb::math::Vec3d worldSpace = indexSpace * transform;
@endcode
Any linear map can produce an equivalent
@vdblink::math::AffineMap AffineMap@endlink, which in turn can produce
an equivalent 4&times;4 matrix.
Starting with a linear transform one can produce a consistent matrix as follows:
@code
openvdb::math::Mat4d matrix;
if (transform->isLinear()) {
// Get the equivalent 4x4 matrix.
matrix = transform->getBaseMap()->getAffineMap()->getMat4();
}
@endcode
This could be used as an intermediate form when constructing new linear
transforms by combining old ones.
@code
// Get the matrix equivalent to linearTransformA.
openvdb::math::Mat4d matrixA =
linearTransformA->getBaseMap()->getAffineMap()->getMat4();
// Invert the matrix equivalent to linearTransformB.
openvdb::math::Mat4d matrixBinv =
(linearTransformB->getBaseMap()->getAffineMap()->getMat4()).inverse();
// Create a new transform that maps the index space of linearTransformA
// to the index space of linearTransformB.
openvdb::math::Transform::Ptr linearTransformAtoB =
openvdb::math::Trasform::createLinearTransform(matrixA * matrixBinv);
@endcode
Notice that in the above example, the internal representation used by
the transform will be simplified if possible to use one of the various
map types.
@subsection sCostOfMaps Working Directly with Maps
Accessing a transform&rsquo;s map through virtual function calls
introduces some overhead and precludes compile-time optimizations
such as inlining.
For this reason, the more computationally intensive OpenVDB tools are
templated to work directly with any underlying map.
This allows the tools direct access to the map&rsquo;s simplified
representation and gives the compiler a free hand to inline.
Maps themselves know nothing of index space and world space, but are
simply functions <I>x</I><SUB><I>range</I></SUB> =
<I>f</I>(<I>x</I><SUB><I>domain</I></SUB>) that map 3-vectors from
one space (the domain) to another (the range), or from the range back to
the domain (<I>x</I><SUB><I>domain</I></SUB> =
<I>f</I><SUP>&minus;1</SUP>(<I>x</I><SUB><I>range</I></SUB>)), by means of
the methods @vdblink::math::MapBase::applyMap() applyMap@endlink and
@vdblink::math::MapBase::applyInverseMap() applyInverseMap@endlink.
@code
// Create a simple uniform scale map that scales by 10.
openvdb::math::UniformScaleMap usm(10.0);
// A point in the domain
openvdb::math::Vec3d domainPoint(0,1,3);
// The resulting range point
openvdb::math::Vec3d rangePoint = usm.applyMap(domainPoint);
// The map is inverted thus:
assert(domainPoint == usm.applyInverseMap(rangePoint));
@endcode
In many tools, the actual map type is not known a priori and
must be deduced at runtime prior to calling the appropriate
map-specific or map-templated code. The type of map currently being
used by a transform can be determined using the
@vdblink::math::Transform::mapType() mapType@endlink method:
@code
// Test for a uniform scale map.
if (transform->mapType() == openvdb::math::UniformScaleMap::type()) {
// This call would return a null pointer in the case of a map type mismatch.
openvdb::math::UniformScaleMap::ConstPtr usm =
transform->map<openvdb::math::UniformScaleMap>();
// Call a function that accepts UniformScaleMaps.
dofoo(*usm)
}
@endcode
To simplify this process, the function
@vdblink::math::processTypedMap processTypedMap@endlink has been provided.
It accepts a transform and a functor templated on the map type.
@subsection sGradientAndMaps Maps and Mathematical Operations
In addition to supporting the mapping of a point from one space to another,
maps also support mapping of local gradients.
This results from use of the chain rule of calculus in computing the
Jacobian of the map.
Essentially, the gradient calculated in the domain of a map can be converted
to the gradient in the range of the map, allowing one to compute a gradient
in index space and then transform it to a gradient in world space.
@code
// Compute the gradient at a point in index space in a
// floating-point grid using the second-order central difference.
openvdb::FloatGrid grid = ...;
openvdb::Coord ijk(2,3,5)
openvdb::math::Vec3d isGrad =
openvdb::math::ISGradient<CD_2D>::result(grid, ijk);
// Apply the inverse Jacobian transform to convert the result to the
// gradient in the world space defined by a map that scales index space
// to create voxels of size 0.1 x 0.2 x 0.1
openvdb::math::ScaleMap scalemap(0.1, 0.2, 0.1);
openvdb::math::Vec3d wsGrad = scalemap.applyIJT(isGrad);
@endcode
*/
-37
View File
@@ -1,37 +0,0 @@
# FAQ {#NanoVDB_FAQ}
* **What is NanoVDB?**
As the name indicates it's a mini-version of the much bigger OpenVDB library, both in terms of functionality and scope. In fact, a stand-alone C++11 implementation of NanoVDB is available in the file [NanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/NanoVDB.h) and the C99 equivalent in the files [CNanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/CNanoVDB.h), and [PNanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/PNanoVDB.h). However, NanoVDB offers one major advantage over OpenVDB, namely support for GPUs. In short, NanoVDB is a standalone static-topology implementation of the well-known sparse volumetric VDB data structure. In other words, while values can be modified in a NanoVDB grid its tree topology cannot.
**What graphics API does NanoVDB support?**
We have tested NanoVDB with CUDA, OpenCL, OpenGL, DirectX 12, OptiX, Vulkan, HLSL, and GLSL. We are also working on adding support for WebGL.
* **What are the advantages of NanoVDB?**
Other then the fact that it runs on the GPU, NanoVDB offers several other advantages over OpenVDB. For its limited applications it's generally faster, uses slightly less memory, is implemented in few header files, and has virtually no dependencies on external libraries (other then C++11 or C99). While NanoVDB inherits most of the memory and data access advantages of OpenVDB (e.g. fast random-access by means of inverse tree-traversal), the improved memory layout of NanoVDB actually results in faster read access performance.
* **What are the limitations of NanoVDB?**
Other than the fact that NanoVDB obviously lacks many of the features and tools of OpenVDB, the most important limitation of NanoVDB is the fact that it *assumes the topology of the tree structure to be static*. Thus, it is possible to modify the values in a NanoVDB grid, but not its topology, e.g. see [modify_nanovdb_thrust.cu](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/examples/ex_modify_nanovdb_thrust/modify_nanovdb_thrust.cu).
* **Does NanoVDB work on the CPU as well as the GPU?**
Yes! In fact, it provides performance advantages on the CPU over OpenVDB, primarily due to the defragmented and more cache-friendly memory layout for spatially coherent voxel access.
* **What is NanoVDB intended for?**
Rendering (e.g. ray-tracing) on the GPU or CPU, and other applications that require fast random access into a sparse volumetric data structure (e.g. collision detection for cloth simulations or static boundary conditions in fluid simulations). Additionally, since NanoVDB is essentially a slimmed-down version of the core data structure in OpenVDB, NanoVDB also serves as a great tool to learn about the implementation details of VDB, and can even serve as a starting point for your own sparse data structure.
* **Does NanoVDB depend on and require CUDA?**
No, NanoVDB is by design agnostic and works with most graphics APIs, e.g. OpenGL, OpenCL, OptiX, CUDA, HLSL, GLSL, DirectX, and even the CPU! The data structure itself (defined in [NanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/NanoVDB.h) and [PNanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/PNanoVDB.h)) only depends on C++11 or C99. However, some of the auxiliary math classes are optionally optimized with intrinsic CUDA calls (e.g. fma in Vec3) and some of the [Allocator](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/util/CudaDeviceBuffer.h) uses CUDA for explicit memory management. It should be straightforward to replace (or remove) these CUDA dependencies if you so desire.
* **How does the data structure of NanoVDB compare to that of OpenVDB?**
Conceptually they are essentially identical (NanoVDB uses the exact same tree configuration), but there are some implementation differences to minimize dependencies on external libraries in NanoVDB (e.g. no boost and std containers), and more importantly, NanoVDB has additional meta-data encoded in tree nodes specifically to accelerate ray-tracing (e.g. min/max values and AABB of active values). Also, NanoVDB is pointer-less and occupies a contiguous block of memory, i.e. de-fragmentized relative to OpenVDB. Effectively, NanoVDB is a linearized version of the well-known OpenVDB data structure with a few additional information baked into the tree nodes!
* **Are there known issues with NanoVDB?**
While the are currently no known bugs, there are certainly lots of room for improvements and enhancements. If you have issues or ideas for new feature in NanoVDB please let us know, e.g by submitting a [Github issue](https://github.com/AcademySoftwareFoundation/openvdb/issues).
-154
View File
@@ -1,154 +0,0 @@
# NanoVDB Hello World Examples {#NanoVDB_HelloWorld}
[The first example](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/examples/ex_openvdb_to_nanovdb_accessor/openvdb_to_nanovdb_accessor.cc) shows how to convert an OpenVDB level set sphere into a NanoVDB level set, use accessors to print out multiple values from both grids, and save the NanoVDB grid to file. Note that **this example depends on both OpenVDB and NanoVDB**.
```cpp
#include <openvdb/tools/LevelSetSphere.h> // replace with your own dependencies for generating the OpenVDB grid
#include <nanovdb/util/CreateNanoGrid.h> // converter from OpenVDB to NanoVDB (includes NanoVDB.h and GridManager.h)
#include <nanovdb/util/IO.h>
// Convert an openvdb level set sphere into a nanovdb, use accessors to print out multiple values from both
// grids and save the NanoVDB grid to file.
// Note, main depends on BOTH OpenVDB and NanoVDB.
int main()
{
try {
// Create an OpenVDB grid (here a level set surface but replace this with your own code)
auto srcGrid = openvdb::tools::createLevelSetSphere<openvdb::FloatGrid>(100.0f, openvdb::Vec3f(0.0f), 1.0f);
// Convert the OpenVDB grid, srcGrid, into a NanoVDB grid handle.
auto handle = nanovdb::createNanoGrid(*srcGrid);
// Define a (raw) pointer to the NanoVDB grid on the host. Note we match the value type of the srcGrid!
auto* dstGrid = handle.grid<float>();
if (!dstGrid)
throw std::runtime_error("GridHandle does not contain a grid with value type float");
// Get accessors for the two grids. Note that accessors only accelerate repeated access!
auto dstAcc = dstGrid->getAccessor();
auto srcAcc = srcGrid->getAccessor();
// Access and print out a cross-section of the narrow-band level set from the two grids
for (int i = 97; i < 104; ++i) {
printf("(%3i,0,0) OpenVDB cpu: % -4.2f, NanoVDB cpu: % -4.2f\n", i, srcAcc.getValue(openvdb::Coord(i, 0, 0)), dstAcc.getValue(nanovdb::Coord(i, 0, 0)));
}
nanovdb::io::writeGrid("data/sphere.nvdb", handle); // Write the NanoVDB grid to file and throw if writing fails
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
}
return 0;
}
```
[The second example](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor/read_nanovdb_sphere_accessor.cc) reads a NanoVDB grid from a file (the one saved in the previous example) and prints out multiple values. Note that **this example does not depend on OpenVDB (nor CUDA), only NanoVDB**.
```cpp
#include <nanovdb/util/IO.h> // this is required to read (and write) NanoVDB files on the host
/// @brief Read a NanoVDB grid from a file and print out multiple values.
///
/// @note Note This example does NOT depend on OpenVDB (nor CUDA), only NanoVDB.
int main()
{
try {
auto handle = nanovdb::io::readGrid("data/sphere.nvdb"); // reads first grid from file
auto* grid = handle.grid<float>(); // get a (raw) pointer to a NanoVDB grid of value type float
if (!grid)
throw std::runtime_error("File did not contain a grid with value type float");
auto acc = grid->getAccessor(); // create an accessor for fast access to multiple values
for (int i = 97; i < 104; ++i) {
printf("(%3i,0,0) NanoVDB cpu: % -4.2f\n", i, acc.getValue(nanovdb::Coord(i, 0, 0)));
}
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
}
return 0;
}
```
[The third example](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor_cuda/read_nanovdb_sphere_accessor_cuda.cc) reads a NanoVDB grid from a file (the one saved in the first example) and prints out multiple values on both the CPU and GPU. Note that **this example does NOT depend on OpenVDB, only NanoVDB and CUDA**.
```cpp
#include <nanovdb/util/IO.h> // this is required to read (and write) NanoVDB files on the host
#include <nanovdb/util/cuda/CudaDeviceBuffer.h> // required for CUDA memory management
extern "C" void launch_kernels(const nanovdb::NanoGrid<float>*,
const nanovdb::NanoGrid<float>*,
cudaStream_t stream);
/// @brief Read a NanoVDB grid from a file and print out multiple values on both the cpu and gpu.
///
/// @note Note This example does NOT depend on OpenVDB, only NanoVDB and CUDA.
int main()
{
try {
// returns a GridHandle using CUDA for memory management.
auto handle = nanovdb::io::readGrid<nanovdb::CudaDeviceBuffer>("data/sphere.nvdb");
cudaStream_t stream; // Create a CUDA stream to allow for asynchronous copy of pinned CUDA memory.
cudaStreamCreate(&stream);
handle.deviceUpload(stream, false); // Copy the NanoVDB grid to the GPU asynchronously
auto* cpuGrid = handle.grid<float>(); // get a (raw) pointer to a NanoVDB grid of value type float on the CPU
auto* deviceGrid = handle.deviceGrid<float>(); // get a (raw) pointer to a NanoVDB grid of value type float on the GPU
if (!deviceGrid || !cpuGrid)
throw std::runtime_error("GridHandle did not contain a grid with value type float");
launch_kernels(deviceGrid, cpuGrid, stream); // Call a host method to print a grid values on both the CPU and GPU
cudaStreamDestroy(stream); // Destroy the CUDA stream
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
}
return 0;
}
```
NVCC requires the CUDA kernel to be defined in [a separate .cu file](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor_cuda/read_nanovdb_sphere_accessor_cuda.cu):
```cpp
#include <nanovdb/NanoVDB.h> // this defined the core tree data structure of NanoVDB accessible on both the host and device
#include <stdio.h> // for printf
// This is called by the host only
void cpu_kernel(const nanovdb::NanoGrid<float>* cpuGrid)
{
auto cpuAcc = cpuGrid->getAccessor();
for (int i = 97; i < 104; ++i) {
printf("(%3i,0,0) NanoVDB cpu: % -4.2f\n", i, cpuAcc.getValue(nanovdb::Coord(i, 0, 0)));
}
}
// This is called by the device only
__global__ void gpu_kernel(const nanovdb::NanoGrid<float>* deviceGrid)
{
if (threadIdx.x > 6)
return;
int i = 97 + threadIdx.x;
auto gpuAcc = deviceGrid->getAccessor();
printf("(%3i,0,0) NanoVDB gpu: % -4.2f\n", i, gpuAcc.getValue(nanovdb::Coord(i, 0, 0)));
}
// This is called by the client code on the host
extern "C" void launch_kernels(const nanovdb::NanoGrid<float>* deviceGrid,
const nanovdb::NanoGrid<float>* cpuGrid,
cudaStream_t stream)
{
// Launch the device kernel asynchronously
gpu_kernel<<<1, 64, 0, stream>>>(deviceGrid);
// Launch the host "kernel" (synchronously)
cpu_kernel(cpuGrid);
}
```
-55
View File
@@ -1,55 +0,0 @@
# Build instructions {#NanoVDB_HowToBuild}
Note that NanoVDB can be built in many different ways, in the sense that its many external dependencies are optional. This includes OpenVDB, TBB, graphics APIs like CUDA, OpenGL, and OpenCL, as well as compression like ZLIB and BLOSC.
However, since the core data structure in [NanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/NanoVDB.h) is self-contained, client code may only depend on this single header file.
Also, note that if the environment variable `VDB_DATA_PATH` is set to a directory containing the OpenVDB files from [the OpenVDB web site](http://www.openvdb.org/download), they will be used for the unit and the benchmark tests. Else a simple narrow-band level set sphere is used. Set the environment variable `VDB_SCRATCH_PATH` to define the path to where images generated in the benchmark tests are stored (defaults to the build directory).
[//]: # (TODO: add back OPTIX, OPENCL, and OPENGL when these options are added back)
To explicitly remove a dependency, `X`, add the argument `-DNANOVDB_USE_X=OFF` where `X = {OPENVDB, TBB, BLOSC, ZLIB, CUDA}`. These options are set in the [NanoVDB root CMakeLists.txt](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/CMakeLists.txt). The same file also defines options to build NanoVDB examples, benchmarks, unit-tests, and command-line tools. The default values for these options are `OFF`. A user can override each of these options by passing, for example, `-DNANOVDB_BUILD_UNITTESTS=ON` flag while running cmake from the command line.
To see the compiler arguments add `-DCMAKE_VERBOSE_MAKEFILE=ON`.
## First example: building NanoVDB and OpenVDB core
NanoVDB is now a module of the larger OpenVDB project. A user can build both libraries together. This will build the OpenVDB core library, install the NanoVDB header files, and build the NanoVDB command-line tools in the `build/nanovdb/cmd` directory. From the 'root' OpenVDB project directory (change the dependency paths to match your environment):
```console
foo@bar:~$ mkdir build
foo@bar:~$ cd build
foo@bar:~$ cmake .. -DUSE_NANOVDB=ON -DTBB_ROOT=/path/to/tbb -DBOOST_ROOT=/path/to/boost -DBLOSC_ROOT=/path/to/blosc -DCMAKE_INSTALL_PREFIX=/install/path
foo@bar:~$ make -j 4 && make install
```
Note that the default value of `NANOVDB_USE_OPENVDB` is linked to `OPENVDB_BUILD_CORE` option and can be overriden by passing on `-DNANOVDB_USE_OPENVDB=OFF`. The `Boost` library is included because it is a requirement for building OpenVDB.
In general, CMake will try to find every optional dependency when a user opts to add an additional dependency. Be sure to check the CMake log to see what dependencies were **not** found.
## Second example: NanoVDB with no dependencies
From the 'root' OpenVDB project directory:
```console
foo@bar:~$ mkdir build
foo@bar:~$ cd build
foo@bar:~$ cmake .. -DUSE_NANOVDB=ON -DOPENVDB_BUILD_CORE=OFF -DOPENVDB_BUILD_BINARIES=OFF -DNANOVDB_USE_TBB=OFF -DNANOVDB_USE_BLOSC=OFF -DNANOVDB_USE_ZLIB=OFF -DCMAKE_INSTALL_PREFIX=/install/path
foo@bar:~$ make -j 4 && make install
```
Another option is to build it from the NanoVDB directory itself, which is much simpler:
```console
foo@bar:~$ cd nanovdb/nanovdb
foo@bar:~$ mkdir build
foo@bar:~$ cd build
foo@bar:~$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/path
foo@bar:~$ make -j 4 && make install
```
Both options will install the NanoVDB header files to the `/install/path` as well as building `nanovdb_print` and `nanovdb_validate` executable. The path where these executables are installed will be different: in the first option they will be under `build/nanovdb/cmd` directory; whilst in the second option they will be under the `build/cmd/` directory.
## Third example: build 'everything' in NanoVDB along with OpenVDB core
From the root OpenVDB directory:
```console
foo@bar:~$ mkdir build
foo@bar:~$ cd build
foo@bar:~$ cmake .. -DUSE_NANOVDB=ON -DNANOVDB_BUILD_UNITTESTS=ON -DNANOVDB_BUILD_EXAMPLES=ON -DNANOVDB_BUILD_BENCHMARK=ON -DNANOVDB_USE_INTRINSICS=ON -DNANOVDB_USE_CUDA=ON -DNANOVDB_CUDA_KEEP_PTX=ON -DTBB_ROOT=/path/to/tbb -DBOOST_ROOT=/path/to/boost -DBLOSC_ROOT=/path/to/blosc -DGTEST_ROOT=/path/to/gtest -DCMAKE_INSTALL_PREFIX=/install/path
foo@bar:~$ make -j 4 && make install
```
Note that if you already have the correct version of OpenVDB pre-installed, you can configure CMake to link against that library by passing the arguments `-DOPENVDB_BUILD_CORE=OFF -DOPENVDB_BUILD_BINARIES=OFF -DOPENVDB_ROOT=/path/to/openvdb` when invoking `cmake`.
-178
View File
@@ -1,178 +0,0 @@
# Source tree structure {#NanoVDB_SourceTree}
#### Overview of the directory tree of NanoVDB.
* [NanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/NanoVDB.h) C++11 implementation of the core data structure and its access methods.
* [CNanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/CNanoVDB.h) Incomplete but useable C99 implementation of the core data structure and its access methods. Designed in particular for use in OpenCL kernels. Note that this relies on zero-sized arrays for the _reserved padding, so will not work on all compilers (with MSVC being a particular example)
* [PNanoVDB.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/PNanoVDB.h) C99 implementation of the core data structure and its access methods. More complete coverage than CNanoVDB. This version is pointer-less and supports virtually all graphics APIs.
* [GridHandle.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/GridHandle.h) defines a handler for the memory allocated to a NanoVDB grid.
* [io/IO.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/io/IO.h) implements I/O support.
* [tools/CreateNanoGrid.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/tools/CreateNanoGrid.h) defines the converter from OpenVDB to NanoVDB and obviously depends on the OpenVDB library (as the only header file).
* [math/Ray.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/math/Ray.h) Ray class.
* [math/HDDA.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/math/HDDA.h) HDDA related.
* [math/SampleFromVoxels.h](https://github.com/AcademySoftwareFoundation/openvdb/blob/master/nanovdb/nanovdb/math/SampleFromVoxels.h) interpolation.
```bash
foo@bar:~$ tree
.
├── CMakeLists.txt
├── cmd
│ ├── CMakeLists.txt
│ ├── convert
│ │ └── nanovdb_convert.cc
│ ├── print
│ │ └── nanovdb_print.cc
│ ├── updateFiles.sh
│ └── validate
│ └── nanovdb_validate.cc
├── CNanoVDB.h
├── cuda
│ ├── DeviceBuffer.h
│ ├── GridHandle.cuh
│ └── NodeManager.cuh
├── docs
│ ├── CMakeLists.txt
│ ├── codingstyle.txt
│ └── doxygen-config
├── examples
│ ├── CMakeLists.txt
│ ├── ex_bump_pool_buffer
│ │ └── bump_pool_buffer.cc
│ ├── ex_collide_level_set
│ │ ├── common.h
│ │ ├── main.cc
│ │ ├── nanovdb.cu
│ │ └── openvdb.cc
│ ├── ex_index_grid_cuda
│ │ ├── index_grid_cuda.cc
│ │ └── index_grid_cuda_kernel.cu
│ ├── ex_make_custom_nanovdb
│ │ └── make_custom_nanovdb.cc
│ ├── ex_make_custom_nanovdb_cuda
│ │ ├── make_custom_nanovdb_cuda.cc
│ │ └── make_custom_nanovdb_cuda_kernel.cu
│ ├── ex_make_funny_nanovdb
│ │ └── make_funny_nanovdb.cc
│ ├── ex_make_nanovdb_sphere
│ │ └── make_nanovdb_sphere.cc
│ ├── ex_make_typed_grids
│ │ └── make_typed_grids.cc
│ ├── ex_map_pool_buffer
│ │ └── map_pool_buffer.cc
│ ├── ex_modify_nanovdb_thrust
│ │ ├── modify_nanovdb_thrust.cc
│ │ └── modify_nanovdb_thrust.cu
│ ├── ex_nodemanager_cuda
│ │ ├── nodemanager_cuda.cc
│ │ └── nodemanager_cuda_kernel.cu
│ ├── ex_openvdb_to_nanovdb
│ │ └── openvdb_to_nanovdb.cc
│ ├── ex_openvdb_to_nanovdb_accessor
│ │ └── openvdb_to_nanovdb_accessor.cc
│ ├── ex_openvdb_to_nanovdb_cuda
│ │ ├── openvdb_to_nanovdb_cuda.cc
│ │ └── openvdb_to_nanovdb_cuda_kernel.cu
│ ├── ex_raytrace_fog_volume
│ │ ├── common.h
│ │ ├── main.cc
│ │ ├── nanovdb.cu
│ │ └── openvdb.cc
│ ├── ex_raytrace_level_set
│ │ ├── common.h
│ │ ├── main.cc
│ │ ├── nanovdb.cu
│ │ └── openvdb.cc
│ ├── ex_read_nanovdb_sphere
│ │ └── read_nanovdb_sphere.cc
│ ├── ex_read_nanovdb_sphere_accessor
│ │ └── read_nanovdb_sphere_accessor.cc
│ ├── ex_read_nanovdb_sphere_accessor_cuda
│ │ ├── read_nanovdb_sphere_accessor_cuda.cu
│ │ └── read_nanovdb_sphere_accessor_cuda_kernel.cu
│ ├── ex_util
│ │ └── ComputePrimitives.h
│ ├── ex_voxels_to_grid_cuda
│ │ └── ex_voxels_to_grid_cuda.cu
│ ├── ex_vox_to_nanovdb
│ │ ├── vox_to_nanovdb.cc
│ │ └── VoxToNanoVDB.h
│ └── ex_write_nanovdb_grids
│ └── write_nanovdb_grids.cc
├── GridHandle.h
├── HostBuffer.h
├── io
│ └── IO.h
├── math
│ ├── CSampleFromVoxels.h
│ ├── DitherLUT.h
│ ├── HDDA.h
│ ├── Math.h
│ ├── Ray.h
│ ├── SampleFromVoxels.h
│ └── Stencils.h
├── NanoVDB.h
├── NodeManager.h
├── PNanoVDB.h
├── Readme.md
├── tools
│ ├── CreateNanoGrid.h
│ ├── CreatePrimitives.h
│ ├── cuda
│ │ ├── AddBlindData.cuh
│ │ ├── GridChecksum.cuh
│ │ ├── GridStats.cuh
│ │ ├── GridValidator.cuh
│ │ ├── IndexToGrid.cuh
│ │ ├── PointsToGrid.cuh
│ │ └── SignedFloodFill.cuh
│ ├── GridBuilder.h
│ ├── GridChecksum.h
│ ├── GridStats.h
│ ├── GridValidator.h
│ └── NanoToOpenVDB.h
├── unittest
│ ├── CMakeLists.txt
│ ├── pnanovdb_validate_strides.h
│ ├── TestNanoVDB.cc
│ ├── TestNanoVDB.cu
│ └── TestOpenVDB.cc
└── util
├── CpuTimer.h
├── CreateNanoGrid.h
├── cuda
│ ├── CudaAddBlindData.cuh
│ ├── CudaDeviceBuffer.h
│ ├── CudaGridChecksum.cuh
│ ├── CudaGridHandle.cuh
│ ├── CudaGridStats.cuh
│ ├── CudaGridValidator.cuh
│ ├── CudaIndexToGrid.cuh
│ ├── CudaNodeManager.cuh
│ ├── CudaPointsToGrid.cuh
│ ├── CudaSignedFloodFill.cuh
│ ├── CudaUtils.h
│ ├── GpuTimer.h
│ ├── Timer.h
│ └── Util.h
├── DitherLUT.h
├── ForEach.h
├── GridBuilder.h
├── GridChecksum.h
├── GridStats.h
├── GridValidator.h
├── HDDA.h
├── HostBuffer.h
├── Invoke.h
├── IO.h
├── NanoToOpenVDB.h
├── NodeManager.h
├── OpenToNanoVDB.h
├── PrefixSum.h
├── Primitives.h
├── Range.h
├── Ray.h
├── Reduce.h
├── SampleFromVoxels.h
├── Stencils.h
├── Timer.h
└── Util.h
-8
View File
@@ -1,8 +0,0 @@
# NanoVDB {#NanoVDB_MainPage}
Welcome to the NanoVDB documentation page.
* @subpage NanoVDB_HowToBuild
* @subpage NanoVDB_FAQ
* @subpage NanoVDB_SourceTree
* @subpage NanoVDB_HelloWorld
-270
View File
@@ -1,270 +0,0 @@
/**
@page points OpenVDB Points
@section secPtContents Contents
- @ref secPtOverview
- @ref secPtCompression
- @ref secPtLocality
- @ref secPtAttributes
- @ref secPtTypedAttributeArray
- @ref secPtAttributeHandle
- @ref secPtAttributePerformance
- @ref secPtAttributeSet
- @ref secPtPointTree
- @ref secPtPointIndexTree
- @ref secPtPointDataTree
- @ref secPtSparsity
- @ref secPtBackground
- @ref secPtActiveValues
- @ref secPtIndexIterators
- @ref secPtIndexFilters
- @ref secPtSpaceAndTrans
@section secPtOverview Introduction
@anchor openvdbPointsOverview
The @b OpenVDB library can store point data within an OpenVDB hierarchy in two
different ways. A @b PointIndexGrid stores index offsets that reference data
stored in an external linear point array, a @b PointDataGrid stores the points
with attributes directly in the VDB Grid. This document focuses mainly on the
localised style of storage used by @b PointDataGrids. Using this storage
mechanism, points are spatially-organised into VDB voxels to provide faster
access and a greater opportunity for data compression compared with linear point
arrays.
See the @ref openvdbPointsHelloWorld "Cookbook" for code examples to get started
using @b OpenVDB @b Points.
@section secPtCompression Compression
A key motivation behind the library is to increase data compression and thus
reduce the memory and disk space requirements of the point set.
There are three types of compression used in this library to store point
attribute data - (1) @b value @b compression where the codec is selected
specifically based on the intent of the data, (2) @b uniform @b compression
where arrays of identical values can be collapsed down into a single value,
(3) @b stream @b compression where the Blosc stream compressor can be used to
pack and unpack streams of data using a fast, lossless compression codec.
Uniform and stream compression are offered in other applications, notably
Houdini, but with the case of stream compression, used only for disk storage.
Value compression is provided based on the principal that a good general-purpose
compression scheme will usually not be superior to one that is specifically
tuned to the range and intention of how the data will be used. The most commonly
used style of value compression in OpenVDB Points is quantization for point
position data. Floating-point world-space positions will typically use a much
higher accuracy than desired around the origin and a much lower accuracy than
desired far from the origin, which is as a result of the dynamic range used in
floating-point that makes it usable at different orders of magnitude. More
tailored position compression is introduced by splitting positions into an
integer offset provided by the VDB voxels and grid transform and a reduced
precision fixed-point offset from the center of the voxel.
In addition, other attributes such as velocity can benefit from value
compression. For example, a unit vector scheme can compress a 3 x float vector
(12 bytes) into just 2 bytes.
@section secPtLocality Locality
Data compression isn't the only area to benefit from a spatially organised data
set. Due to the effects of L1 and L2 caching in modern CPUs, improved cache
locality through storing point data close in memory to their neighbors can bring
about a big improvement in performance.
A number of point rasterization gather-style tests that compared spatially
organised data with randomly organised linear data when dereferenced using a
spatial acceleration structure consistently resulted in a performance
improvement of between 2x and 3x.
@section secPtAttributes Attributes
Attribute storage is provided as an independent toolset within the library to
allow for use outside of OpenVDB grids.
@subsection secPtTypedAttributeArray TypedAttributeArray
The TypedAttributeArray stores array data with a specified value type and
compression codec, which form the template signature.
@code
template<typename ValueType, typename Codec>
class TypedAttributeArray: public AttributeArray
@endcode
The base AttributeArray class from which the TypedAttributeArray derives is not
templated and can be used for all non-typed operations such as serialization.
Here is an example of floating-point scalar attribute storage using a truncation
codec to reduce the footprint from 32-bit to 16-bit:
@code
openvdb::points::TypedAttributeArray<float, openvdb::points::TruncateCodec>
@endcode
@subsection secPtAttributeHandle AttributeHandle
AttributeHandle and AttributeWriteHandle classes provide access to the array
data without requiring knowledge of the codec. This is important as it can allow
users to add their own attribute compression schemes without requiring any
modification to existing code.
AttributeHandles provide benefits to memory usage in allowing data to be packed
and unpacked efficiently when using stream compression. When compressed with a
stream compression scheme, the AttributeHandle unpacks attribute data into a
local (uncompressed) buffer on access and discards this temporary data once the
AttributeHandle is destroyed. This has the benefit of retaining the stream
compression during access which lowers the peak memory substantially.
This is how to create a float AttributeHandle bound to a specific attribute in
a leaf:
@code
auto handle = AttributeHandle<float>::create(leaf->constAttributeArray("attribute_name"));
@endcode
Note that ensuring const access to the attribute array will prevent redundant
copying when using a read-only handle.
@subsection secPtAttributePerformance TypedAttributeArray vs AttributeHandle
One key benefit of AttributeHandles is that they ensure the data being accessed
has been uncompressed and is in-core on creation of the handle to avoid the need
to perform these checks when the data is being accessed and modified for
improved performance. An AttributeHandle may also be provided a specific codec
if known to eliminate the indirection cost.
@subsection secPtAttributeSet AttributeSet and Descriptor
The AttributeSet stores a collection of attribute arrays along with a Descriptor
that tracks the type of each of the attribute arrays.
In typical use cases, the Descriptor is shared amongst leaf nodes with many of
the algorithms making this assumption for performance reasons. However, it is
still possible to configure the data so that leaf nodes in the same grid can use
different Descriptors with different numbers and types of attributes. A typical
use-case for this might be to reduce precision of an attribute further from a
camera where accuracy is deemed less important and can be traded for a reduced
memory or disk footprint.
@section secPtPointTree The Point Tree
@subsection secPtPointIndexTree Point Index Tree
As mentioned in the introduction, the PointIndexTree is a structure in OpenVDB
that stores an array of offset indices to a linear point array in the leaf
nodes. In constrast, the PointDataTree stores the actual data localised in the
leaf nodes.
The PointIndexTree has this tree configuration:
@code
typedef tree::Tree4<PointIdx32, 5, 4, 3>::Type PointIndexTree;
@endcode
@subsection secPtPointDataTree Point Data Tree
The PointDataTree has this tree configuration:
@code
typedef tree::Tree4<PointDataIdx32, 5, 4, 3>::Type PointDataTree;
@endcode
Note that with both the PointIndexTree and the PointDataTree, the data type is
actually a 32-bit unsigned integer, but it is provided in this form to
distinguish it from other LeafNodes that store the same data type. None of the
other components within the Tree or Grid hierarchy change. It is for this reason
that many of the existing features of OpenVDB such as serialization work without
requiring additional functionality in OpenVDB.
@section secPtSparsity Voxel Values
For the PointDataTree, the voxel values represent the end position in the linear
attribute arrays attached to each LeafNode. Using the value of the previous
voxel (zero for the first voxel), the offset for the start position can be
deduced.
@subsection secPtBackground Background and Tile Values
There are three distinct ways of storing data in an OpenVDB tree:
<B>voxel values</B>, <B>tile values</B>, and a <B>background value</B>.
Unfortunately the background value and tile values make little sense for point
data. While technically it would be valid to use a non-zero background value and
tile value, this would simply mean that only the first voxel in the LeafNode
contains points which is neither an efficient storage mechanism nor particularly
common. For this reason, the LeafNode constructor may take a background value
but it is internally overriden to be zero on construction.
@subsection secPtActiveValues Active Values
Any voxel or tile can be classified as either @b active or @b inactive. The
interpretation of this state is application-specific, however there are some
conventions, such as using the active state to denote the narrow band in a
levelset. For points, the most intuitive use of the active state is to mark a
voxel as active if it contains points and inactive otherwise. This allows
iteration over the points in a LeafNode to be accelerated to only iterate over
voxels that contain points.
@subsection secPtIndexIterators Index Iterators
@anchor openvdbPointsIterators
An index iterator contains a value iterator and an index filter, however the
most common usage is provided by the convenience methods on the leaf node:
@code
auto iterAll = leaf.beginIndexAll();
auto iterOn = leaf.beginIndexOn();
auto iterOff = leaf.beginIndexOff();
for (; iterOn; ++iterOn) {
Index32 index = *iterOn;
}
@endcode
These are analagous to the value iterators in the LeafNode and are creating an
index iterator that wraps the value iterator together with a null filter.
It is also possible to iterate over indices within a specific voxel by using the
beginIndexVoxel convenience method on the leaf:
@code
auto iterVoxel = leaf.beginIndexVoxel(ijk);
@endcode
For performance and simplicity, it is recommended to use the all/on/off index
iterators where possible, as these hide the explicit voxel iteration from the
user meaning it is only necessary to iterate over the indices within the leaf.
It is also possible to retrieve the voxel coordinate from the index iterator
directly.
@subsection secPtIndexFilters Index Filters
Index filters provide an easy way of only iterating over indices that match a
set criteria. One such index filter provided by the library is to iterate over
the points within a group:
@code
openvdb::points::GroupFilter filter("test_point_group");
auto iter = leaf.beginIndexOn(filter);
@endcode
As the index iterator is templated on the filter, it's possible to construct
filters that do relatively complicated operations provided they meet the basic
interface requirements of an IndexFilter.
@section secPtSpaceAndTrans Voxel Space, Index Space, World Space
Points are stored in @b voxel @b space, meaning all point positions lie between
(-0.5, -0.5, -0.5) and (0.5, 0.5, 0.5) with the center of the voxel being
(0.0, 0.0, 0.0). The position of the point can be extracted in @b index @b space
by adding the voxel space position to the ijk value of the voxel. The position
of the point can be extracted in @b world @b space by using the grid transform
to do an indexToWorld conversion.
See the @ref openvdbPointsHelloWorld "Cookbook" for code examples to get started
using @b OpenVDB @b Points.
*/
-650
View File
@@ -1,650 +0,0 @@
/**
@page python Using OpenVDB in Python
This section describes the OpenVDB Python module and includes Python code
snippets and some complete programs that illustrate how to perform common tasks.
The Python module exposes most of the functionality of the C++
@vdblink::Grid Grid@endlink class, including I/O, metadata
management, voxel access and iteration, but almost none of the many
@ref secToolUtils "tools".
We expect to add support for tools in forthcoming releases.
The Python module supports a fixed set of grid types.
If the symbol @c PY_OPENVDB_WRAP_ALL_GRID_TYPES is defined at compile time,
most of the grid types declared in openvdb.h are accessible in Python,
otherwise only @b FloatGrid, @b BoolGrid and @b Vec3SGrid are accessible.
To add support for grids with other value types or configurations,
search for @c PY_OPENVDB_WRAP_ALL_GRID_TYPES 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 <tt>.vdb</tt> files
or pickled will not be readable by clients using the standard version
of the module.
Also note that the @vdblink::tree::Tree Tree@endlink class is not exposed
in Python.
Much of its functionality is either available through the
@vdblink::Grid Grid@endlink 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, which returns a new grid that shares
its tree with the original grid, @b deepCopy, which returns a new grid
that owns its own tree, and @b sharesWith, which reports whether two grids
share a tree.
@section sPyContents Contents
- @ref sPyBasics
- @ref sPyHandlingMetadata
- @ref sPyAccessors
- @ref sPyIteration
- @ref sPyNumPy
- @ref sPyMeshConversion
- @ref sPyCppAPI
@section sPyBasics Getting started
The following example is a complete program that illustrates some of the
basic steps to create grids and write them to disk:
@code{.py}
import pyopenvdb as vdb
# A grid comprises a sparse tree representation of voxel data,
# user-supplied metadata and a voxel space to world space transform,
# which defaults to the identity transform.
# A FloatGrid stores one single-precision floating point value per voxel.
# Other grid types include BoolGrid and Vec3SGrid. The module-level
# attribute pyopenvdb.GridTypes gives the complete list.
cube = vdb.FloatGrid()
cube.fill(min=(100, 100, 100), max=(199, 199, 199), value=1.0)
# Name the grid "cube".
cube.name = 'cube'
# Populate another FloatGrid with a sparse, narrow-band level set
# representation of a sphere with radius 50 voxels, located at
# (1.5, 2, 3) in index space.
sphere = vdb.createLevelSetSphere(radius=50, center=(1.5, 2, 3))
# Associate some metadata with the grid.
sphere['radius'] = 50.0
# Associate a scaling transform with the grid that sets the voxel size
# to 0.5 units in world space.
sphere.transform = vdb.createLinearTransform(voxelSize=0.5)
# Name the grid "sphere".
sphere.name = 'sphere'
# Write both grids to a VDB file.
vdb.write('mygrids.vdb', grids=[cube, sphere])
@endcode
This example shows how to read grids from files, and some ways to modify
grids:
@code{.py}
import pyopenvdb as vdb
# Read a .vdb file and return a list of grids populated with
# their metadata and transforms, but not their trees.
filename = 'mygrids.vdb'
grids = vdb.readAllGridMetadata(filename)
# Look for and read in a level-set grid that has certain metadata.
sphere = None
for grid in grids:
if (grid.gridClass == vdb.GridClass.LEVEL_SET and 'radius' in grid
and grid['radius'] > 10.0):
sphere = vdb.read(filename, grid.name)
else:
print 'skipping grid', grid.name
if sphere:
# Convert the level set sphere to a narrow-band fog volume, in which
# interior voxels have value 1, exterior voxels have value 0, and
# narrow-band voxels have values varying linearly from 0 to 1.
outside = sphere.background
width = 2.0 * outside
# Visit and update all of the grid's active values, which correspond to
# voxels in the narrow band.
for iter in sphere.iterOnValues():
dist = iter.value
iter.value = (outside - dist) / width
# Visit all of the grid's inactive tile and voxel values and update
# the values that correspond to the interior region.
for iter in sphere.iterOffValues():
if iter.value < 0.0:
iter.value = 1.0
iter.active = False
# Set exterior voxels to 0.
sphere.background = 0.0
sphere.gridClass = vdb.GridClass.FOG_VOLUME
@endcode
@section sPyHandlingMetadata Handling metadata
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,&nbsp;value) pairs or, in the case of grids, through
a dictionary-like interface.
Add (name,&nbsp;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.
@code{.py}
>>> import pyopenvdb as vdb
>>> grid = vdb.Vec3SGrid()
>>> grid['vector'] = 'gradient'
>>> grid['radius'] = 50.0
>>> grid['center'] = (10, 15, 10)
>>> grid.metadata
{'vector': 'gradient', 'radius': 50.0, 'center': (10, 15, 10)}
>>> grid['radius']
50.0
>>> 'radius' in grid, 'misc' in grid
(True, False)
# OK to overwrite an existing value with a value of another type:
>>> grid['center'] = 0.0
# A 4-element sequence is not a supported metadata value type:
>>> grid['center'] = (0, 0, 0, 0)
File "<stdin>", line 1, in <module>
TypeError: metadata value "(0, 0, 0, 0)" of type tuple is not allowed
# Metadata names must be strings:
>>> grid[0] = (10.5, 15, 30)
File "<stdin>", line 1, in <module>
TypeError: expected str, found int as argument 1 to __setitem__()
@endcode
Alternatively, replace all or some of a grid&rsquo;s metadata by supplying
a (name,&nbsp;value) dictionary:
@code{.py}
>>> metadata = {
... 'vector': 'gradient',
... 'radius': 50.0,
... 'center': (10, 15, 10)
... }
# Replace all of the grid's metadata.
>>> grid.metadata = metadata
>>> metadata = {
... 'center': [10.5, 15, 30],
... 'scale': 3.14159
... }
# Overwrite "center" and add "scale":
>>> grid.updateMetadata(metadata)
@endcode
Iterate over a grid&rsquo;s metadata as you would over a dictionary:
@code{.py}
>>> for key in grid:
... print '%s = %s' % (key, grid[key])
...
vector = gradient
radius = 50.0
scale = 3.14159
center = (10.5, 15.0, 30.0)
@endcode
Removing metadata is also straightforward:
@code{.py}
>>> del grid['vector']
>>> del grid['center']
>>> del grid['vector'] # error: already removed
File "<stdin>", line 1, in <module>
KeyError: 'vector'
>>> grid.metadata = {} # remove all metadata
@endcode
Some grid metadata is exposed in the form of properties, either because
it might be frequently accessed (a grid&rsquo;s name, for example)
or because its allowed values are somehow restricted:
@code{.py}
>>> grid = vdb.createLevelSetSphere(radius=10.0)
>>> grid.metadata
{'class': 'level set'}
>>> grid.gridClass = vdb.GridClass.FOG_VOLUME
>>> grid.metadata
{'class': 'fog volume'}
# The gridClass property requires a string value:
>>> grid.gridClass = 123
File "<stdin>", line 1, in <module>
TypeError: expected str, found int as argument 1 to setGridClass()
# Only certain strings are recognized; see pyopenvdb.GridClass
# for the complete list.
>>> grid.gridClass = 'Hello, world.'
>>> grid.metadata
{'class': 'unknown'}
>>> grid.metadata = {}
>>> grid.vectorType = vdb.VectorType.COVARIANT
>>> grid.metadata
{'vector_type': 'covariant'}
>>> grid.name = 'sphere'
>>> grid.creator = 'Python'
>>> grid.metadata
{'vector_type': 'covariant', 'name': 'sphere', 'creator': 'Python'}
@endcode
Setting these properties to @c None removes the corresponding metadata,
but the properties retain default values:
@code{.py}
>>> grid.creator = grid.vectorType = None
>>> grid.metadata
{'name': 'sphere'}
>>> grid.creator, grid.vectorType
('', 'invariant')
@endcode
Metadata can be associated with a <tt>.vdb</tt> file at the time the file
is written, by supplying a (name,&nbsp;value) dictionary
as the optional @c metadata argument to the @b write function:
@code{.py}
>>> metadata = {
... 'creator': 'Python',
... 'time': '11:05:00'
... }
>>> vdb.write('mygrids.vdb', grids=grid, metadata=metadata)
@endcode
File-level metadata can be retrieved with either the @b readMetadata
function or the @b readAll function:
@code{.py}
>>> metadata = vdb.readMetadata('mygrids.vdb')
>>> metadata
{'creator': 'Python', 'time': '11:05:00'}
>>> grids, metadata = vdb.readAll('mygrids.vdb')
>>> metadata
{'creator': 'Python', 'time': '11:05:00'}
>>> [grid.name for grid in grids]
['sphere']
@endcode
@section sPyAccessors Voxel access
Grids provide read-only and read/write accessors for voxel lookup via @ijk
index coordinates.
Accessors store references to their parent grids, so a grid will not
be deleted while it has accessors in use.
@code{.py}
>>> import pyopenvdb as vdb
# Read two grids from a file.
>>> grids, metadata = vdb.readAll('smoke2.vdb')
>>> [grid.name for grid in grids]
['density', 'v']
# Get read/write accessors to the two grids.
>>> dAccessor = grids[0].getAccessor()
>>> vAccessor = grids[1].getAccessor()
>>> ijk = (100, 103, 101)
>>> dAccessor.probeValue(ijk)
(0.17614534497261047, True)
# Change the value of a voxel.
>>> dAccessor.setValueOn(ijk, 0.125)
>>> dAccessor.probeValue(ijk)
(0.125, True)
>>> vAccessor.probeValue(ijk)
((-2.90625, 9.84375, 0.84228515625), True)
# Change the active state of a voxel.
>>> vAccessor.setActiveState(ijk, False)
>>> vAccessor.probeValue(ijk)
((-2.90625, 9.84375, 0.84228515625), False)
# Get a read-only accessor to one of the grids.
>>> dAccessor = grids[0].getConstAccessor()
>>> dAccessor.setActiveState(ijk, False)
File "<stdin>", line 1, in <module>
TypeError: accessor is read-only
# Delete the accessors once they are no longer needed,
# so that the grids can be garbage-collected.
>>> del dAccessor, vAccessor
@endcode
@section sPyIteration Iteration
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.
@code{.py}
>>> import pyopenvdb as vdb
>>> grid = vdb.read('smoke2.vdb', gridname='v')
>>> grid.__class__.__name__
'Vec3SGrid'
# Iterate over inactive values and print the coordinates of the first
# five voxel values and the bounding boxes of the first five tile values.
>>> voxels = tiles = 0
... N = 5
... for item in grid.citerOffValues(): # read-only iterator
... if voxels == N and tiles == N:
... break
... if item.count == 1:
... if voxels < N:
... voxels += 1
... print 'voxel', item.min
... else:
... if tiles < N:
... tiles += 1
... print 'tile', item.min, item.max
...
tile (0, 0, 0) (7, 7, 7)
tile (0, 0, 8) (7, 7, 15)
tile (0, 0, 16) (7, 7, 23)
tile (0, 0, 24) (7, 7, 31)
tile (0, 0, 32) (7, 7, 39)
voxel (40, 96, 88)
voxel (40, 96, 89)
voxel (40, 96, 90)
voxel (40, 96, 91)
voxel (40, 96, 92)
# Iterate over and normalize all active values.
>>> from math import sqrt
>>> for item in grid.iterOnValues(): # read/write iterator
... vector = item.value
... magnitude = sqrt(sum(x * x for x in vector))
... item.value = [x / magnitude for x in vector]
...
@endcode
For some operations, it might be more convenient to use one of
the grid methods @b mapOn, @b mapOff or @b mapAll.
These methods iterate over a grid&rsquo;s tiles and voxels
(active, inactive or both, respectively) and replace each value <i>x</i>
with <i>f</i>(<i>x</i>), where <i>f</i> is a callable object.
These methods are not multithreaded.
@code{.py}
>>> import pyopenvdb as vdb
>>> from math import sqrt
>>> grid = vdb.read('smoke2.vdb', gridname='v')
>>> def normalize(vector):
... magnitude = sqrt(sum(x * x for x in vector))
... return [x / magnitude for x in vector]
...
>>> grid.mapOn(normalize)
@endcode
Similarly, the @b combine method iterates over corresponding pairs of values
(tile and voxel) of two grids @e A and @e B of the same type
(<b>FloatGrid</b>, <b>Vec3SGrid</b>, etc.), replacing values in @e A
with <i>f</i>(<i>a</i>, <i>b</i>), where <i>f</i> is a callable object.
This operation assumes that index coordinates @ijk in both grids correspond
to the same physical, world space location.
Also, the operation always leaves grid @e B empty.
@code{.py}
>>> import pyopenvdb as vdb
>>> density = vdb.read('smoke2.vdb', gridname='density')
>>> density.__class__.__name__
'FloatGrid'
>>> sphere = vdb.createLevelSetSphere(radius=50.0, center=(100, 300, 100))
>>> density.combine(sphere, lambda a, b: min(a, b))
@endcode
For now, @b combine operates only on tile and voxel values,
not on their active states or other attributes.
@section sPyNumPy Working with NumPy arrays
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 and @b copyToArray 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.
@code{.py}
>>> import pyopenvdb as vdb
>>> import numpy
>>> array = numpy.random.rand(200, 200, 200)
>>> array.dtype
dtype('float64')
# Copy values from a three-dimensional array of doubles
# into a grid of floats.
>>> grid = vdb.FloatGrid()
>>> grid.copyFromArray(array)
>>> grid.activeVoxelCount() == array.size
True
>>> grid.evalActiveVoxelBoundingBox()
((0, 0, 0), (199, 199, 199))
# Copy values from a four-dimensional array of ints
# into a grid of float vectors.
>>> vecarray = numpy.ndarray((60, 70, 80, 3), int)
>>> vecarray.fill(42)
>>> vecgrid = vdb.Vec3SGrid()
>>> vecgrid.copyFromArray(vecarray)
>>> vecgrid.activeVoxelCount() == 60 * 70 * 80
True
>>> vecgrid.evalActiveVoxelBoundingBox()
((0, 0, 0), (59, 69, 79))
@endcode
When copying from a NumPy array, values in the array that are equal to
the destination grid&rsquo;s background value (or close to it, if the
@c tolerance argument to @b copyFromArray is nonzero) are set to the
background value and are marked inactive.
All other values are marked active.
@code{.py}
>>> grid.clear()
>>> grid.copyFromArray(array, tolerance=0.2)
>>> print '%d%% of copied voxels are active' % (
... round(100.0 * grid.activeVoxelCount() / array.size))
80% of copied voxels are active
@endcode
The optional @c ijk argument specifies the index coordinates of the voxel
in the destination grid into which to start copying values.
That is, array index (0,&nbsp;0,&nbsp;0) maps to voxel @ijk.
@code{.py}
>>> grid.clear()
>>> grid.copyFromArray(array, ijk=(-1, 2, 3))
>>> grid.evalActiveVoxelBoundingBox()
((-1, 2, 3), (198, 201, 202))
@endcode
The @b copyToArray method also accepts an @c ijk argument.
It specifies the index coordinates of the voxel to be copied to array
index (0,&nbsp;0,&nbsp;0).
@code{.py}
>>> grid = vdb.createLevelSetSphere(radius=10.0)
>>> array = numpy.ndarray((40, 40, 40), int)
>>> array.fill(0)
# Copy values from a grid of floats into
# a three-dimensional array of ints.
>>> grid.copyToArray(array, ijk=(-15, -20, -35))
>>> array[15, 20]
array([ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 2, 1, 0, -1, -2, -3, -3,
-3, -3, -3, -3, -3, -3, -3, -3, -3, -3])
@endcode
@b copyToArray has no @c tolerance argument, because there is no distinction
between active and inactive values in the destination array.
@section sPyMeshConversion Mesh conversion
Also available if the OpenVDB Python module is compiled with NumPy support
(see @ref sPyNumPy "above") are grid methods to convert polygonal meshes to
level sets (see @vdblink::tools::meshToLevelSet() tools::meshToLevelSet@endlink
for some restrictions) and to convert isosurfaces of scalar-valued grids
to meshes.
@code{.py}
>>> import pyopenvdb as vdb
>>> import numpy
>>> grid = vdb.read('bunny.vdb', 'ls_bunny')
# Convert a volume to a quadrilateral mesh.
>>> points, quads = grid.convertToQuads()
# World-space vertices of the mesh:
>>> points
array([[-14.05082607, -0.10118673, -0.40250054],
[-14.05230808, -0.05570767, -0.45693323],
[-14.05613995, -0.0734246 , -0.42150033],
...,
[ 7.25201273, 13.25417805, 6.45283508],
[ 7.25596714, 13.31225586, 6.40827513],
[ 7.30518484, 13.21096039, 6.40724468]], dtype=float32)
# Quadrilateral faces of the mesh, given by
# 4-tuples of indices into the vertex list:
>>> quads
array([[ 5, 2, 1, 4],
[ 11, 7, 6, 10],
[ 14, 9, 8, 13],
...,
[1327942, 1327766, 1339685, 1339733],
[1339728, 1327921, 1327942, 1339733],
[1339733, 1339685, 1339661, 1339728]], dtype=uint32)
# Convert the mesh back to a (single-precision) volume.
# Give the resulting grid the original grid's transform.
>>> gridFromQuads = vdb.FloatGrid.createLevelSetFromPolygons(
... points, quads=quads, transform=grid.transform)
# Alternatively, mesh a volume adaptively for a lower polygon count.
# Adaptive meshing generates both triangular and quadrilateral faces.
>>> points, triangles, quads = grid.convertToPolygons(adaptivity=0.5)
# World-space vertices of the mesh:
>>> points
array([[-14.02906322, -0.07213751, -0.49265194],
[-14.11877823, -0.11127799, -0.17118289],
[-13.85006142, -0.08145611, -0.86669081],
...,
[ 7.31098318, 12.97358608, 6.55133963],
[ 7.20240211, 12.80632019, 6.80356836],
[ 7.23679161, 13.28100395, 6.45595646]], dtype=float32)
# Triangular faces of the mesh, given by
# triples of indices into the vertex list:
>>> triangles
array([[ 8, 7, 0],
[ 14, 9, 8],
[ 14, 11, 9],
...,
[22794, 22796, 22797],
[22784, 22783, 22810],
[22796, 22795, 22816]], dtype=uint32)
# Quadrilateral faces of the mesh, given by
# 4-tuples of indices into the vertex list:
>>> quads
array([[ 4, 3, 6, 5],
[ 8, 9, 10, 7],
[ 11, 12, 10, 9],
...,
[23351, 23349, 23341, 23344],
[23344, 23117, 23169, 23351],
[23169, 23167, 23349, 23351]], dtype=uint32)
# Convert the mesh to a double-precision volume.
>>> doubleGridFromPolys = vdb.DoubleGrid.createLevelSetFromPolygons(
... points, triangles, quads, transform=grid.transform)
@endcode
The mesh representation is similar to that of the commonly-used
<a href="http://en.wikipedia.org/wiki/Wavefront_.obj_file">
Wavefront&nbsp;<tt>.obj</tt></a> file format,
except that the vertex array is indexed starting from 0 rather than 1.
To output mesh data to a file in <tt>.obj</tt> format, one might do
the following:
@code{.py}
>>> def writeObjFile(filename, points, triangles=[], quads=[]):
... f = open(filename, 'w')
... # Output vertices.
... for xyz in points:
... f.write('v %g %g %g\n' % tuple(xyz))
... f.write('\n')
... # Output faces.
... for ijk in triangles:
... f.write('f %d %d %d\n' %
... (ijk[0]+1, ijk[1]+1, ijk[2]+1)) # offset vertex indices by one
... for ijkl in quads:
... f.write('f %d %d %d %d\n' %
... (ijkl[0]+1, ijkl[1]+1, ijkl[2]+1, ijkl[3]+1))
... f.close()
...
>>> mesh = grid.convertToPolygons(adaptivity=0.8)
>>> writeObjFile('bunny.obj', *mesh)
@endcode
@section sPyCppAPI C++ glue routines
Python objects of type @b FloatGrid, @b Vec3SGrid, etc. are backed by
C structs that &ldquo;inherit&rdquo; from @c PyObject.
The OpenVDB Python extension module includes public functions that you can
call in your own extension modules to convert between
@vdblink::Grid openvdb::Grids@endlink and <tt>PyObject</tt>s.
See the pyopenvdb.h reference for a description of these functions
and a usage example.
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 @c RTLD_GLOBAL
flag when importing the OpenVDB module, to allow its symbols to be shared
across modules.
See @b setdlopenflags in the Python @b sys module for one way to do this.
*/
+28
View File
@@ -0,0 +1,28 @@
# *ƒ*(VDB)
## A New Home for ƒVDB
:warning: The public home for fVDB development is now located in the Academy Software Foundation OpenVDB Github Organization [https://github.com/openvdb](https://github.com/openvdb). :warning:
All of the code and history for fVDB on the OpenVDB `feature/fvdb` branch has been moved to repositories in the OpenVDB Github Organization. In order to encourage movement to fVDB's new home in the OpenVDB Github Organization, we have removed the code from the head of this branch but the history remains.
The components of fVDB have been split into the following repositories:
### [fvdb-core](https://github.com/openvdb/fvdb-core)
The fvdb-core repository houses the core library and PyTorch extension for ƒVDB. ƒVDB is a framework that provides differentiable, sparse volumetric operators built on top of NanoVDB and enables PyTorch users to utilize the NanoVDB data structure to build powerful and scalable spatial intelligence applications.
### [fvdb-examples](https://github.com/openvdb/fvdb-examples)
The fvdb-examples repository contains examples of how to use the ƒVDB library to build spatial intelligence networks or pipelines. These are provided as reference for how to implement interesting or well-known methods and networks on top of ƒVDB including examples of pipelines that perform panoptic segmentation and depth reconstruction.
### [fvdb-reality-capture](https://github.com/openvdb/fvdb-reality-capture)
The fvdb-reality-capture repository contains examples of how to use the ƒVDB library to build reality capture pipelines centered on ƒVDB's 3D Gaussian splatting methods. This repository houses utilities and examples that illustrate how to train and render 3D Gaussian splatting models using ƒVDB as well as interesting methods that build upon the 3D Gaussian scene representation such as meshing.
### [nanovdb-editor](https://github.com/openvdb/nanovdb-editor)
The nanovdb-editor repository contains a library, python bindings and a standalone GUI application that allows you to view and edit NanoVDB. nanovdb-editor also provides viewer functionality for fVDB.
-363
View File
@@ -1,363 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
CMake Configuration for NanoVDB
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
project(NanoVDB LANGUAGES C CXX)
include(GNUInstallDirs)
###############################################################################
message(STATUS "----------------------------------------------------")
message(STATUS "--------------- Configuring NanoVDB ----------------")
message(STATUS "----------------------------------------------------")
###############################################################################
# add options
###############################################################################
option(NANOVDB_BUILD_TOOLS "Build command-line tools" ON)
option(NANOVDB_BUILD_UNITTESTS "Build Unit tests" OFF)
option(NANOVDB_BUILD_EXAMPLES "Build examples" OFF)
#option(NANOVDB_BUILD_BENCHMARK "Build benchmark in examples" OFF)
option(NANOVDB_BUILD_PYTHON_MODULE "Build the nanovdb Python module" OFF)
option(NANOVDB_USE_INTRINSICS "Build with hardware intrinsics support" OFF)
option(NANOVDB_USE_CUDA "Build with CUDA support" OFF)
option(NANOVDB_CUDA_KEEP_PTX "Keep CUDA PTX" OFF)
option(NANOVDB_USE_OPENVDB "Build with OpenVDB support" OFF)
option(NANOVDB_USE_BLOSC "Build with BLOSC support" ${USE_BLOSC})
option(NANOVDB_USE_ZLIB "Build with ZLIB support" ${USE_ZLIB})
option(NANOVDB_USE_TBB "Build with TBB support" ${USE_TBB})
option(NANOVDB_USE_MAGICAVOXEL "Build with MagicaVoxel support" OFF)
option(NANOVDB_ALLOW_FETCHCONTENT
"Allow FetchContent to download missing dependencies" OFF)
###############################################################################
# sanitize user input
if(NANOVDB_USE_OPENVDB)
if(NOT NANOVDB_USE_TBB)
message(FATAL_ERROR "Invalid CMake build configuration:
NANOVDB_USE_OPENVDB : [ON]
NANOVDB_USE_TBB : [OFF]
If you are linking NanoVDB against OpenVDB, then you
need to use TBB, (i.e. -DNANOVDB_USE_TBB=ON).")
endif()
endif()
###############################################################################
enable_testing()
# Add our cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake")
if(UNIX)
# For CMake's find Threads module which brings in pthread - This flag
# forces the compiler -pthread flag vs -lpthread
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
endif()
#if(NANOVDB_BUILD_UNITTESTS OR NANOVDB_BUILD_BENCHMARK)
if(NANOVDB_BUILD_UNITTESTS)
find_package(GTest ${MINIMUM_GOOGLETEST_VERSION} REQUIRED)
endif()
if(NANOVDB_USE_CUDA)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# Allow the user to provide CMAKE_CUDA_ARCHITECTURES
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 75)
endif()
enable_language(CUDA)
set(NANOVDB_CUDA_EXTENDED_LAMBDA "--expt-extended-lambda")
if(CUDA_VERSION_MAJOR GREATER_EQUAL 11)
set(NANOVDB_CUDA_EXTENDED_LAMBDA "--extended-lambda")
endif()
set(CMAKE_CUDA_FLAGS "${NANOVDB_CUDA_EXTENDED_LAMBDA} -use_fast_math -lineinfo ${CMAKE_CUDA_FLAGS}")
# workaround for win32 bug when nvcc "--keep" is used.
if(WIN32)
if(NANOVDB_CUDA_KEEP_PTX)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/Release")
set(CMAKE_CUDA_FLAGS_RELEASE
" --source-in-ptx --keep ${CMAKE_CUDA_FLAGS_RELEASE}")
endif()
endif()
if(MSVC)
# If a CMAKE_MSVC_RUNTIME_LIBRARY has not been provided and we're building
# against openvdb, match the CRT that openvdb has been built against. This
# setting is automatically propagated to CXX files but not CUDA sources, so
# the VDB_MSVC_RUNTIME_SELECTION variables is used on targets with .cu files
if(NOT CMAKE_MSVC_RUNTIME_LIBRARY AND NANOVDB_USE_OPENVDB AND OPENVDB_BUILD_CORE)
get_target_property(VDB_MSVC_RUNTIME_SELECTION openvdb MSVC_RUNTIME_LIBRARY)
endif()
endif()
find_package(CUDAToolkit)
endif()
if(NANOVDB_USE_OPENVDB)
if(NOT OPENVDB_BUILD_CORE AND NOT TARGET OpenVDB::openvdb)
find_package(OpenVDB REQUIRED COMPONENTS openvdb)
endif()
endif()
if(NANOVDB_USE_TBB AND NOT TARGET TBB::tbb)
find_package(TBB ${MINIMUM_TBB_VERSION} REQUIRED)
endif()
if(NANOVDB_USE_BLOSC AND NOT TARGET Blosc::blosc)
find_package(Blosc ${MINIMUM_BLOSC_VERSION} REQUIRED)
endif()
if(NANOVDB_USE_ZLIB AND NOT TARGET ZLIB::ZLIB)
find_package(ZLIB ${MINIMUM_ZLIB_VERSION} REQUIRED)
endif()
if(NANOVDB_USE_MAGICAVOXEL)
if(NANOVDB_ALLOW_FETCHCONTENT)
if(NOT ogt_POPULATED)
message(STATUS "Downloading ogt...")
FetchContent_Declare(
ogt
GIT_REPOSITORY https://github.com/jpaver/opengametools.git
GIT_TAG master)
FetchContent_GetProperties(ogt)
if(NOT ogt_POPULATED)
FetchContent_Populate(ogt)
set(NANOVDB_OGT_INCLUDE_DIRECTORY ${ogt_SOURCE_DIR}/src)
endif()
endif()
endif()
endif()
###############################################################################
# Installation
###############################################################################
# NanoVDB header files
set(NANOVDB_INCLUDE_FILES
CNanoVDB.h
GridHandle.h
HostBuffer.h
NanoVDB.h
NodeManager.h
PNanoVDB.h
)
# NanoVDB cuda header files
set(NANOVDB_INCLUDE_CUDA_FILES
cuda/DeviceBuffer.h
cuda/DeviceStreamMap.h
cuda/GridHandle.cuh
cuda/NodeManager.cuh
cuda/UnifiedBuffer.h
)
# NanoVDB io header files
set(NANOVDB_INCLUDE_IO_FILES
io/IO.h
)
# NanoVDB math header files
set(NANOVDB_INCLUDE_MATH_FILES
math/CSampleFromVoxels.h
math/DitherLUT.h
math/HDDA.h
math/Math.h
math/Ray.h
math/SampleFromVoxels.h
math/Stencils.h
)
# NanoVDB tools header files
set(NANOVDB_INCLUDE_TOOLS_FILES
tools/CreateNanoGrid.h
tools/CreatePrimitives.h
tools/GridBuilder.h
tools/GridChecksum.h
tools/GridStats.h
tools/GridValidator.h
tools/NanoToOpenVDB.h
)
# NanoVDB tools/cuda header files
set(NANOVDB_INCLUDE_TOOLS_CUDA_FILES
tools/cuda/AddBlindData.cuh
tools/cuda/GridChecksum.cuh
tools/cuda/GridStats.cuh
tools/cuda/GridValidator.cuh
tools/cuda/IndexToGrid.cuh
tools/cuda/PointsToGrid.cuh
tools/cuda/SignedFloodFill.cuh
)
# NanoVDB util header files
set(NANOVDB_INCLUDE_UTIL_FILES
util/CpuTimer.h
util/CreateNanoGrid.h
util/DitherLUT.h
util/ForEach.h
util/GridBuilder.h
util/GridChecksum.h
util/GridStats.h
util/GridValidator.h
util/HDDA.h
util/HostBuffer.h
util/Invoke.h
util/IO.h
util/NanoToOpenVDB.h
util/NodeManager.h
util/OpenToNanoVDB.h
util/PrefixSum.h
util/Primitives.h
util/Range.h
util/Ray.h
util/Reduce.h
util/SampleFromVoxels.h
util/Stencils.h
util/Timer.h
util/Util.h
)
# NanoVDB util/cuda header files
set(NANOVDB_INCLUDE_UTIL_CUDA_FILES
util/cuda/CudaAddBlindData.cuh
util/cuda/CudaGridHandle.cuh
util/cuda/CudaIndexToGrid.cuh
util/cuda/CudaSignedFloodFill.cuh
util/cuda/Timer.h
util/cuda/CudaDeviceBuffer.h
util/cuda/CudaGridStats.cuh
util/cuda/CudaNodeManager.cuh
util/cuda/CudaUtils.h
util/cuda/Util.h
util/cuda/CudaGridChecksum.cuh
util/cuda/CudaGridValidator.cuh
util/cuda/CudaPointsToGrid.cuh
util/cuda/GpuTimer.h
)
add_library(nanovdb INTERFACE)
target_include_directories(nanovdb INTERFACE ../)
target_compile_options(nanovdb INTERFACE
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-invalid-offsetof>"
"$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/bigobj>")
if(WIN32)
target_compile_definitions(nanovdb INTERFACE -DNOMINMAX -D_USE_MATH_DEFINES)
endif()
if(NANOVDB_USE_INTRINSICS)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_INTRINSICS)
endif()
if(NANOVDB_USE_OPENVDB)
if(NOT OPENVDB_BUILD_CORE)
target_link_libraries(nanovdb INTERFACE OpenVDB::openvdb)
else()
target_link_libraries(nanovdb INTERFACE openvdb)
endif()
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_OPENVDB)
endif()
if(NANOVDB_USE_TBB)
target_link_libraries(nanovdb INTERFACE TBB::tbb)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_TBB)
if(WIN32)
# this prevents tbb_debug.lib issue on windows
target_compile_definitions(nanovdb INTERFACE -DTBB_USE_PREVIEW_BINARY)
endif()
endif()
if(NANOVDB_USE_BLOSC)
target_link_libraries(nanovdb INTERFACE Blosc::blosc)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_BLOSC)
endif()
if(NANOVDB_USE_ZLIB)
target_link_libraries(nanovdb INTERFACE ZLIB::ZLIB)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_ZIP)
endif()
if(NANOVDB_USE_CUDA)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_CUDA)
if(NOT CMAKE_CUDA_ARCHITECTURES)
target_compile_options(nanovdb INTERFACE
"$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:-arch=sm_75>")
endif()
# Add CUDA includes to any C++ units which use NanoVDB
target_include_directories(nanovdb INTERFACE
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
endif()
if(NANOVDB_USE_MAGICAVOXEL)
target_compile_definitions(nanovdb INTERFACE -DNANOVDB_USE_MAGICAVOXEL)
target_include_directories(nanovdb INTERFACE ${NANOVDB_OGT_INCLUDE_DIRECTORY})
endif()
if(TARGET Threads::Threads)
target_link_libraries(nanovdb INTERFACE Threads::Threads)
endif()
set(NANOVDB_INSTALL_ROOT_DIR ${NANOVDB_INSTALL_INCLUDEDIR}/nanovdb)
set(NANOVDB_INSTALL_CUDA_DIR ${NANOVDB_INSTALL_ROOT_DIR}/cuda)
set(NANOVDB_INSTALL_IO_DIR ${NANOVDB_INSTALL_ROOT_DIR}/io)
set(NANOVDB_INSTALL_MATH_DIR ${NANOVDB_INSTALL_ROOT_DIR}/math)
set(NANOVDB_INSTALL_TOOLS_DIR ${NANOVDB_INSTALL_ROOT_DIR}/tools)
set(NANOVDB_INSTALL_TOOLS_CUDA_DIR ${NANOVDB_INSTALL_TOOLS_DIR}/cuda)
set(NANOVDB_INSTALL_UTIL_DIR ${NANOVDB_INSTALL_ROOT_DIR}/util)
set(NANOVDB_INSTALL_UTIL_CUDA_DIR ${NANOVDB_INSTALL_UTIL_DIR}/cuda)
install(FILES ${NANOVDB_INCLUDE_FILES} DESTINATION ${NANOVDB_INSTALL_ROOT_DIR})
install(FILES ${NANOVDB_INCLUDE_CUDA_FILES} DESTINATION ${NANOVDB_INSTALL_CUDA_DIR})
install(FILES ${NANOVDB_INCLUDE_IO_FILES} DESTINATION ${NANOVDB_INSTALL_IO_DIR})
install(FILES ${NANOVDB_INCLUDE_MATH_FILES} DESTINATION ${NANOVDB_INSTALL_MATH_DIR})
install(FILES ${NANOVDB_INCLUDE_TOOLS_FILES} DESTINATION ${NANOVDB_INSTALL_TOOLS_DIR})
install(FILES ${NANOVDB_INCLUDE_TOOLS_CUDA_FILES} DESTINATION ${NANOVDB_INSTALL_TOOLS_CUDA_DIR})
install(FILES ${NANOVDB_INCLUDE_UTIL_FILES} DESTINATION ${NANOVDB_INSTALL_UTIL_DIR})
install(FILES ${NANOVDB_INCLUDE_UTIL_CUDA_FILES} DESTINATION ${NANOVDB_INSTALL_UTIL_CUDA_DIR})
###############################################################################
# Options
###############################################################################
if(NANOVDB_BUILD_TOOLS)
add_subdirectory(cmd)
endif()
if(NANOVDB_BUILD_UNITTESTS)
add_subdirectory(unittest)
endif()
if(NANOVDB_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
if(NANOVDB_BUILD_PYTHON_MODULE)
add_subdirectory(python)
endif()
-715
View File
@@ -1,715 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
//
// Simple C-wrapper for the nanovdb structure
// Meant for systems where you lack a C++ compiler.
//
#ifndef __CNANOVDB__
#define __CNANOVDB__
#define CNANOVDB_DATA_ALIGNMENT 32
#define CNANOVDB_ALIGNMENT_PADDING(x, n) (-(x) & ((n)-1))
#define USE_SINGLE_ROOT_KEY
#ifdef __OPENCL_VERSION__
#define CNANOVDB_GLOBAL __global
#define RESTRICT restrict
// OpenCL doesn't define these basic types:
typedef unsigned long uint64_t;
typedef long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
#else
#define CNANOVDB_GLOBAL
#define RESTRICT __restrict
#endif
enum cnanovdb_GridType
{
cnanovdb_GridType_Unknown = 0,
cnanovdb_GridType_Float = 1,
cnanovdb_GridType_Double = 2,
cnanovdb_GridType_Int16 = 3,
cnanovdb_GridType_Int32 = 4,
cnanovdb_GridType_Int64 = 5,
cnanovdb_GridType_Vec3f = 6,
cnanovdb_GridType_Vec3d = 7,
cnanovdb_GridType_Mask = 8,
cnanovdb_GridType_FP16 = 9,
cnanovdb_GridType_End = 10
};
#define ROOT_LEVEL 3
#define DEFINEMASK_int(LOG2DIM, SIZE) \
typedef struct \
{ \
uint64_t mWords[SIZE >> 6]; \
} cnanovdb_mask##LOG2DIM; \
\
static void cnanovdb_mask##LOG2DIM##_clear(CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask) \
{ for (uint32_t i = 0; i < (SIZE >> 6); i++) mask->mWords[i] = 0; } \
\
static bool cnanovdb_mask##LOG2DIM##_isOn(const CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask, uint32_t n) \
{ return 0 != (mask->mWords[n >> 6] & (((uint64_t)(1)) << (n & 63))); } \
/**/
#define DEFINEMASK(LOG2DIM) \
DEFINEMASK_int(LOG2DIM, (1U << (3*LOG2DIM)))
#define INSTANTIATE(LOG2DIM) \
DEFINEMASK(LOG2DIM)
INSTANTIATE(3)
INSTANTIATE(4)
INSTANTIATE(5)
typedef struct
{
float mMatF[9]; // r,c = 3*r + c
float mInvMatF[9]; // r,c = 3*r + c
float mVecF[3];
float mTaperF;
double mMatD[9]; // r,c = 3*r + c
double mInvMatD[9]; // r,c = 3*r + c
double mVecD[3];
double mTaperD;
} cnanovdb_map;
typedef struct
{
float mVec[3];
} cnanovdb_Vec3F;
typedef struct
{
int32_t mVec[3];
} cnanovdb_coord;
static int
cnanovdb_coord_compare(const CNANOVDB_GLOBAL cnanovdb_coord *a, const cnanovdb_coord *b)
{
if (a->mVec[0] < b->mVec[0])
return -1;
if (a->mVec[0] > b->mVec[0])
return 1;
if (a->mVec[1] < b->mVec[1])
return -1;
if (a->mVec[1] > b->mVec[1])
return 1;
if (a->mVec[2] < b->mVec[2])
return -1;
if (a->mVec[2] > b->mVec[2])
return 1;
return 0;
}
#ifdef USE_SINGLE_ROOT_KEY
static uint64_t
cnanovdb_coord_to_key(const cnanovdb_coord *RESTRICT ijk)
{
// Define to workaround a bug with 64-bit shifts in the AMD OpenCL compiler.
#if defined(AVOID_64BIT_SHIFT)
uint2 key = (uint2)( ((uint32_t)ijk->mVec[2]) >> 12, 0) |
(uint2)((((uint32_t)ijk->mVec[1]) >> 12) << 21,
((uint32_t)ijk->mVec[1]) >> 23) |
(uint2)(0, (((uint32_t)ijk->mVec[0]) >> 12) << 10);
return *(uint64_t *)&key;
#else
return ((uint64_t) (((uint32_t)ijk->mVec[2]) >> 12)) |
(((uint64_t) (((uint32_t)ijk->mVec[1]) >> 12)) << 21) |
(((uint64_t) (((uint32_t)ijk->mVec[0]) >> 12)) << 42);
#endif
}
#else
static void
cnanovdb_coord_to_key(cnanovdb_coord *RESTRICT key, const cnanovdb_coord *RESTRICT ijk)
{
key->mVec[0] = ijk->mVec[0] & ~((1u << 12) - 1u);
key->mVec[1] = ijk->mVec[1] & ~((1u << 12) - 1u);
key->mVec[2] = ijk->mVec[2] & ~((1u << 12) - 1u);
}
#endif
static void
cnanovdb_map_apply(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_map *RESTRICT map, const cnanovdb_Vec3F *src)
{
float sx = src->mVec[0];
float sy = src->mVec[1];
float sz = src->mVec[2];
dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2] + map->mVecF[0];
dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5] + map->mVecF[1];
dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8] + map->mVecF[2];
}
static void
cnanovdb_map_applyInverse(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_map *RESTRICT map, const cnanovdb_Vec3F *src)
{
float sx = src->mVec[0] - map->mVecF[0];
float sy = src->mVec[1] - map->mVecF[1];
float sz = src->mVec[2] - map->mVecF[2];
dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
}
static void
cnanovdb_map_applyJacobi(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_map *RESTRICT map, const cnanovdb_Vec3F *src)
{
float sx = src->mVec[0];
float sy = src->mVec[1];
float sz = src->mVec[2];
dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2];
dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5];
dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8];
}
static void
cnanovdb_map_applyInverseJacobi(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_map *RESTRICT map, const cnanovdb_Vec3F *src)
{
float sx = src->mVec[0];
float sy = src->mVec[1];
float sz = src->mVec[2];
dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
}
static void
cnanovdb_map_applyIJT(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_map *RESTRICT map, const cnanovdb_Vec3F *src)
{
float sx = src->mVec[0];
float sy = src->mVec[1];
float sz = src->mVec[2];
dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[3] + sz * map->mInvMatF[6];
dst->mVec[1] = sx * map->mInvMatF[1] + sy * map->mInvMatF[4] + sz * map->mInvMatF[7];
dst->mVec[2] = sx * map->mInvMatF[2] + sy * map->mInvMatF[5] + sz * map->mInvMatF[8];
}
typedef struct
{
int64_t mByteOffset; // byte offset to the blind data, relative to the GridData.
uint64_t mElementCount; // number of elements, e.g. point count
uint32_t mFlags; // flags
uint32_t mSemantic; // semantic meaning of the data.
uint32_t mDataClass; // 4 bytes
uint32_t mDataType; // 4 bytes
char mName[256];
uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(int64_t)+sizeof(uint64_t)+2*sizeof(uint32_t)+2*sizeof(uint32_t)+256*sizeof(char), CNANOVDB_DATA_ALIGNMENT)];
} cnanovdb_gridblindmetadata;
typedef struct
{
uint64_t mMagic; // 8B magic to validate it is valid grid data.
uint64_t mChecksum; // 8B. Checksum of grid buffer.
uint32_t mVersion;// 4B. compacted major.minor.path version number.
uint32_t mFlags; // 4B. flags for grid.
uint32_t mGridIndex;// 4B. Index of this grid in the buffer
uint32_t mGridCount; // 4B. Total number of grids in the buffer
uint64_t mGridSize; // 8B. byte count of this entire grid occupied in the buffer.
char mGridName[256]; // 256B
cnanovdb_map mMap; // 264B. affine transformation between index and world space in both single and double precision
double mBBox[6]; // 48B. floating-point bounds of active values in WORLD SPACE
double mVoxelSize[3]; // 24B. size of a voxel in world units
uint32_t mGridClass; // 4B.
uint32_t mGridType; // 4B.
uint64_t mBlindMetadataOffset; // 8B. offset of GridBlindMetaData structures.
int32_t mBlindMetadataCount; // 4B. count of GridBlindMetaData structures.
uint32_t _reserved[CNANOVDB_ALIGNMENT_PADDING(8 + 8 + 4 + 4 + 4 + 4 + 8 + 256 + 24 + 24 + sizeof(cnanovdb_map) + 24 + 4 + 4 + 8 + 4, CNANOVDB_DATA_ALIGNMENT) / 4];
} cnanovdb_griddata;
static void
cnanovdb_griddata_worldToIndex(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid, const cnanovdb_Vec3F *src)
{
cnanovdb_map_applyInverse(dst, &grid->mMap, src);
}
static void
cnanovdb_griddata_indexToWorld(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid, const cnanovdb_Vec3F *src)
{
cnanovdb_map_apply(dst, &grid->mMap, src);
}
static void
cnanovdb_griddata_worldToIndexDir(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid, const cnanovdb_Vec3F *src)
{
cnanovdb_map_applyInverseJacobi(dst, &grid->mMap, src);
}
static void
cnanovdb_griddata_indexToWorldDir(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid, const cnanovdb_Vec3F *src)
{
cnanovdb_map_applyJacobi(dst, &grid->mMap, src);
}
static void
cnanovdb_griddata_applyIJT(cnanovdb_Vec3F *dst, const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid, const cnanovdb_Vec3F *src)
{
cnanovdb_map_applyIJT(dst, &grid->mMap, src);
}
typedef struct
{
uint64_t mNodeOffset[ROOT_LEVEL + 1];
uint32_t mNodeCount[ROOT_LEVEL];
uint32_t mTileCount[ROOT_LEVEL];
uint64_t mVoxelCount;
uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(4*sizeof(uint64_t)+(3+3)*sizeof(uint32_t)+sizeof(uint64_t), CNANOVDB_DATA_ALIGNMENT)];
} cnanovdb_treedata;
static const CNANOVDB_GLOBAL cnanovdb_treedata *
cnanovdb_griddata_tree(const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT griddata)
{
return (const CNANOVDB_GLOBAL cnanovdb_treedata *)(griddata + 1);
}
#define CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
typedef union \
{ \
VALUETYPE value; \
uint64_t child; \
} cnanovdb_tileentry##SUFFIX; \
/**/
typedef struct
{
cnanovdb_coord mKey;
const CNANOVDB_GLOBAL void *mNode[4];
} cnanovdb_readaccessor;
static void
cnanovdb_readaccessor_insert(cnanovdb_readaccessor *RESTRICT acc, int childlevel, const CNANOVDB_GLOBAL void *RESTRICT node, const cnanovdb_coord *RESTRICT ijk)
{
acc->mNode[childlevel] = node;
acc->mKey.mVec[0] = ijk->mVec[0];
acc->mKey.mVec[1] = ijk->mVec[1];
acc->mKey.mVec[2] = ijk->mVec[2];
}
#define CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
typedef struct \
{ \
cnanovdb_coord mBBox_min; \
uint8_t mBBoxDif[3]; \
uint8_t mFlags; \
cnanovdb_mask##LOG2DIM mValueMask; \
VALUETYPE mMinimum; \
VALUETYPE mMaximum; \
STATSTYPE mAverage; \
STATSTYPE mStdDevi; \
uint32_t _reserved[ CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_mask##LOG2DIM)+2*sizeof(VALUETYPE)+2*sizeof(STATSTYPE)+sizeof(cnanovdb_coord)+sizeof(uint8_t[3])+sizeof(uint8_t), CNANOVDB_DATA_ALIGNMENT)/4]; \
VALUETYPE mVoxels[1u << (3*LOG2DIM)]; \
} cnanovdb_node##LEVEL##SUFFIX; \
\
static uint32_t \
cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
{ \
return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
} \
\
static VALUETYPE \
cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
return node->mVoxels[n]; \
} \
\
static VALUETYPE \
cnanovdb_node##LEVEL##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT /* DO NOT REMOVE: Required for C99 compliance */ acc) \
{ \
(void)(acc); \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
return node->mVoxels[n]; \
} \
\
static bool \
cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
return true; \
return false; \
} \
\
static bool \
cnanovdb_node##LEVEL##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT /* DO NOT REMOVE: Required for C99 compliance */ acc) \
{ \
(void)(acc); \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
return true; \
return false; \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
return basenode + i; \
} \
\
/**/
#define CREATE_LEAF_NODE(LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
#define CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
typedef struct \
{ \
cnanovdb_coord mBBox_min, mBBox_max; \
int32_t mOffset; \
uint32_t mFlags; \
cnanovdb_mask##LOG2DIM mValueMask, mChildMask; \
VALUETYPE mMinimum, mMaximum; \
STATSTYPE mAverage, mStdDevi; \
uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_mask##LOG2DIM)+sizeof(VALUETYPE)*2+sizeof(STATSTYPE)*2+sizeof(cnanovdb_coord)*2+sizeof(int32_t)+sizeof(uint32_t), CNANOVDB_DATA_ALIGNMENT)]; \
cnanovdb_tileentry##SUFFIX mTable[1u << (3*LOG2DIM)]; \
} cnanovdb_node##LEVEL##SUFFIX; \
\
static uint32_t \
cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
{ \
return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX * \
cnanovdb_node##LEVEL##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, uint32_t n) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *childnode = (const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *)( ((CNANOVDB_GLOBAL uint8_t *)node) + node->mTable[n].child); \
return childnode; \
} \
\
static VALUETYPE \
cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValue(child, ijk); \
} \
return node->mTable[n].value; \
} \
\
static VALUETYPE \
cnanovdb_node##LEVEL##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValueAndCache(child, ijk, acc); \
} \
return node->mTable[n].value; \
} \
\
static bool \
cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActive(child, ijk); \
} \
return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
} \
\
static bool \
cnanovdb_node##LEVEL##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
{ \
uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActiveAndCache(child, ijk, acc); \
} \
return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
{ \
const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
return basenode + i; \
} \
\
/**/
#define CREATE_INTERNAL_NODE(CHILDLEVEL, LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
#ifdef USE_SINGLE_ROOT_KEY
#define DEFINE_KEY(KEY) \
uint64_t KEY;
#define KEYSIZE sizeof(uint64_t)
#define KEYSEARCH(SUFFIX) \
uint64_t key; \
key = cnanovdb_coord_to_key(ijk); \
\
for (int i = low; i < high; i++) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + i; \
if (tile->key == key) \
return tile; \
} \
/**/
#else
#define DEFINE_KEY(KEY) \
cnanovdb_coord KEY;
#define KEYSIZE sizeof(cnanovdb_coord)
#define KEYSEARCH(SUFFIX) \
cnanovdb_coord key; \
cnanovdb_coord_to_key(&key, ijk); \
\
while (low != high) \
{ \
int32_t mid = low + (( high - low ) >> 1 ); \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + mid; \
\
int keycmp = cnanovdb_coord_compare(&tile->key, &key); \
if (keycmp == 0) \
{ \
return tile; \
} \
\
if (keycmp < 0) \
low = mid + 1; \
else \
high = mid; \
} \
/**/
#endif
#define CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
typedef struct \
{ \
DEFINE_KEY(key); \
int64_t child; \
uint32_t state; \
VALUETYPE value; \
uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(KEYSIZE)+sizeof(VALUETYPE)+sizeof(int64_t)+sizeof(uint32_t), CNANOVDB_DATA_ALIGNMENT)]; \
} cnanovdb_rootdata_tile##SUFFIX; \
\
typedef struct \
{ \
cnanovdb_coord mBBox_min, mBBox_max; \
uint32_t mTableSize; \
VALUETYPE mBackground; \
VALUETYPE mMinimum, mMaximum; \
STATSTYPE mAverage, mStdDevi; \
uint32_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_coord)*2+sizeof(uint32_t)+sizeof(VALUETYPE)*3+sizeof(STATSTYPE)*2, CNANOVDB_DATA_ALIGNMENT)/4]; \
} cnanovdb_rootdata##SUFFIX; \
\
static const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX * \
cnanovdb_treedata_root##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT treedata) \
{ \
return (const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *) ((const CNANOVDB_GLOBAL uint8_t *)(treedata) + treedata->mNodeOffset[ROOT_LEVEL]); \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
cnanovdb_rootdata##SUFFIX##_getTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, uint32_t n) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *basetile = (const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *) (rootdata + 1); \
return basetile + n; \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX * \
cnanovdb_rootdata##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *RESTRICT tile) \
{ \
CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *basenode = (CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) (((CNANOVDB_GLOBAL uint8_t *) rootdata) + tile->child); \
return basenode; \
} \
\
static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
cnanovdb_rootdata##SUFFIX##_findTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
{ \
int32_t low = 0, high = rootdata->mTableSize; \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tiles = cnanovdb_rootdata##SUFFIX##_getTile(rootdata, 0); \
\
KEYSEARCH(SUFFIX) \
return 0; \
} \
\
static VALUETYPE \
cnanovdb_rootdata##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
if (!tile) \
return rootdata->mBackground; \
if (tile->child == 0) \
return tile->value; \
return cnanovdb_node2##SUFFIX##_getValue( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
} \
\
static VALUETYPE \
cnanovdb_rootdata##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
if (!tile) \
return rootdata->mBackground; \
if (tile->child == 0) \
return tile->value; \
const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
return cnanovdb_node2##SUFFIX##_getValueAndCache( child, ijk, acc ); \
} \
\
static bool \
cnanovdb_rootdata##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
if (!tile) \
return false; \
if (tile->child == 0) \
return tile->state; \
return cnanovdb_node2##SUFFIX##_isActive( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
} \
\
static bool \
cnanovdb_rootdata##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
{ \
const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
if (!tile) \
return false; \
if (tile->child == 0) \
return tile->state; \
const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
return cnanovdb_node2##SUFFIX##_isActiveAndCache( child, ijk, acc ); \
} \
/**/
inline void
cnanovdb_readaccessor_init(cnanovdb_readaccessor *RESTRICT acc,
const CNANOVDB_GLOBAL void /*cnanovdb_rootdata* */ *RESTRICT rootdata)
{
acc->mNode[0] = acc->mNode[1] = acc->mNode[2] = 0;
acc->mNode[3] = rootdata;
}
#define DEFINE_ISCACHED(LEVEL, MASK) \
inline bool \
cnanovdb_readaccessor_isCached##LEVEL(cnanovdb_readaccessor *RESTRICT acc, int32_t dirty) \
{ \
if (!acc->mNode[LEVEL]) \
return false; \
if (dirty & ~MASK) \
{ \
acc->mNode[LEVEL] = 0; \
return false; \
} \
return true; \
} \
/**/
DEFINE_ISCACHED(0, ((1u << 3) - 1u) )
DEFINE_ISCACHED(1, ((1u << 7) - 1u) )
DEFINE_ISCACHED(2, ((1u << 12) - 1u) )
inline int32_t
cnanovdb_readaccessor_computeDirty(const cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk)
{
return (ijk->mVec[0] ^ acc->mKey.mVec[0]) |
(ijk->mVec[1] ^ acc->mKey.mVec[1]) |
(ijk->mVec[2] ^ acc->mKey.mVec[2]);
}
#define CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
inline VALUETYPE \
cnanovdb_readaccessor_getValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
{ \
int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
\
if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
return cnanovdb_node0##SUFFIX##_getValue( ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
return cnanovdb_node1##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
return cnanovdb_node2##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
\
return cnanovdb_rootdata##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
} \
\
inline bool \
cnanovdb_readaccessor_isActive##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
{ \
int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
\
if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
return cnanovdb_node0##SUFFIX##_isActive( ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
return cnanovdb_node1##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
return cnanovdb_node2##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
\
return cnanovdb_rootdata##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
} \
/**/
#define CREATE_GRIDTYPE(VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
CREATE_LEAF_NODE(0, 3, 3, VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_INTERNAL_NODE(0, 1, 4, 7, VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_INTERNAL_NODE(1, 2, 5, 12, VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
/**/
CREATE_GRIDTYPE(float, float, F)
CREATE_GRIDTYPE(cnanovdb_Vec3F, float, F3)
static int
cnanovdb_griddata_valid(const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid)
{
if (!grid)
return 0;
if (grid->mMagic != 0x304244566f6e614eUL && grid->mMagic != 0x314244566f6e614eUL)
return 0;
return 1;
}
static int
cnanovdb_griddata_validF(const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid)
{
if (!cnanovdb_griddata_valid(grid))
return 0;
if (grid->mGridType != cnanovdb_GridType_Float)
return 0;
return 1;
}
static int
cnanovdb_griddata_validF3(const CNANOVDB_GLOBAL cnanovdb_griddata *RESTRICT grid)
{
if (!cnanovdb_griddata_valid(grid))
return 0;
if (grid->mGridType != cnanovdb_GridType_Vec3f)
return 0;
return 1;
}
#endif
-530
View File
@@ -1,530 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb/GridHandle.h
\author Ken Museth
\date January 8, 2020
\brief Defines GridHandle, which manages a host, and possibly a device,
memory buffer containing one or more NanoVDB grids.
*/
#ifndef NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
#define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
#include <fstream> // for std::ifstream
#include <iostream> // for std::cerr/cout
#include <vector>
#include <initializer_list>
#include <nanovdb/NanoVDB.h>// for toGridType
#include <nanovdb/HostBuffer.h>
#include <nanovdb/tools/GridChecksum.h>// for updateGridCount
namespace nanovdb {
// --------------------------> GridHandle <------------------------------------
struct GridHandleMetaData {uint64_t offset, size; GridType gridType;};
/// @brief This class serves to manage a buffer containing one or more NanoVDB Grids.
///
/// @note It is important to note that this class does NOT depend on OpenVDB.
template<typename BufferT = HostBuffer>
class GridHandle
{
std::vector<GridHandleMetaData> mMetaData;
BufferT mBuffer;
template <typename T>
static T* no_const(const T* ptr) { return const_cast<T*>(ptr); }
public:
using BufferType = BufferT;
/// @brief Move constructor from a dual host-device buffer
/// @param buffer buffer containing one or more NanoGrids that will be moved into this GridHandle
/// @throw Will throw and error with the buffer does not contain a valid NanoGrid!
/// @note The implementation of this template specialization is in nanovdb/cuda/GridHandle.cuh since it requires CUDA
template<typename T = BufferT, typename util::enable_if<BufferTraits<T>::hasDeviceDual, int>::type = 0>
GridHandle(T&& buffer);
/// @brief Move constructor from a host buffer
/// @param buffer buffer containing one or more NanoGrids that will be moved into this GridHandle
/// @throw Will throw and error with the buffer does not contain a valid NanoGrid!
template<typename T = BufferT, typename util::disable_if<BufferTraits<T>::hasDeviceDual, int>::type = 0>
GridHandle(T&& buffer);
/// @brief Constructs an empty GridHandle
GridHandle() = default;
/// @brief Disallow copy-construction
GridHandle(const GridHandle&) = delete;
/// @brief Move copy-constructor
GridHandle(GridHandle&& other) noexcept {
mBuffer = std::move(other.mBuffer);
mMetaData = std::move(other.mMetaData);
}
/// @brief clear this GridHandle to an empty handle
void reset() {
mBuffer.clear();
mMetaData.clear();
}
/// @brief Disallow copy assignment operation
GridHandle& operator=(const GridHandle&) = delete;
/// @brief Move copy assignment operation
GridHandle& operator=(GridHandle&& other) noexcept {
mBuffer = std::move(other.mBuffer);
mMetaData = std::move(other.mMetaData);
return *this;
}
/// @brief Performs a deep copy of the GridHandle, possibly templated on a different buffer type
/// @tparam OtherBufferT Buffer type of the deep copy
/// @param buffer optional buffer used for allocation
/// @return A new handle of the specified buffer type that contains a deep copy of the current handle
template <typename OtherBufferT = HostBuffer>
GridHandle<OtherBufferT> copy(const OtherBufferT& buffer = OtherBufferT()) const;
/// @brief Return a reference to the buffer
BufferT& buffer() { return mBuffer; }
/// @brief Return a const reference to the buffer
const BufferT& buffer() const { return mBuffer; }
/// @brief Returns a non-const pointer to the data.
/// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
void* data() { return mBuffer.data(); }
/// @brief Returns a const pointer to the data.
/// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
const void* data() const { return mBuffer.data(); }
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, const void*>::type
deviceData() const { return mBuffer.deviceData(); }
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void*>::type
deviceData() { return mBuffer.deviceData(); }
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void*>::type
deviceData(int device) { return mBuffer.deviceData(device); }
//@{
/// @brief Returns the size in bytes of the raw memory buffer managed by this GridHandle.
[[deprecated("Use GridHandle::bufferSize instead.")]] uint64_t size() const { return mBuffer.size(); }
uint64_t bufferSize() const { return mBuffer.size(); }
//@}
//@{
/// @brief Return true if this handle is empty, i.e. has no allocated memory
bool empty() const { return mBuffer.size() == 0; }
bool isEmpty() const { return mBuffer.size() == 0; }
//@}
/// @brief Return true if this handle is not empty, i.e. contains at least one grid
operator bool() const { return !this->empty(); }
/// @brief Returns a const host pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
/// @tparam ValueT Value type of the grid point to be returned
/// @param n Index of the (host) grid pointer to be returned
/// @warning Note that the return pointer can be NULL if the GridHandle no host grid, @a n is invalid
/// or if the template parameter does not match the specified grid!
template<typename ValueT>
const NanoGrid<ValueT>* grid(uint32_t n = 0) const;
/// @brief Returns a host pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
/// @tparam ValueT Value type of the grid point to be returned
/// @param n Index of the (host) grid pointer to be returned
/// @warning Note that the return pointer can be NULL if the GridHandle no host grid, @a n is invalid
/// or if the template parameter does not match the specified grid!
template<typename ValueT>
NanoGrid<ValueT>* grid(uint32_t n = 0) {return const_cast<NanoGrid<ValueT>*>(static_cast<const GridHandle*>(this)->template grid<ValueT>(n));}
/// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
/// @tparam ValueT Value type of the grid point to be returned
/// @param n Index of the (device) grid pointer to be returned
/// @warning Note that the return pointer can be NULL if the GridHandle has no device grid, @a n is invalid,
/// or if the template parameter does not match the specified grid.
template<typename ValueT, typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
deviceGrid(uint32_t n=0) const;
/// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
/// @tparam ValueT Value type of the grid point to be returned
/// @param n Index of the grid pointer to be returned
/// @param verbose if non-zero error messages will be printed in case something failed
/// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid,
/// or if the template parameter does not match the specified grid.
template<typename ValueT, typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, NanoGrid<ValueT>*>::type
deviceGrid(uint32_t n=0){return const_cast<NanoGrid<ValueT>*>(static_cast<const GridHandle*>(this)->template deviceGrid<ValueT>(n));}
/// @brief Upload the grid to the device, e.g. from CPU to GPU
/// @note This method is only available if the buffer supports devices
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceUpload(void* stream, bool sync = true) { mBuffer.deviceUpload(stream, sync); }
/// @brief Upload the host buffer to a specefic device buffer. It device buffer doesn't exist it's created first
/// @param device Device to upload host data to
/// @param stream cuda stream
/// @param sync if false the memory copy is asynchronous
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceUpload(int device = 0, void* stream = nullptr, bool sync = true) { mBuffer.deviceUpload(device, stream, sync); }
/// @brief Download the grid to from the device, e.g. from GPU to CPU
/// @note This method is only available if the buffer supports devices
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceDownload(void* stream, bool sync = true) { mBuffer.deviceDownload(stream, sync); }
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceDownload(int device = 0, void* stream = nullptr, bool sync = true) { mBuffer.deviceDownload(device, stream, sync); }
/// @brief Check if the buffer is this handle has any padding, i.e. if the buffer is larger than the combined size of all its grids
/// @return true is the combined size of all grid is smaller than the buffer size
bool isPadded() const {return mMetaData.empty() ? false : mMetaData.back().offset + mMetaData.back().size != mBuffer.size();}
/// @brief Return the total number of grids contained in this buffer
uint32_t gridCount() const {return static_cast<uint32_t>(mMetaData.size());}
/// @brief Return the grid size of the @a n'th grid in this GridHandle
/// @param n index of the grid (assumed to be less than gridCount())
/// @return Return the byte size of the specified grid
uint64_t gridSize(uint32_t n = 0) const {return mMetaData[n].size; }
/// @brief compute the total sum of memory footprints of all the grids in this buffer
/// @return the number of bytes occupied by all grids associated with this buffer
uint64_t totalGridSize() const {
uint64_t sum = 0;
for (auto &m : mMetaData) sum += m.size;
NANOVDB_ASSERT(sum <= mBuffer.size());
return sum;
}
/// @brief compute the size of unusedstorage in this buffer
/// @return the number of unused bytes in this buffer.
uint64_t freeSize() const {return mBuffer.size() - this->totalGridSize();}
/// @brief Test if this buffer has any unused storage left, i.e. memory not occupied by grids
/// @return true if there is no extra storage left in this buffer, i.e. empty or fully occupied with grids
bool isFull() const { return this->totalGridSize() == mBuffer.size(); }
/// @brief Return the GridType of the @a n'th grid in this GridHandle
/// @param n index of the grid (assumed to be less than gridCount())
/// @return Return the GridType of the specified grid
GridType gridType(uint32_t n = 0) const {return mMetaData[n].gridType; }
/// @brief Access to the GridData of the n'th grid in the current handle
/// @param n zero-based ID of the grid
/// @return Const pointer to the n'th GridData in the current handle
const GridData* gridData(uint32_t n = 0) const;
/// @brief Returns a const point to the @a n'th grid meta data
/// @param n zero-based ID of the grid
/// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
const GridMetaData* gridMetaData(uint32_t n = 0) const;
/// @brief Write a specific grid in this buffer to an output stream
/// @param os output stream that the buffer will be written to
/// @param n zero-based index of the grid to be written to stream
void write(std::ostream& os, uint32_t n) const {
if (const GridData* data = this->gridData(n)) {
os.write((const char*)data, data->mGridSize);
} else {
throw std::runtime_error("GridHandle does not contain a #" + std::to_string(n) + " grid");
}
}
/// @brief Write the entire grid buffer to an output stream
/// @param os output stream that the buffer will be written to
void write(std::ostream& os) const {
for (uint32_t n=0; n<this->gridCount(); ++n) this->write(os, n);
}
/// @brief Write this entire grid buffer to a file
/// @param fileName string name of the output file
void write(const std::string &fileName) const {
std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
if (!os.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for output");
this->write(os);
}
/// @brief Write a specific grid to file
/// @param fileName string name of the output file
/// @param n zero-based index of the grid to be written to file
void write(const std::string &fileName, uint32_t n) const {
std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
if (!os.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for output");
this->write(os, n);
}
/// @brief Read an entire raw grid buffer from an input stream
/// @param is input stream containing a raw grid buffer
/// @param pool optional pool from which to allocate the new grid buffer
/// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid
void read(std::istream& is, const BufferT& pool = BufferT());
/// @brief Read a specific grid from an input stream containing a raw grid buffer
/// @param is input stream containing a raw grid buffer
/// @param n zero-based index of the grid to be read
/// @param pool optional pool from which to allocate the new grid buffer
/// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid
void read(std::istream& is, uint32_t n, const BufferT& pool = BufferT());
/// @brief Read a specific grid from an input stream containing a raw grid buffer
/// @param is input stream containing a raw grid buffer
/// @param gridName string name of the grid to be read
/// @param pool optional pool from which to allocate the new grid buffer
/// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid with the speficied name
void read(std::istream& is, const std::string &gridName, const BufferT& pool = BufferT());
/// @brief Read a raw grid buffer from a file
/// @param filename string name of the input file containing a raw grid buffer
/// @param pool optional pool from which to allocate the new grid buffe
void read(const std::string &fileName, const BufferT& pool = BufferT()) {
std::ifstream is(fileName, std::ios::in | std::ios::binary);
if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
this->read(is, pool);
}
/// @brief Read a specific grid from a file containing a raw grid buffer
/// @param filename string name of the input file containing a raw grid buffer
/// @param n zero-based index of the grid to be read
/// @param pool optional pool from which to allocate the new grid buffer
/// @throw Will throw a std::ios_base::failure if the file does not exist and a
/// std::logic_error if the files does not contain a valid raw grid
void read(const std::string &fileName, uint32_t n, const BufferT& pool = BufferT()) {
std::ifstream is(fileName, std::ios::in | std::ios::binary);
if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
this->read(is, n, pool);
}
/// @brief Read a specific grid from a file containing a raw grid buffer
/// @param filename string name of the input file containing a raw grid buffer
/// @param gridName string name of the grid to be read
/// @param pool optional pool from which to allocate the new grid buffer
/// @throw Will throw a std::ios_base::failure if the file does not exist and a
/// std::logic_error if the files does not contain a valid raw grid withe the specified name
void read(const std::string &fileName, const std::string &gridName, const BufferT& pool = BufferT()) {
std::ifstream is(fileName, std::ios::in | std::ios::binary);
if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
this->read(is, gridName, pool);
}
}; // GridHandle
// --------------------------> Implementation of private methods in GridHandle <------------------------------------
template<typename BufferT>
inline const GridData* GridHandle<BufferT>::gridData(uint32_t n) const
{
const void *data = this->data();
if (data == nullptr || n >= mMetaData.size()) return nullptr;
return util::PtrAdd<GridData>(data, mMetaData[n].offset);
}// const GridData* GridHandle<BufferT>::gridData(uint32_t n) const
template<typename BufferT>
inline const GridMetaData* GridHandle<BufferT>::gridMetaData(uint32_t n) const
{
const auto *data = this->data();
if (data == nullptr || n >= mMetaData.size()) return nullptr;
return util::PtrAdd<GridMetaData>(data, mMetaData[n].offset);
}// const GridMetaData* GridHandle<BufferT>::gridMetaData(uint32_t n) const
inline __hostdev__ void cpyGridHandleMeta(const GridData *data, GridHandleMetaData *meta)
{
uint64_t offset = 0;
for (auto *p=meta, *q=p+data->mGridCount; p!=q; ++p) {
*p = {offset, data->mGridSize, data->mGridType};
offset += p->size;
data = util::PtrAdd<GridData>(data, p->size);
}
}// void cpyGridHandleMeta(const GridData *data, GridHandleMetaData *meta)
// template specialization of move constructor from a host buffer
template<typename BufferT>
template<typename T, typename util::disable_if<BufferTraits<T>::hasDeviceDual, int>::type>
GridHandle<BufferT>::GridHandle(T&& buffer)
{
static_assert(util::is_same<T,BufferT>::value, "Expected U==BufferT");
mBuffer = std::move(buffer);
if (auto *data = reinterpret_cast<const GridData*>(mBuffer.data())) {
if (!data->isValid()) throw std::runtime_error("GridHandle was constructed with an invalid host buffer");
mMetaData.resize(data->mGridCount);
cpyGridHandleMeta(data, mMetaData.data());
}
}// GridHandle<BufferT>::GridHandle(T&& buffer)
template<typename BufferT>
template <typename OtherBufferT>
inline GridHandle<OtherBufferT> GridHandle<BufferT>::copy(const OtherBufferT& other) const
{
if (mBuffer.isEmpty()) return GridHandle<OtherBufferT>();// return an empty handle
auto buffer = OtherBufferT::create(mBuffer.size(), &other);
std::memcpy(buffer.data(), mBuffer.data(), mBuffer.size());// deep copy of buffer
return GridHandle<OtherBufferT>(std::move(buffer));
}// GridHandle<OtherBufferT> GridHandle<BufferT>::copy(const OtherBufferT& other) const
template<typename BufferT>
template<typename ValueT>
inline const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
{
const void *data = mBuffer.data();
if (data == nullptr || n >= mMetaData.size() || mMetaData[n].gridType != toGridType<ValueT>()) return nullptr;
return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData[n].offset);
}// const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
template<typename BufferT>
template<typename ValueT, typename U>
inline typename util::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
GridHandle<BufferT>::deviceGrid(uint32_t n) const
{
const void *data = mBuffer.deviceData();
if (data == nullptr || n >= mMetaData.size() || mMetaData[n].gridType != toGridType<ValueT>()) return nullptr;
return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData[n].offset);
}// GridHandle<BufferT>::deviceGrid(uint32_t n) cons
template<typename BufferT>
void GridHandle<BufferT>::read(std::istream& is, const BufferT& pool)
{
GridData data;
is.read((char*)&data, sizeof(GridData));
if (data.isValid()) {
uint64_t size = data.mGridSize, sum = 0u;
while(data.mGridIndex + 1u < data.mGridCount) {// loop over remaining raw grids in stream
is.seekg(data.mGridSize - sizeof(GridData), std::ios::cur);// skip grid
is.read((char*)&data, sizeof(GridData));
sum += data.mGridSize;
}
auto buffer = BufferT::create(size + sum, &pool);
is.seekg(-int64_t(sum + sizeof(GridData)), std::ios::cur);// rewind to start
is.read((char*)(buffer.data()), buffer.size());
*this = GridHandle(std::move(buffer));
} else {
is.seekg(-sizeof(GridData), std::ios::cur);// rewind
throw std::logic_error("This stream does not contain a valid raw grid buffer");
}
}// void GridHandle<BufferT>::read(std::istream& is, const BufferT& pool)
template<typename BufferT>
void GridHandle<BufferT>::read(std::istream& is, uint32_t n, const BufferT& pool)
{
GridData data;
is.read((char*)&data, sizeof(GridData));
if (data.isValid()) {
if (n>=data.mGridCount) throw std::runtime_error("stream does not contain a #" + std::to_string(n) + " grid");
while(data.mGridIndex != n) {
is.seekg(data.mGridSize - sizeof(GridData), std::ios::cur);// skip grid
is.read((char*)&data, sizeof(GridData));
}
auto buffer = BufferT::create(data.mGridSize, &pool);
is.seekg(-sizeof(GridData), std::ios::cur);// rewind
is.read((char*)(buffer.data()), data.mGridSize);
tools::updateGridCount((GridData*)buffer.data(), 0u, 1u);
*this = GridHandle(std::move(buffer));
} else {
is.seekg(-sizeof(GridData), std::ios::cur);// rewind sizeof(GridData) bytes to undo initial read
throw std::logic_error("This file does not contain a valid raw buffer");
}
}// void GridHandle<BufferT>::read(std::istream& is, uint32_t n, const BufferT& pool)
template<typename BufferT>
void GridHandle<BufferT>::read(std::istream& is, const std::string &gridName, const BufferT& pool)
{
static const std::streamsize byteSize = sizeof(GridData);
GridData data;
is.read((char*)&data, byteSize);
is.seekg(-byteSize, std::ios::cur);// rewind
if (data.isValid()) {
uint32_t n = 0;
while(data.mGridName != gridName && n++ < data.mGridCount) {
is.seekg(data.mGridSize, std::ios::cur);// skip grid
is.read((char*)&data, byteSize);// read sizeof(GridData) bytes
is.seekg(-byteSize, std::ios::cur);// rewind
}
if (n>data.mGridCount) throw std::runtime_error("No raw grid named \""+gridName+"\"");
auto buffer = BufferT::create(data.mGridSize, &pool);
is.read((char*)(buffer.data()), data.mGridSize);
tools::updateGridCount((GridData*)buffer.data(), 0u, 1u);
*this = GridHandle(std::move(buffer));
} else {
throw std::logic_error("This file does not contain a valid raw buffer");
}
}// void GridHandle<BufferT>::read(std::istream& is, const std::string &gridName n, const BufferT& pool)
// --------------------------> free-standing functions <------------------------------------
/// @brief Split all grids in a single GridHandle into a vector of multiple GridHandles each with a single grid
/// @tparam BufferT Type of the input and output grid buffers
/// @param handle GridHandle with grids that will be slip into individual GridHandles
/// @param pool optional pool used for allocation of output GridHandle
/// @return Vector of GridHandles each containing a single grid
template<typename BufferT, template <class, class...> class VectorT = std::vector>
inline VectorT<GridHandle<BufferT>>
splitGrids(const GridHandle<BufferT> &handle, const BufferT* other = nullptr)
{
using HandleT = GridHandle<BufferT>;
const void *ptr = handle.data();
if (ptr == nullptr) return VectorT<HandleT>();
VectorT<HandleT> handles(handle.gridCount());
for (auto &h : handles) {
const GridData *src = reinterpret_cast<const GridData*>(ptr);
NANOVDB_ASSERT(src->isValid());
auto buffer = BufferT::create(src->mGridSize, other);
GridData *dst = reinterpret_cast<GridData*>(buffer.data());
std::memcpy(dst, src, src->mGridSize);
tools::updateGridCount(dst, 0u, 1u);
h = HandleT(std::move(buffer));
ptr = util::PtrAdd(ptr, src->mGridSize);
}
return std::move(handles);
}// splitGrids
/// @brief Combines (or merges) multiple GridHandles into a single GridHandle containing all grids
/// @tparam BufferT Type of the input and output grid buffers
/// @param handles Vector of GridHandles to be combined
/// @param pool optional pool used for allocation of output GridHandle
/// @return single GridHandle containing all input grids
template<typename BufferT, template <class, class...> class VectorT>
inline GridHandle<BufferT>
mergeGrids(const VectorT<GridHandle<BufferT>> &handles, const BufferT* pool = nullptr)
{
uint64_t size = 0u;
uint32_t counter = 0u, gridCount = 0u;
for (auto &h : handles) {
gridCount += h.gridCount();
for (uint32_t n=0; n<h.gridCount(); ++n) size += h.gridSize(n);
}
auto buffer = BufferT::create(size, pool);
void *dst = buffer.data();
for (auto &h : handles) {
const void *src = h.data();
for (uint32_t n=0; n<h.gridCount(); ++n) {
std::memcpy(dst, src, h.gridSize(n));
GridData *data = reinterpret_cast<GridData*>(dst);
NANOVDB_ASSERT(data->isValid());
tools::updateGridCount(data, counter++, gridCount);
dst = util::PtrAdd(dst, data->mGridSize);
src = util::PtrAdd(src, data->mGridSize);
}
}
return GridHandle<BufferT>(std::move(buffer));
}// mergeGrids
} // namespace nanovdb
#if defined(__CUDACC__)
#include <nanovdb/cuda/GridHandle.cuh>
#endif// defined(__CUDACC__)
#endif // NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
-590
View File
@@ -1,590 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
@file nanovdb/HostBuffer.h
@date April 20, 2021
@brief HostBuffer - a buffer that contains a shared or private bump
pool to either externally or internally managed host memory.
@details This HostBuffer can be used in multiple ways, most of which are
demonstrated in the examples below. Memory in the pool can
be managed or unmanged (e.g. internal or external) and can
be shared between multiple buffers or belong to a single buffer.
Example that uses HostBuffer::create inside io::readGrids to create a
full self-managed buffer, i.e. not shared and without padding, per grid in the file.
@code
auto handles = nanovdb::io::readGrids("file.nvdb");
@endcode
Example that uses HostBuffer::createFull. Assuming you have a raw pointer
to a NanoVDB grid of unknown type, this examples shows how to create its
GridHandle which can be used to enquire about the grid type and meta data.
@code
void *data;// pointer to a NanoVDB grid of unknown type
uint64_t size;// byte size of NanoVDB grid of unknown type
auto buffer = nanovdb::HostBuffer::createFull(size, data);
nanovdb::GridHandle<> gridHandle(std::move(buffer));
@endcode
Example that uses HostBuffer::createPool for internally managed host memory.
Suppose you want to read multiple grids in multiple files, but reuse the same
fixed sized memory buffer to both avoid memory fragmentation as well as
exceeding the fixed memory ceiling!
@code
auto pool = nanovdb::HostBuffer::createPool(1 << 30);// 1 GB memory pool
std::vector<std::string>> frames;// vector of grid names
for (int i=0; i<frames.size(); ++i) {
auto handles = nanovdb::io::readGrids(frames[i], 0, pool);// throws if grids in file exceed 1 GB
...
pool.reset();// clears all handles and resets the memory pool for reuse
}
@endcode
Example that uses HostBuffer::createPool for externally managed host memory.
Note that in this example @c handles are allowed to outlive @c pool since
they internally store a shared pointer to the memory pool. However @c data
MUST outlive @c handles since the pool does not own its memory in this example.
@code
const size_t poolSize = 1 << 30;// 1 GB
void *data = std::malloc(size + NANOVDB_DATA_ALIGNMENT);// 1 GB pool with padding
void *buffer = nanovdb::alignPtr(data);// 32B aligned buffer
//void *buffer = std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, poolSize);// in C++17
auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
auto handles1 = nanovdb::io::readGrids("file1.nvdb", 0, pool);
auto handles2 = nanovdb::io::readGrids("file2.nvdb", 0, pool);
....
std::free(data);
//std::free(buffer);
@endcode
Example that uses HostBuffer::createPool for externally managed host memory.
Note that in this example @c handles are allowed to outlive @c pool since
they internally store a shared pointer to the memory pool. However @c array
MUST outlive @c handles since the pool does not own its memory in this example.
@code
const size_t poolSize = 1 << 30;// 1 GB
std::unique_ptr<char[]> array(new char[size + NANOVDB_DATA_ALIGNMENT]);// scoped pool of 1 GB with padding
void *buffer = nanovdb::alignPtr(array.get());// 32B aligned buffer
auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
auto handles = nanovdb::io::readGrids("file.nvdb", 0, pool);
@endcode
*/
#ifndef NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
#define NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
#include <nanovdb/NanoVDB.h>// for NANOVDB_DATA_ALIGNMENT;
#include <stdint.h> // for types like int32_t etc
#include <cstdio> // for fprintf
#include <cstdlib> // for std::malloc/std::realloc/std::free
#include <memory>// for std::make_shared
#include <mutex>// for std::mutex
#include <unordered_set>// for std::unordered_set
#include <cassert>// for assert
#include <sstream>// for std::stringstream
#include <cstring>// for memcpy
#define checkPtr(ptr, msg) \
{ \
ptrAssert((ptr), (msg), __FILE__, __LINE__); \
}
namespace nanovdb {
template<typename BufferT>
struct BufferTraits
{
static constexpr bool hasDeviceDual = false;
};
// ----------------------------> HostBuffer <--------------------------------------
/// @brief This is a buffer that contains a shared or private pool
/// to either externally or internally managed host memory.
///
/// @note Terminology:
/// Pool: 0 = buffer.size() < buffer.poolSize()
/// Buffer: 0 < buffer.size() < buffer.poolSize()
/// Full: 0 < buffer.size() = buffer.poolSize()
/// Empty: 0 = buffer.size() = buffer.poolSize()
class HostBuffer
{
struct Pool;// forward declaration of private pool struct
std::shared_ptr<Pool> mPool;
uint64_t mSize; // total number of bytes for the NanoVDB grid.
void* mData; // raw buffer for the NanoVDB grid.
#if defined(DEBUG) || defined(_DEBUG)
static inline void ptrAssert(void* ptr, const char* msg, const char* file, int line, bool abort = true)
{
if (ptr == nullptr) {
fprintf(stderr, "NULL pointer error: %s %s %d\n", msg, file, line);
if (abort)
exit(1);
}
if (uint64_t(ptr) % NANOVDB_DATA_ALIGNMENT) {
fprintf(stderr, "Alignment pointer error: %s %s %d\n", msg, file, line);
if (abort)
exit(1);
}
}
#else
static inline void ptrAssert(void*, const char*, const char*, int, bool = true)
{
}
#endif
public:
/// @brief Return a full buffer or an empty buffer
HostBuffer(uint64_t bufferSize = 0);
/// @brief Move copy-constructor
HostBuffer(HostBuffer&& other);
/// @brief Custom descructor
~HostBuffer() { this->clear(); }
/// @brief Move copy assignment operation
HostBuffer& operator=(HostBuffer&& other);
/// @brief Disallow copy-construction
HostBuffer(const HostBuffer&) = delete;
/// @brief Disallow copy assignment operation
HostBuffer& operator=(const HostBuffer&) = delete;
/// @brief Return a pool buffer which satisfies: buffer.size == 0,
/// buffer.poolSize() == poolSize, and buffer.data() == nullptr.
/// If data==nullptr, memory for the pool will be allocated.
///
/// @throw If poolSize is zero.
static HostBuffer createPool(uint64_t poolSize, void *data = nullptr);
/// @brief Return a full buffer which satisfies: buffer.size == bufferSize,
/// buffer.poolSize() == bufferSize, and buffer.data() == data.
/// If data==nullptr, memory for the pool will be allocated.
///
/// @throw If bufferSize is zero.
static HostBuffer createFull(uint64_t bufferSize, void *data = nullptr);
/// @brief Return a buffer with @c bufferSize bytes managed by
/// the specified memory @c pool. If none is provided, i.e.
/// @c pool == nullptr or @c pool->poolSize() == 0, one is
/// created with size @c bufferSize, i.e. a full buffer is returned.
///
/// @throw If the specified @c pool has insufficient memory for
/// the requested buffer size.
static HostBuffer create(uint64_t bufferSize, const HostBuffer* pool = nullptr);
/// @brief Initialize as a full buffer with the specified size. If data is NULL
/// the memory is internally allocated.
void init(uint64_t bufferSize, void *data = nullptr);
//@{
/// @brief Retuns a pointer to the raw memory buffer managed by this allocator.
///
/// @warning Note that the pointer can be NULL if the allocator was not initialized!
const void* data() const { return mData; }
void* data() { return mData; }
//@}
//@{
/// @brief Returns the size in bytes associated with this buffer.
uint64_t bufferSize() const { return mSize; }
uint64_t size() const { return this->bufferSize(); }
//@}
/// @brief Returns the size in bytes of the memory pool shared with this instance.
uint64_t poolSize() const;
/// @brief Return true if memory is managed (using std::malloc and std:free) by the
/// shared pool in this buffer. Else memory is assumed to be managed externally.
bool isManaged() const;
//@{
/// @brief Returns true if this buffer has no memory associated with it
bool isEmpty() const { return !mPool || mSize == 0 || mData == nullptr; }
bool empty() const { return this->isEmpty(); }
//@}
/// @brief Return true if this is a pool, i.e. an empty buffer with a nonempty
/// internal pool, i.e. this->size() == 0 and this->poolSize() != 0
bool isPool() const { return mSize == 0 && this->poolSize() > 0; }
/// @brief Return true if the pool exists, is nonempty but has no more available memory
bool isFull() const;
/// @brief Clear this buffer so it is empty.
void clear();
/// @brief Clears all existing buffers that are registered against the memory pool
/// and resets the pool so it can be reused to create new buffers.
///
/// @throw If this instance is not empty or contains no pool.
///
/// @warning This method is not thread-safe!
void reset();
/// @brief Total number of bytes from the pool currently in use by buffers
uint64_t poolUsage() const;
/// @brief resize the pool size. It will attempt to resize the existing
/// memory block, but if that fails a deep copy is performed.
/// If @c data is not NULL it will be used as new externally
/// managed memory for the pool. All registered buffers are
/// updated so GridHandle::grid might return a new address (if
/// deep copy was performed).
///
/// @note This method can be use to resize the memory pool and even
/// change it from internally to externally managed memory or vice versa.
///
/// @throw if @c poolSize is less than this->poolUsage() the used memory
/// or allocations fail.
void resizePool(uint64_t poolSize, void *data = nullptr);
}; // HostBuffer class
// --------------------------> Implementation of HostBuffer::Pool <------------------------------------
// This is private struct of HostBuffer so you can safely ignore the API
struct HostBuffer::Pool
{
using HashTableT = std::unordered_set<HostBuffer*>;
std::mutex mMutex; // mutex for updating mRegister and mFree
HashTableT mRegister;
void *mData, *mFree;
uint64_t mSize, mPadding;
bool mManaged;
/// @brief External memory ctor
Pool(uint64_t size = 0, void* data = nullptr)
: mData(data)
, mFree(mData)
, mSize(size)
, mPadding(0)
, mManaged(data == nullptr)
{
if (mManaged) {
mData = Pool::alloc(mSize);
if (mData == nullptr) throw std::runtime_error("Pool::Pool malloc failed");
}
mPadding = alignmentPadding(mData);
if (!mManaged && mPadding != 0) {
throw std::runtime_error("Pool::Pool: external memory buffer is not aligned to " +
std::to_string(NANOVDB_DATA_ALIGNMENT) +
" bytes.\nHint: use nanovdb::alignPtr or std::aligned_alloc (C++17 only)");
}
mFree = util::PtrAdd(mData, mPadding);
}
/// @brief Custom destructor
~Pool()
{
assert(mRegister.empty());
if (mManaged) std::free(mData);
}
/// @brief Disallow copy-construction
Pool(const Pool&) = delete;
/// @brief Disallow move-construction
Pool(const Pool&&) = delete;
/// @brief Disallow copy assignment operation
Pool& operator=(const Pool&) = delete;
/// @brief Disallow move assignment operation
Pool& operator=(const Pool&&) = delete;
/// @brief Return the total number of bytes used from this Pool by buffers
uint64_t usage() const { return util::PtrDiff(mFree, mData) - mPadding; }
/// @brief Allocate a buffer of the specified size and add it to the register
void add(HostBuffer* buffer, uint64_t size)
{
void *alignedFree = util::PtrAdd(mFree, alignmentPadding(mFree));
if (util::PtrAdd(alignedFree, size) > util::PtrAdd(mData, mPadding + mSize)) {
std::stringstream ss;
ss << "HostBuffer::Pool: insufficient memory\n"
<< "\tA buffer requested " << size << " bytes with " << NANOVDB_DATA_ALIGNMENT
<< "-bytes alignment from a pool with "
<< mSize << " bytes of which\n\t" << (util::PtrDiff(alignedFree, mData) - mPadding)
<< " bytes are used by " << mRegister.size() << " other buffer(s). "
<< "Pool is " << (mManaged ? "internally" : "externally") << " managed.\n";
//std::cerr << ss.str();
throw std::runtime_error(ss.str());
}
buffer->mSize = size;
const std::lock_guard<std::mutex> lock(mMutex);
mRegister.insert(buffer);
buffer->mData = alignedFree;
mFree = util::PtrAdd(alignedFree, size);
}
/// @brief Remove the specified buffer from the register
void remove(HostBuffer *buffer)
{
const std::lock_guard<std::mutex> lock(mMutex);
mRegister.erase(buffer);
}
/// @brief Replaces buffer1 with buffer2 in the register
void replace(HostBuffer *buffer1, HostBuffer *buffer2)
{
const std::lock_guard<std::mutex> lock(mMutex);
mRegister.erase( buffer1);
mRegister.insert(buffer2);
}
/// @brief Reset the register and all its buffers
void reset()
{
for (HostBuffer *buffer : mRegister) {
buffer->mPool.reset();
buffer->mSize = 0;
buffer->mData = nullptr;
}
mRegister.clear();
mFree = util::PtrAdd(mData, mPadding);
}
/// @brief Resize this Pool and update registered buffers as needed. If data is no NULL
/// it is used as externally managed memory.
void resize(uint64_t size, void *data = nullptr)
{
const uint64_t memUsage = this->usage();
const bool managed = (data == nullptr);
if (!managed && alignmentPadding(data) != 0) {
throw std::runtime_error("Pool::resize: external memory buffer is not aligned to " +
std::to_string(NANOVDB_DATA_ALIGNMENT) + " bytes");
}
if (memUsage > size) {
throw std::runtime_error("Pool::resize: insufficient memory");
}
uint64_t padding = 0;
if (mManaged && managed && size != mSize) { // managed -> managed
padding = mPadding;
data = Pool::realloc(mData, memUsage, size, padding); // performs both copy and free of mData
} else if (!mManaged && managed) { // un-managed -> managed
data = Pool::alloc(size);
padding = alignmentPadding(data);
}
if (data == nullptr) {
throw std::runtime_error("Pool::resize: allocation failed");
} else if (data != mData) {
void* paddedData = util::PtrAdd(data, padding);
if (!(mManaged && managed)) { // no need to copy if managed -> managed
memcpy(paddedData, util::PtrAdd(mData, mPadding), memUsage);
}
for (HostBuffer* buffer : mRegister) { // update registered buffers
//buffer->mData = paddedData + ptrdiff_t(buffer->mData - (mData + mPadding));
buffer->mData = util::PtrAdd(paddedData, util::PtrDiff(buffer->mData, util::PtrAdd(mData, mPadding)));
}
mFree = util::PtrAdd(paddedData, memUsage); // update the free pointer
if (mManaged && !managed) {// only free if managed -> un-managed
std::free(mData);
}
mData = data;
mPadding = padding;
}
mSize = size;
mManaged = managed;
}
/// @brief Return true is all the memory in this pool is in use.
bool isFull() const
{
assert(mFree <= util::PtrAdd(mData, mPadding + mSize));
return mSize > 0 ? mFree == util::PtrAdd(mData, mPadding + mSize) : false;
}
private:
static void* alloc(uint64_t size)
{
//#if (__cplusplus >= 201703L)
// return std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, size);//C++17 or newer
//#else
// make sure we alloc enough space to align the result
return std::malloc(size + NANOVDB_DATA_ALIGNMENT);
//#endif
}
static void* realloc(void* const origData,
uint64_t origSize,
uint64_t desiredSize,
uint64_t& padding)
{
// make sure we alloc enough space to align the result
void* data = std::realloc(origData, desiredSize + NANOVDB_DATA_ALIGNMENT);
if (data != nullptr && data != origData) {
uint64_t newPadding = alignmentPadding(data);
// Number of padding bytes may have changed -- move data if that's the case
if (newPadding != padding) {
// Realloc should not happen when shrinking down buffer, but let's be safe
std::memmove(util::PtrAdd(data, newPadding),
util::PtrAdd(data, padding),
math::Min(origSize, desiredSize));
padding = newPadding;
}
}
return data;
}
};// struct HostBuffer::Pool
// --------------------------> Implementation of HostBuffer <------------------------------------
inline HostBuffer::HostBuffer(uint64_t size) : mPool(nullptr), mSize(size), mData(nullptr)
{
if (size>0) {
mPool = std::make_shared<Pool>(size);
mData = mPool->mFree;
mPool->mRegister.insert(this);
mPool->mFree = util::PtrAdd(mPool->mFree, size);
}
}
inline HostBuffer::HostBuffer(HostBuffer&& other) : mPool(other.mPool), mSize(other.mSize), mData(other.mData)
{
if (mPool && mSize != 0) {
mPool->replace(&other, this);
}
other.mPool.reset();
other.mSize = 0;
other.mData = nullptr;
}
inline void HostBuffer::init(uint64_t bufferSize, void *data)
{
if (bufferSize == 0) {
throw std::runtime_error("HostBuffer: invalid buffer size");
}
if (mPool) {
mPool.reset();
}
if (!mPool || mPool->mSize != bufferSize) {
mPool = std::make_shared<Pool>(bufferSize, data);
}
mPool->add(this, bufferSize);
}
inline HostBuffer& HostBuffer::operator=(HostBuffer&& other)
{
if (mPool) {
mPool->remove(this);
}
mPool = other.mPool;
mSize = other.mSize;
mData = other.mData;
if (mPool && mSize != 0) {
mPool->replace(&other, this);
}
other.mPool.reset();
other.mSize = 0;
other.mData = nullptr;
return *this;
}
inline uint64_t HostBuffer::poolSize() const
{
return mPool ? mPool->mSize : 0u;
}
inline uint64_t HostBuffer::poolUsage() const
{
return mPool ? mPool->usage(): 0u;
}
inline bool HostBuffer::isManaged() const
{
return mPool ? mPool->mManaged : false;
}
inline bool HostBuffer::isFull() const
{
return mPool ? mPool->isFull() : false;
}
inline HostBuffer HostBuffer::createPool(uint64_t poolSize, void *data)
{
if (poolSize == 0) {
throw std::runtime_error("HostBuffer: invalid pool size");
}
HostBuffer buffer;
buffer.mPool = std::make_shared<Pool>(poolSize, data);
// note the buffer is NOT registered by its pool since it is not using its memory
buffer.mSize = 0;
buffer.mData = nullptr;
return buffer;
}
inline HostBuffer HostBuffer::createFull(uint64_t bufferSize, void *data)
{
if (bufferSize == 0) {
throw std::runtime_error("HostBuffer: invalid buffer size");
}
HostBuffer buffer;
buffer.mPool = std::make_shared<Pool>(bufferSize, data);
buffer.mPool->add(&buffer, bufferSize);
return buffer;
}
inline HostBuffer HostBuffer::create(uint64_t bufferSize, const HostBuffer* pool)
{
HostBuffer buffer;
if (pool == nullptr || !pool->mPool) {
buffer.mPool = std::make_shared<Pool>(bufferSize);
} else {
buffer.mPool = pool->mPool;
}
buffer.mPool->add(&buffer, bufferSize);
return buffer;
}
inline void HostBuffer::clear()
{
if (mPool) {// remove self from the buffer register in the pool
mPool->remove(this);
}
mPool.reset();
mSize = 0;
mData = nullptr;
}
inline void HostBuffer::reset()
{
if (this->size()>0) {
throw std::runtime_error("HostBuffer: only empty buffers can call reset");
}
if (!mPool) {
throw std::runtime_error("HostBuffer: this buffer contains no pool to reset");
}
mPool->reset();
}
inline void HostBuffer::resizePool(uint64_t size, void *data)
{
if (!mPool) {
throw std::runtime_error("HostBuffer: this buffer contains no pool to resize");
}
mPool->resize(size, data);
}
} // namespace nanovdb
#endif // end of NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
File diff suppressed because it is too large Load Diff
-327
View File
@@ -1,327 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb/NodeManager.h
\author Ken Museth
\date February 12, 2021
\brief This class allows for sequential access to nodes
in a NanoVDB tree on both the host and device.
\details The ordering of the sequential access to nodes is always breadth-first!
*/
#include <nanovdb/NanoVDB.h>// for NanoGrid etc
#include <nanovdb/HostBuffer.h>// for HostBuffer
#ifndef NANOVDB_NODEMANAGER_H_HAS_BEEN_INCLUDED
#define NANOVDB_NODEMANAGER_H_HAS_BEEN_INCLUDED
namespace nanovdb {
/// @brief NodeManager allows for sequential access to nodes
template <typename BuildT>
class NodeManager;
/// @brief NodeManagerHandle manages the memory of a NodeManager
template<typename BufferT = HostBuffer>
class NodeManagerHandle;
/// @brief brief Construct a NodeManager and return its handle
///
/// @param grid grid whose nodes will be accessed sequentially
/// @param buffer buffer from which to allocate the output handle
///
/// @note This is the only way to create a NodeManager since it's using
/// managed memory pointed to by a NodeManagerHandle.
template <typename BuildT, typename BufferT = HostBuffer>
NodeManagerHandle<BufferT> createNodeManager(const NanoGrid<BuildT> &grid,
const BufferT& buffer = BufferT());
struct NodeManagerData
{// 48B = 6*8B
uint64_t mMagic;// 8B
union {int64_t mPadding; uint8_t mLinear;};// 8B of which 1B is used for a binary flag
void *mGrid;// 8B pointer to either host or device grid
union {int64_t *mPtr[3], mOff[3];};// 24B, use mOff if mLinear!=0
};
/// @brief This class serves to manage a raw memory buffer of a NanoVDB NodeManager or LeafManager.
template<typename BufferT>
class NodeManagerHandle
{
GridType mGridType{GridType::Unknown};
BufferT mBuffer;
template<typename BuildT>
const NodeManager<BuildT>* getMgr() const {
return mGridType == toGridType<BuildT>() ? (const NodeManager<BuildT>*)mBuffer.data() : nullptr;
}
template<typename BuildT, typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, const NodeManager<BuildT>*>::type
getDeviceMgr() const {
return mGridType == toGridType<BuildT>() ? (const NodeManager<BuildT>*)mBuffer.deviceData() : nullptr;
}
template <typename T>
static T* no_const(const T* ptr) { return const_cast<T*>(ptr); }
public:
/// @brief Move constructor from a buffer
NodeManagerHandle(GridType gridType, BufferT&& buffer) : mGridType(gridType) { mBuffer = std::move(buffer); }
/// @brief Empty ctor
NodeManagerHandle() = default;
/// @brief Disallow copy-construction
NodeManagerHandle(const NodeManagerHandle&) = delete;
/// @brief Disallow copy assignment operation
NodeManagerHandle& operator=(const NodeManagerHandle&) = delete;
/// @brief Move copy assignment operation
NodeManagerHandle& operator=(NodeManagerHandle&& other) noexcept {
mGridType = other.mGridType;
mBuffer = std::move(other.mBuffer);
other.mGridType = GridType::Unknown;
return *this;
}
/// @brief Move copy-constructor
NodeManagerHandle(NodeManagerHandle&& other) noexcept {
mGridType = other.mGridType;
mBuffer = std::move(other.mBuffer);
other.mGridType = GridType::Unknown;
}
/// @brief Default destructor
~NodeManagerHandle() { this->reset(); }
/// @brief clear the buffer
void reset() { mBuffer.clear(); }
/// @brief Return a reference to the buffer
BufferT& buffer() { return mBuffer; }
/// @brief Return a const reference to the buffer
const BufferT& buffer() const { return mBuffer; }
/// @brief Returns a non-const pointer to the data.
///
/// @warning Note that the return pointer can be NULL if the NodeManagerHandle was not initialized
void* data() { return mBuffer.data(); }
/// @brief Returns a const pointer to the data.
///
/// @warning Note that the return pointer can be NULL if the NodeManagerHandle was not initialized
const void* data() const { return mBuffer.data(); }
/// @brief Returns the size in bytes of the raw memory buffer managed by this NodeManagerHandle's allocator.
uint64_t size() const { return mBuffer.size(); }
/// @brief Returns a const pointer to the NodeManager encoded in this NodeManagerHandle.
///
/// @warning Note that the return pointer can be NULL if the template parameter does not match the specified grid!
template<typename BuildT>
const NodeManager<BuildT>* mgr() const { return this->template getMgr<BuildT>(); }
/// @brief Returns a pointer to the NodeManager encoded in this NodeManagerHandle.
///
/// @warning Note that the return pointer can be NULL if the template parameter does not match the specified grid!
template<typename BuildT>
NodeManager<BuildT>* mgr() { return no_const(this->template getMgr<BuildT>()); }
/// @brief Return a const pointer to the NodeManager encoded in this NodeManagerHandle on the device, e.g. GPU
///
/// @warning Note that the return pointer can be NULL if the template parameter does not match the specified grid!
template<typename BuildT, typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, const NodeManager<BuildT>*>::type
deviceMgr() const { return this->template getDeviceMgr<BuildT>(); }
/// @brief Return a const pointer to the NodeManager encoded in this NodeManagerHandle on the device, e.g. GPU
///
/// @warning Note that the return pointer can be NULL if the template parameter does not match the specified grid!
template<typename BuildT, typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, NodeManager<BuildT>*>::type
deviceMgr() { return no_const(this->template getDeviceMgr<BuildT>()); }
/// @brief Upload the NodeManager to the device, e.g. from CPU to GPU
///
/// @note This method is only available if the buffer supports devices
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceUpload(void* deviceGrid, void* stream = nullptr, bool sync = true)
{
assert(deviceGrid);
auto *data = reinterpret_cast<NodeManagerData*>(mBuffer.data());
void *tmp = data->mGrid;
data->mGrid = deviceGrid;
mBuffer.deviceUpload(stream, sync);
data->mGrid = tmp;
}
/// @brief Download the NodeManager to from the device, e.g. from GPU to CPU
///
/// @note This method is only available if the buffer supports devices
template<typename U = BufferT>
typename util::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
deviceDownload(void* stream = nullptr, bool sync = true)
{
auto *data = reinterpret_cast<NodeManagerData*>(mBuffer.data());
void *tmp = data->mGrid;
mBuffer.deviceDownload(stream, sync);
data->mGrid = tmp;
}
};// NodeManagerHandle
/// @brief This class allows for sequential access to nodes in a NanoVDB tree
///
/// @details Nodes are always arranged breadth first during sequential access of nodes
/// at a particular level.
template<typename BuildT>
class NodeManager : private NodeManagerData
{
using DataT = NodeManagerData;
using GridT = NanoGrid<BuildT>;
using TreeT = typename GridTree<GridT>::type;
template<int LEVEL>
using NodeT = typename NodeTrait<TreeT, LEVEL>::type;
using RootT = NodeT<3>;// root node
using Node2 = NodeT<2>;// upper internal node
using Node1 = NodeT<1>;// lower internal node
using Node0 = NodeT<0>;// leaf node
public:
static constexpr bool FIXED_SIZE = Node0::FIXED_SIZE && Node1::FIXED_SIZE && Node2::FIXED_SIZE;
NodeManager(const NodeManager&) = delete;
NodeManager(NodeManager&&) = delete;
NodeManager& operator=(const NodeManager&) = delete;
NodeManager& operator=(NodeManager&&) = delete;
~NodeManager() = delete;
/// @brief return true if the nodes have both fixed size and are arranged breadth-first in memory.
/// This allows for direct and memory-efficient linear access to nodes.
__hostdev__ static bool isLinear(const GridT &grid) {return FIXED_SIZE && grid.isBreadthFirst();}
/// @brief return true if the nodes have both fixed size and are arranged breadth-first in memory.
/// This allows for direct and memory-efficient linear access to nodes.
__hostdev__ bool isLinear() const {return DataT::mLinear!=0u;}
/// @brief Return the memory footprint in bytes of the NodeManager derived from the specified grid
__hostdev__ static uint64_t memUsage(const GridT &grid) {
uint64_t size = sizeof(NodeManagerData);
if (!NodeManager::isLinear(grid)) {
const uint32_t *p = grid.tree().mNodeCount;
size += sizeof(int64_t)*(p[0]+p[1]+p[2]);
}
return size;
}
/// @brief Return the memory footprint in bytes of this instance
__hostdev__ uint64_t memUsage() const {return NodeManager::memUsage(this->grid());}
/// @brief Return a reference to the grid
__hostdev__ GridT& grid() { return *reinterpret_cast<GridT*>(DataT::mGrid); }
__hostdev__ const GridT& grid() const { return *reinterpret_cast<const GridT*>(DataT::mGrid); }
/// @brief Return a reference to the tree
__hostdev__ TreeT& tree() { return this->grid().tree(); }
__hostdev__ const TreeT& tree() const { return this->grid().tree(); }
/// @brief Return a reference to the root
__hostdev__ RootT& root() { return this->tree().root(); }
__hostdev__ const RootT& root() const { return this->tree().root(); }
/// @brief Return the number of tree nodes at the specified level
/// @details 0 is leaf, 1 is lower internal, and 2 is upper internal level
__hostdev__ uint64_t nodeCount(int level) const { return this->tree().nodeCount(level); }
__hostdev__ uint64_t leafCount() const { return this->tree().nodeCount(0); }
__hostdev__ uint64_t lowerCount() const { return this->tree().nodeCount(1); }
__hostdev__ uint64_t upperCount() const { return this->tree().nodeCount(2); }
/// @brief Return the i'th leaf node with respect to breadth-first ordering
template <int LEVEL>
__hostdev__ const NodeT<LEVEL>& node(uint32_t i) const {
NANOVDB_ASSERT(i < this->nodeCount(LEVEL));
const NodeT<LEVEL>* ptr = nullptr;
if (DataT::mLinear) {
ptr = util::PtrAdd<const NodeT<LEVEL>>(DataT::mGrid, DataT::mOff[LEVEL]) + i;
} else {
ptr = util::PtrAdd<const NodeT<LEVEL>>(DataT::mGrid, DataT::mPtr[LEVEL][i]);
}
NANOVDB_ASSERT(ptr && isAligned(ptr));
return *ptr;
}
/// @brief Return the i'th node with respect to breadth-first ordering
template <int LEVEL>
__hostdev__ NodeT<LEVEL>& node(uint32_t i) {
NANOVDB_ASSERT(i < this->nodeCount(LEVEL));
NodeT<LEVEL>* ptr = nullptr;
if (DataT::mLinear) {
ptr = util::PtrAdd<NodeT<LEVEL>>(DataT::mGrid, DataT::mOff[LEVEL]) + i;
} else {
ptr = util::PtrAdd<NodeT<LEVEL>>(DataT::mGrid, DataT::mPtr[LEVEL][i]);
}
NANOVDB_ASSERT(ptr && isAligned(ptr));
return *ptr;
}
/// @brief Return the i'th leaf node with respect to breadth-first ordering
__hostdev__ const Node0& leaf(uint32_t i) const { return this->node<0>(i); }
__hostdev__ Node0& leaf(uint32_t i) { return this->node<0>(i); }
/// @brief Return the i'th lower internal node with respect to breadth-first ordering
__hostdev__ const Node1& lower(uint32_t i) const { return this->node<1>(i); }
__hostdev__ Node1& lower(uint32_t i) { return this->node<1>(i); }
/// @brief Return the i'th upper internal node with respect to breadth-first ordering
__hostdev__ const Node2& upper(uint32_t i) const { return this->node<2>(i); }
__hostdev__ Node2& upper(uint32_t i) { return this->node<2>(i); }
}; // NodeManager<BuildT> class
template <typename BuildT, typename BufferT>
NodeManagerHandle<BufferT> createNodeManager(const NanoGrid<BuildT> &grid,
const BufferT& buffer)
{
NodeManagerHandle<BufferT> handle(toGridType<BuildT>(), BufferT::create(NodeManager<BuildT>::memUsage(grid), &buffer));
auto *data = reinterpret_cast<NodeManagerData*>(handle.data());
NANOVDB_ASSERT(data && isAligned(data));
NANOVDB_ASSERT(toGridType<BuildT>() == grid.gridType());
#ifdef NANOVDB_USE_NEW_MAGIC_NUMBERS
*data = NodeManagerData{NANOVDB_MAGIC_NODE, {0u}, (void*)&grid, {{0u,0u,0u}}};
#else
*data = NodeManagerData{NANOVDB_MAGIC_NUMB, {0u}, (void*)&grid, {{0u,0u,0u}}};
#endif
if (NodeManager<BuildT>::isLinear(grid)) {
data->mLinear = uint8_t(1u);
data->mOff[0] = util::PtrDiff(grid.tree().template getFirstNode<0>(), &grid);
data->mOff[1] = util::PtrDiff(grid.tree().template getFirstNode<1>(), &grid);
data->mOff[2] = util::PtrDiff(grid.tree().template getFirstNode<2>(), &grid);
} else {
int64_t *ptr0 = data->mPtr[0] = reinterpret_cast<int64_t*>(data + 1);
int64_t *ptr1 = data->mPtr[1] = data->mPtr[0] + grid.tree().nodeCount(0);
int64_t *ptr2 = data->mPtr[2] = data->mPtr[1] + grid.tree().nodeCount(1);
// Performs depth first traversal but breadth first insertion
for (auto it2 = grid.tree().root().cbeginChild(); it2; ++it2) {
*ptr2++ = util::PtrDiff(&*it2, &grid);
for (auto it1 = it2->cbeginChild(); it1; ++it1) {
*ptr1++ = util::PtrDiff(&*it1, &grid);
for (auto it0 = it1->cbeginChild(); it0; ++it0) {
*ptr0++ = util::PtrDiff(&*it0, &grid);
}// loop over child nodes of the lower internal node
}// loop over child nodes of the upper internal node
}// loop over child nodes of the root node
}
return handle;// // is converted to r-value so return value is move constructed!
}// createNodeManager
} // namespace nanovdb
#if defined(__CUDACC__)
#include <nanovdb/cuda/NodeManager.cuh>
#endif// defined(__CUDACC__)
#endif // NANOVDB_NODEMANAGER_H_HAS_BEEN_INCLUDED
File diff suppressed because it is too large Load Diff
-14
View File
@@ -1,14 +0,0 @@
<img src="https://www.openvdb.org/images/nanovdb_logo.png" height="150">
# NanoVDB:
A lightweight GPU friendly version of VDB initially targeting rendering applications.
* [Build instructions for make and cmake](../../doc/nanovdb/HowToBuild.md)
* [Frequently asked questions](../../doc/nanovdb/FAQ.md)
* [Source tree](../../doc/nanovdb/SourceTree.md)
* [Examples](../../doc/nanovdb/HelloWorld.md)
### Copyright Contributors to the OpenVDB Project
### SPDX-License-Identifier: Apache-2.0
[![CircleCI](https://circleci.com/gh/NVIDIA-Omniverse/NanoVDB.svg?style=svg&circle-token=6c3b9bb166841033a0e0c1a9ee5ac49f73d89152)](https://circleci.com/gh/NVIDIA-Omniverse/NanoVDB)
-48
View File
@@ -1,48 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#
#[=======================================================================[
CMake Configuration for NanoVDB Command Line Tools
#]=======================================================================]
cmake_minimum_required(VERSION 3.20)
project(NanoVDBExamples LANGUAGES CXX)
include(GNUInstallDirs)
###############################################################################
message(STATUS "----------------------------------------------------")
message(STATUS "--------- Configuring NanoVDB Cmd Tools ------------")
message(STATUS "----------------------------------------------------")
###############################################################################
# -----------------------------------------------------------------------------
# workaround for win32 bug when nvcc "--keep" is used.
if(WIN32 AND NANOVDB_CUDA_KEEP_PTX)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/Release")
endif()
# -----------------------------------------------------------------------------
if(NOT NANOVDB_USE_OPENVDB)
message(WARNING " - OpenVDB required to build nanovdb_convert. Skipping.")
else()
add_executable(nanovdb_convert convert/nanovdb_convert.cc)
target_link_libraries(nanovdb_convert PRIVATE nanovdb)
install(TARGETS nanovdb_convert RUNTIME DESTINATION ${NANOVDB_INSTALL_BINDIR})
endif()
# -----------------------------------------------------------------------------
# nanovdb_print
add_executable(nanovdb_print print/nanovdb_print.cc)
target_link_libraries(nanovdb_print PRIVATE nanovdb)
install(TARGETS nanovdb_print RUNTIME DESTINATION ${NANOVDB_INSTALL_BINDIR})
# -----------------------------------------------------------------------------
# nanovdb_validate
add_executable(nanovdb_validate validate/nanovdb_validate.cc)
target_link_libraries(nanovdb_validate PRIVATE nanovdb)
install(TARGETS nanovdb_validate RUNTIME DESTINATION ${NANOVDB_INSTALL_BINDIR})
@@ -1,307 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb_convert.cc
\author Ken Museth
\date May 21, 2020
\brief Command-line tool that converts between openvdb and nanovdb files
*/
#include <string>
#include <algorithm>
#include <cctype>
#include <nanovdb/io/IO.h> // this is required to read (and write) NanoVDB files on the host
#include <nanovdb/tools/CreateNanoGrid.h>
#include <nanovdb/tools/NanoToOpenVDB.h>
void usage [[noreturn]] (const std::string& progName, int exitStatus = EXIT_FAILURE)
{
std::cerr << "\nUsage: " << progName << " [options] *.vdb output.nvdb\n"
<< "Which: converts one or more OpenVDB files to a single NanoVDB file\n\n"
<< "Usage: " << progName << " [options] *.nvdb output.vdb\n"
<< "Which: converts one or more NanoVDB files to a single OpenVDB file\n\n"
<< "Options:\n"
<< "-a,--abs-error float\t Absolute error tolerance used for variable bit depth quantization\n"
<< "-b,--blosc\tUse BLOSC compression on the output file\n"
<< "-c,--checksum mode\t where mode={none, partial, full}\n"
<< "-d,--dither\tApply dithering during blocked compression\n"
<< "-f,--force\tOverwrite output file if it already exists\n"
<< "--fp4\tQuantize float grids to 4 bits\n"
<< "--fp8\tQuantize float grids to 8 bits\n"
<< "--fp16\tQuantize float grids to 16 bits\n"
<< "--fpN\tQuantize float grids to variable bit depth (use -a or -r to specify a tolerance)\n"
<< "-g,--grid name\tConvert all grids matching the specified string name\n"
<< "-h,--help\tPrints this message\n"
<< "-r,--rel-error float\t Relative error tolerance used for variable bit depth quantization\n"
<< "-s,--stats mode\t where mode={none, bbox, extrema, all}\n"
<< "-v,--verbose\tPrint verbose information to the terminal\n"
<< "--version\tPrint version information to the terminal\n"
<< "-z,--zip\tUse ZIP compression on the output file\n";
exit(exitStatus);
}
void version [[noreturn]] (const char* progName, int exitStatus = EXIT_SUCCESS)
{
char str[8];
nanovdb::toStr(str, nanovdb::Version());
printf("\n%s was build against NanoVDB version %s\n", progName, str);
exit(exitStatus);
}
int main(int argc, char* argv[])
{
int exitStatus = EXIT_SUCCESS;
nanovdb::io::Codec codec = nanovdb::io::Codec::NONE;// compression codec for the file
nanovdb::tools::StatsMode sMode = nanovdb::tools::StatsMode::Default;
nanovdb::CheckMode cMode = nanovdb::CheckMode::Default;
nanovdb::GridType qMode = nanovdb::GridType::Unknown;//specify the quantization mode
bool verbose = false, overwrite = false, dither = false, absolute = true;
float tolerance = -1.0f;
std::string gridName;
std::vector<std::string> fileNames;
auto toLowerCase = [](std::string &str) {
std::transform(str.begin(), str.end(), str.begin(),[](unsigned char c){return std::tolower(c);});
};
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg[0] == '-') {
if (arg == "-v" || arg == "--verbose") {
verbose = true;
} else if (arg == "--version") {
version(argv[0]);
} else if (arg == "-f" || arg == "--force") {
overwrite = true;
} else if (arg == "--fp4") {
qMode = nanovdb::GridType::Fp4;
} else if (arg == "--fp8") {
qMode = nanovdb::GridType::Fp8;
} else if (arg == "--fp16") {
qMode = nanovdb::GridType::Fp16;
} else if (arg == "--fpN") {
qMode = nanovdb::GridType::FpN;
} else if (arg == "-h" || arg == "--help") {
usage(argv[0], EXIT_SUCCESS);
} else if (arg == "-b" || arg == "--blosc") {
codec = nanovdb::io::Codec::BLOSC;
} else if (arg == "-d" || arg == "--dither") {
dither = true;
} else if (arg == "-z" || arg == "--zip") {
codec = nanovdb::io::Codec::ZIP;
} else if (arg == "-c" || arg == "--checksum") {
if (i + 1 == argc) {
std::cerr << "Expected a mode to follow the -c,--checksum option\n" << std::endl;
usage(argv[0]);
} else {
std::string str(argv[++i]);
toLowerCase(str);
if (str == "none") {
cMode = nanovdb::CheckMode::Disable;
} else if (str == "partial") {
cMode = nanovdb::CheckMode::Partial;
} else if (str == "full") {
cMode = nanovdb::CheckMode::Full;
} else {
std::cerr << "Expected one of the following checksum modes: {none, partial, full}\n" << std::endl;
usage(argv[0]);
}
}
} else if (arg == "-s" || arg == "--stats") {
if (i + 1 == argc) {
std::cerr << "Expected a mode to follow the -s,--stats option\n" << std::endl;
usage(argv[0]);
} else {
std::string str(argv[++i]);
toLowerCase(str);
if (str == "none") {
sMode = nanovdb::tools::StatsMode::Disable;
} else if (str == "bbox") {
sMode = nanovdb::tools::StatsMode::BBox;
} else if (str == "extrema") {
sMode = nanovdb::tools::StatsMode::MinMax;
} else if (str == "all") {
sMode = nanovdb::tools::StatsMode::All;
} else {
std::cerr << "Expected one of the following stats modes: {none, bbox, extrema, all}\n" << std::endl;
usage(argv[0]);
}
}
} else if (arg == "-a" || arg == "--abs-error") {
if (i + 1 == argc) {
std::cerr << "Expected a float to follow the -a,--abs-error option\n" << std::endl;
usage(argv[0]);
} else {
qMode = nanovdb::GridType::FpN;
absolute = true;
tolerance = static_cast<float>(atof(argv[++i]));
}
} else if (arg == "-r" || arg == "--rel-error") {
if (i + 1 == argc) {
std::cerr << "Expected a float to follow the -r,--rel-error option\n" << std::endl;
usage(argv[0]);
} else {
qMode = nanovdb::GridType::FpN;
absolute = false;
tolerance = static_cast<float>(atof(argv[++i]));
}
} else if (arg == "-g" || arg == "--grid") {
if (i + 1 == argc) {
std::cerr << "Expected a grid name to follow the -g,--grid option\n" << std::endl;
usage(argv[0]);
} else {
gridName.assign(argv[++i]);
}
} else {
std::cerr << "\nIllegal option: \"" << arg << "\"\n";
usage(argv[0]);
}
} else if (!arg.empty()) {
fileNames.push_back(arg);
}
}
if (fileNames.size() < 2) {
std::cerr << "Expected at least one input file followed by exactly one output file\n" << std::endl;
usage(argv[0]);
}
const std::string outputFile = fileNames.back();
const std::string ext = outputFile.substr(outputFile.find_last_of(".") + 1);
bool toNanoVDB = false;
if (ext == "nvdb") {
toNanoVDB = true;
} else if (ext != "vdb") {
std::cerr << "Unrecognized file extension: \"" << ext << "\"\n" << std::endl;
usage(argv[0]);
}
fileNames.pop_back();
if (!overwrite) {
std::ifstream is(outputFile, std::ios::in | std::ios::binary);
if (is.peek() != std::ifstream::traits_type::eof()) {
std::cout << "Overwrite the existing output file named \"" << outputFile << "\"? [Y]/N: ";
std::string answer;
getline(std::cin, answer);
toLowerCase(answer);
if (!answer.empty() && answer != "y" && answer != "yes") {
std::cout << "Please specify a different output file" << std::endl;
exit(EXIT_SUCCESS);
}
}
}
openvdb::initialize();
// Note, unlike OpenVDB, NanoVDB allows for multiple write operations into the same output file stream.
// Hence, NanoVDB grids can be read, converted and written to file one at a time whereas all
// the OpenVDB grids has to be written to file in a single operation.
auto openToNano = [&](const openvdb::GridBase::Ptr& base)
{
using SrcGridT = openvdb::FloatGrid;
if (auto floatGrid = openvdb::GridBase::grid<SrcGridT>(base)) {
nanovdb::tools::CreateNanoGrid<SrcGridT> s(*floatGrid);
s.setStats(sMode);
s.setChecksum(cMode);
s.enableDithering(dither);
s.setVerbose(verbose ? 1 : 0);
switch (qMode) {
case nanovdb::GridType::Fp4:
return s.getHandle<nanovdb::Fp4>();
case nanovdb::GridType::Fp8:
return s.getHandle<nanovdb::Fp8>();
case nanovdb::GridType::Fp16:
return s.getHandle<nanovdb::Fp16>();
case nanovdb::GridType::FpN:
if (absolute) {
return s.getHandle<nanovdb::FpN>(nanovdb::tools::AbsDiff(tolerance));
} else {
return s.getHandle<nanovdb::FpN>(nanovdb::tools::RelDiff(tolerance));
}
default:
break;
}// end of switch
}
return nanovdb::tools::openToNanoVDB(base, sMode, cMode, verbose ? 1 : 0);
};
try {
if (toNanoVDB) { // OpenVDB -> NanoVDB
std::ofstream os(outputFile, std::ios::out | std::ios::binary);
for (auto& inputFile : fileNames) {
if (inputFile.substr(inputFile.find_last_of(".") + 1) != "vdb") {
std::cerr << "Since the last file has extension .nvdb the remaining input files were expected to have extensions .vdb\n" << std::endl;
usage(argv[0]);
}
if (verbose)
std::cout << "Opening OpenVDB file named \"" << inputFile << "\"" << std::endl;
openvdb::io::File file(inputFile);
file.open(false); //disable delayed loading
if (gridName.empty()) {// convert all grid in the file
auto grids = file.getGrids();
std::vector<nanovdb::GridHandle<nanovdb::HostBuffer> > handles;
for (auto& grid : *grids) {
if (verbose) {
std::cout << "Converting OpenVDB grid named \"" << grid->getName() << "\" to NanoVDB" << std::endl;
}
handles.push_back(openToNano(grid));
} // loop over OpenVDB grids in file
auto handle = nanovdb::mergeGrids<nanovdb::HostBuffer, std::vector>(handles);
nanovdb::io::writeGrid(os, handle, codec);
} else {// convert only grid with matching name
auto grid = file.readGrid(gridName);
if (verbose) {
std::cout << "Converting OpenVDB grid named \"" << grid->getName() << "\" to NanoVDB" << std::endl;
}
auto handle = openToNano(grid);
nanovdb::io::writeGrid(os, handle, codec);
}
} // loop over input files
} else { // NanoVDB -> OpenVDB
openvdb::io::File file(outputFile);
openvdb::GridPtrVecPtr grids(new openvdb::GridPtrVec());
for (auto& inputFile : fileNames) {
if (inputFile.substr(inputFile.find_last_of(".") + 1) != "nvdb") {
std::cerr << "Since the last file has extension .vdb the remaining input files were expected to have extensions .nvdb\n" << std::endl;
usage(argv[0]);
}
if (verbose)
std::cout << "Opening NanoVDB file named \"" << inputFile << "\"" << std::endl;
if (gridName.empty()) {
auto handles = nanovdb::io::readGrids(inputFile, verbose);
for (auto &h : handles) {
for (uint32_t i = 0; i < h.gridCount(); ++i) {
if (verbose)
std::cout << "Converting NanoVDB grid named \"" << h.gridMetaData(i)->shortGridName() << "\" to OpenVDB" << std::endl;
grids->push_back(nanovdb::tools::nanoToOpenVDB(h, 0, i));
}
}
} else {
auto handle = nanovdb::io::readGrid(inputFile, gridName);
if (!handle) {
std::cerr << "File did not contain a NanoVDB grid named \"" << gridName << "\"\n" << std::endl;
usage(argv[0]);
}
if (verbose)
std::cout << "Converting NanoVDB grid named \"" << handle.gridMetaData()->shortGridName() << "\" to OpenVDB" << std::endl;
grids->push_back(nanovdb::tools::nanoToOpenVDB(handle));
}
} // loop over input files
file.write(*grids);
}
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
exitStatus = EXIT_FAILURE;
}
catch (...) {
std::cerr << "Exception oof unexpected type caught" << std::endl;
exitStatus = EXIT_FAILURE;
}
return exitStatus;
}
-327
View File
@@ -1,327 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb_print.cc
\author Ken Museth
\date May 21, 2020
\brief Command-line tool that prints information about grids in a nanovdb file
*/
#include <nanovdb/io/IO.h> // this is required to read (and write) NanoVDB files on the host
#include <iomanip>
#include <sstream>
void usage [[noreturn]] (const std::string& progName, int exitStatus = EXIT_FAILURE)
{
std::cerr << "\nUsage: " << progName << " [options] *.nvdb\n"
<< "Which: Prints grid information from one or more NanoVDB files\n\n"
<< "Options:\n"
<< "-g,--grid name\tPrint all grids matching the specified string name\n"
<< "-h,--help\tPrints this message\n"
<< "-l,--long\tPrints out extra grid information\n"
<< "-s,--short\tOnly prints out a minimum amount of grid information\n"
<< "-v,--verbose\tPrint information about the meaning of the labels\n"
<< "--version\tPrint version information to the terminal\n";
exit(exitStatus);
}
void version [[noreturn]] (const char* progName, int exitStatus = EXIT_SUCCESS)
{
char str[8];
nanovdb::toStr(str, nanovdb::Version());
printf("\n%s was build against NanoVDB version %s\n", progName, str);
exit(exitStatus);
}
int main(int argc, char* argv[])
{
int exitStatus = EXIT_SUCCESS;
enum Mode : int { Short = 0,
Default = 1,
Long = 2 } mode = Default;
char str[32];
bool verbose = false;
std::string gridName;
std::vector<std::string> fileNames;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg[0] == '-') {
if (arg == "-h" || arg == "--help") {
usage(argv[0], EXIT_SUCCESS);
} else if (arg == "--version") {
version(argv[0]);
} else if (arg == "-s" || arg == "--short") {
mode = Short;
} else if (arg == "-l" || arg == "--long") {
mode = Long;
} else if (arg == "-v" || arg == "--verbose") {
verbose = true;
} else if (arg == "-g" || arg == "--grid") {
if (i + 1 == argc) {
std::cerr << "\nExpected a grid name to follow the -g,--grid option\n";
usage(argv[0]);
} else {
gridName.assign(argv[++i]);
}
} else {
std::cerr << "\nIllegal option: \"" << arg << "\"\n";
usage(argv[0]);
}
} else if (!arg.empty()) {
fileNames.push_back(arg);
}
}
if (fileNames.size() == 0) {
std::cerr << "\nExpected at least one input NanoVDB file\n";
usage(argv[0]);
}
const auto nameKey = nanovdb::io::stringHash(gridName);
auto format = [](uint64_t b) {
std::stringstream ss;
ss << std::setprecision(4);
if (b >> 40) {
ss << double(b) / double(1ULL << 40) << " TB";
} else if (b >> 30) {
ss << double(b) / double(1ULL << 30) << " GB";
} else if (b >> 20) {
ss << double(b) / double(1ULL << 20) << " MB";
} else if (b >> 10) {
ss << double(b) / double(1ULL << 10) << " KB";
} else {
ss << b << " Bytes";
}
return ss.str();
};
const int padding = 2;
auto width = [&](size_t& n, const std::string& str) {
const auto size = str.length() + padding;
if (size > n)
n = size;
};
auto Vec3dToStr = [](const nanovdb::Vec3d& v) {
std::stringstream ss;
ss << std::setprecision(3);
ss << "(" << v[0] << "," << v[1] << "," << v[2] << ")";
return ss.str();
};
auto wbboxToStr = [](const nanovdb::math::BBox<nanovdb::Vec3d>& bbox) {
std::stringstream ss;
if (bbox.empty()) {
ss << "empty grid";
} else {
ss << std::setprecision(3);
ss << "(" << bbox[0][0] << "," << bbox[0][1] << "," << bbox[0][2] << ")";
ss << " -> ";
ss << "(" << bbox[1][0] << "," << bbox[1][1] << "," << bbox[1][2] << ")";
}
return ss.str();
};
auto ibboxToStr = [](const nanovdb::CoordBBox& bbox) {
std::stringstream ss;
if (bbox.empty()) {
ss << "empty grid";
} else {
ss << "(" << bbox[0][0] << "," << bbox[0][1] << "," << bbox[0][2] << ")";
ss << " -> ";
ss << "(" << bbox[1][0] << "," << bbox[1][1] << "," << bbox[1][2] << ")";
}
return ss.str();
};
auto resToStr = [](const nanovdb::CoordBBox& bbox) {
std::stringstream ss;
auto dim = bbox.dim();
ss << dim[0] << " x " << dim[1] << " x " << dim[2];
return ss.str();
};
auto nodesToStr = [](const uint32_t* nodes) {
std::stringstream ss;
ss << nodes[2] << "->" << nodes[1] << "->" << nodes[0];
return ss.str();
};
try {
for (auto& file : fileNames) {
auto list = nanovdb::io::readGridMetaData(file);
if (!gridName.empty()) {
std::vector<nanovdb::io::FileGridMetaData> tmp;
for (auto& m : list) {
if (nameKey == m.nameKey && gridName == m.gridName)
tmp.emplace_back(m);
}
list = tmp;
}
if (list.size() == 0)
continue;
const auto numberWidth = std::to_string(list.size()).length() + padding;
auto nameWidth = std::string("Name").length() + padding;
auto typeWidth = std::string("Type").length() + padding;
auto classWidth = std::string("Class").length() + padding;
auto codecWidth = std::string("Codec").length() + padding;
auto ibboxWidth = std::string("Index Bounding Box").length() + padding;
auto wbboxWidth = std::string("World BBox").length() + padding;
auto sizeWidth = std::string("Size").length() + padding;
auto fileWidth = std::string("File").length() + padding;
auto voxelsWidth = std::string("# Voxels").length() + padding;
auto voxelSizeWidth = std::string("Scale").length() + padding;
auto versionWidth = std::string("Version").length() + padding;
auto configWidth = std::string("32^3->16^3->8^3").length() + padding;
auto tileWidth = std::string("# Active tiles").length() + padding;
auto resWidth = std::string("Resolution").length() + padding;
for (auto& m : list) {
width(nameWidth, m.gridName);
width(typeWidth, nanovdb::toStr(str, m.gridType));
width(classWidth, nanovdb::toStr(str, m.gridClass));
width(codecWidth, nanovdb::io::toStr(str, m.codec));
width(wbboxWidth, wbboxToStr(m.worldBBox));
width(ibboxWidth, ibboxToStr(m.indexBBox));
width(resWidth, resToStr(m.indexBBox));
width(sizeWidth, format(m.gridSize));
width(fileWidth, format(m.fileSize));
width(versionWidth, nanovdb::toStr(str, m.version));
width(configWidth, nodesToStr(m.nodeCount));
width(tileWidth, nodesToStr(m.tileCount));
width(voxelsWidth, std::to_string(m.voxelCount));
width(voxelSizeWidth, Vec3dToStr(m.voxelSize));
}
std::cout << "\nThe file \"" << file << "\" contains the following ";
if (list.size()>1) {
std::cout << list.size() << " grids:\n";
} else {
std::cout << "grid:\n";
}
std::cout << std::left << std::setw(numberWidth) << "#"
<< std::left << std::setw(nameWidth) << "Name"
<< std::left << std::setw(typeWidth) << "Type";
if (mode != Short) {
std::cout << std::left << std::setw(classWidth) << "Class"
<< std::left << std::setw(versionWidth) << "Version"
<< std::left << std::setw(codecWidth) << "Codec"
<< std::left << std::setw(sizeWidth) << "Size"
<< std::left << std::setw(fileWidth) << "File"
<< std::left << std::setw(voxelSizeWidth) << "Scale";
}
std::cout << std::left << std::setw(voxelsWidth) << "# Voxels"
<< std::left << std::setw(resWidth) << "Resolution";
if (mode == Long) {
std::cout << std::left << std::setw(configWidth) << "32^3->16^3->8^3"
<< std::left << std::setw(tileWidth) << "# Active tiles"
<< std::left << std::setw(ibboxWidth) << "Index Bounding Box"
<< std::left << std::setw(wbboxWidth) << "World Bounding Box";
}
std::cout << std::endl;
int n = 0;
for (auto& m : list) {
if (!gridName.empty() && (nameKey != m.nameKey || gridName != m.gridName))
continue;
std::cout << std::left << std::setw(numberWidth) << ++n
<< std::left << std::setw(nameWidth) << m.gridName
<< std::left << std::setw(typeWidth) << nanovdb::toStr(str, m.gridType);
if (mode != Short) {
std::cout << std::left << std::setw(classWidth) << nanovdb::toStr(str, m.gridClass)
<< std::left << std::setw(versionWidth) << nanovdb::toStr(str+10, m.version)
<< std::left << std::setw(codecWidth) << nanovdb::io::toStr(str + 20, m.codec)
<< std::left << std::setw(sizeWidth) << format(m.gridSize)
<< std::left << std::setw(fileWidth) << format(m.fileSize)
<< std::left << std::setw(voxelSizeWidth) << Vec3dToStr(m.voxelSize);
}
std::cout << std::left << std::setw(voxelsWidth) << m.voxelCount
<< std::left << std::setw(resWidth) << resToStr(m.indexBBox);
if (mode == Long) {
std::cout << std::left << std::setw(configWidth) << nodesToStr(m.nodeCount)
<< std::left << std::setw(tileWidth) << nodesToStr(m.tileCount)
<< std::left << std::setw(ibboxWidth) << ibboxToStr(m.indexBBox)
<< std::left << std::setw(wbboxWidth) << wbboxToStr(m.worldBBox);
}
std::cout << std::endl;
}
}
if (verbose) {
size_t w = 0;
switch (mode) {
case Mode::Short:
width(w, "\"Name\":");
width(w, "\"Type\":");
width(w, "\"# Voxels\":");
width(w, "\"Resolution\":");
std::cout << std::left << std::setw(w) << "\n\"Name\":" << "name of a grid. Note that it is optional and hence might be empty."
<< std::left << std::setw(w) << "\n\"Type\":" << "static type of the values in a grid, e.g. float, vec3f etc."
<< std::left << std::setw(w) << "\n\"# Voxels\":" << "total number of active values in a grid."
<< std::left << std::setw(w) << "\n\"Resolution\":" << "Efficient resolution of all the active values in a grid!\n";
break;
case Mode::Default:
width(w, "\"Name\":");
width(w, "\"Type\":");
width(w, "\"Class\":");
width(w, "\"Version\":");
width(w, "\"Codec\":");
width(w, "\"Size\":");
width(w, "\"File\":");
width(w, "\"Scale\":");
width(w, "\"# Voxels\":");
width(w, "\"Resolution\":");
std::cout << std::left << std::setw(w) << "\n\"Name\":" << "name of a grid. Note that it is optional and hence might be empty."
<< std::left << std::setw(w) << "\n\"Type\":" << "static type of the values in a grid, e.g. float, vec3f etc."
<< std::left << std::setw(w) << "\n\"Class\":" << "class of the grid, e.g. FOG for Fog volume, LS for level set, etc."
<< std::left << std::setw(w) << "\n\"Version\":" << "major.minor.patch version numbers of the grid."
<< std::left << std::setw(w) << "\n\"Codec\":" << "codec of the optional compression applied to the out-of-core grid, i.e. on disk."
<< std::left << std::setw(w) << "\n\"Size\":" << "In-core memory footprint of the grid, i.e. in ram."
<< std::left << std::setw(w) << "\n\"File\":" << "Out-of-core memory footprint of the grid, i.e. on disk."
<< std::left << std::setw(w) << "\n\"Scale\":" << "Scale of the grid, i.e. the size of a voxel in world units."
<< std::left << std::setw(w) << "\n\"# Voxels\":" << "total number of active values in a grid."
<< std::left << std::setw(w) << "\n\"Resolution\":" << "Efficient resolution of all the active values in a grid!\n";
break;
case Mode::Long:
width(w, "\"Name\":");
width(w, "\"Type\":");
width(w, "\"Class\":");
width(w, "\"Version\":");
width(w, "\"Codec\":");
width(w, "\"Size\":");
width(w, "\"File\":");
width(w, "\"Scale\":");
width(w, "\"# Voxels\":");
width(w, "\"Resolution\":");
width(w, "\"32^3->16^3->8^3\":");
width(w, "\"# Active tiles\":");
width(w, "\"Index Bounding Box\":");
width(w, "\"World Bounding Box\":");
std::cout << std::left << std::setw(w) << "\n\"Name\":" << "name of a grid. Note that it is optional and hence might be empty."
<< std::left << std::setw(w) << "\n\"Type\":" << "static type of the values in a grid, e.g. float, vec3f etc."
<< std::left << std::setw(w) << "\n\"Class\":" << "class of the grid, e.g. FOG for Fog volume, LS for level set, etc."
<< std::left << std::setw(w) << "\n\"Version\":" << "major.minor.patch version numbers of the grid."
<< std::left << std::setw(w) << "\n\"Codec\":" << "codec of the optional compression applied to the out-of-core grid, i.e. on disk."
<< std::left << std::setw(w) << "\n\"Size\":" << "In-core memory footprint of the grid, e.g. in RAM on the CPU."
<< std::left << std::setw(w) << "\n\"File\":" << "Out-of-core memory footprint of the grid, i.e. compressed on disk."
<< std::left << std::setw(w) << "\n\"Scale\":" << "Scale of the grid, i.e. the size of a voxel in world units."
<< std::left << std::setw(w) << "\n\"# Voxels\":" << "total number of active values in a grid. Note this includes both active tiles and voxels."
<< std::left << std::setw(w) << "\n\"Resolution\":" << "Efficient resolution of all the active values in a grid!"
<< std::left << std::setw(w) << "\n\"32^3->16^3->8^3\":" << "Number of nodes at each level of the tree structure from the root to leaf level."
<< std::left << std::setw(w) << "\n\"# Active tiles\":" << "Number of active tiles at each level of the tree structure from the root to leaf level."
<< std::left << std::setw(w) << "\n\"Index Bounding Box\":" << "coordinate bounding box of all the active values in a grid. Note that both min and max coordinates are inclusive!"
<< std::left << std::setw(w) << "\n\"World Bounding Box\":" << "world-space bounding box of all the active values in a grid. Note that min is inclusive and max is exclusive!\n";
break;
default:
throw std::runtime_error("Internal error in switch!");
break;
}
}
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
exitStatus = EXIT_FAILURE;
}
catch (...) {
std::cerr << "Exception of unexpected type caught" << std::endl;
exitStatus = EXIT_FAILURE;
}
return exitStatus;
}// main
-222
View File
@@ -1,222 +0,0 @@
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
from pathlib import Path
def open_file(file_path):
"""
Opens a file. If utf-8 decoding fails, try windows-1252.
Args:
file_path: Path of the file to open.
Returns:
The content of the file in an arbitrary format.
"""
try:
with open(file_path, "r", encoding="utf-8", errors="replace") as file:
return file.read()
except UnicodeDecodeError:
with open(file_path, "r", encoding="windows-1252", errors="replace") as file:
return file.read()
def write_file(file_path, content):
"""
Writes a file. If utf-8 decoding fails, try windows-1252.
Args:
file_path: Path of the file to open.
Returns:
None.
"""
try:
with open(file_path, "w", encoding="utf-8", errors="replace") as file:
file.write(content)
except UnicodeDecodeError:
with open(file_path, "w", encoding="windows-1252", errors="replace") as file:
file.write(content)
def update_files(dir_path):
"""
Updates the content of files ending in .h, .cuh, .cc, .cu, and .cpp
to call the appropriate API as we update NanoVDB from version 32.6 to
version 32.7. This includes changes in namespaces, function names, and
include directories.
Args:
Directory path: will include files in downstream directories.
Returns:
None. Writes the contents of the file.
"""
# List of file extensions to search for
file_extensions = [".h", ".cuh", ".cc", ".cu", ".cpp"]
nspace_dic = {
"math": [
"Ray",
"DDA<",
"HDDA",
"Vec3<",
"Vec4<",
"BBox<",
"ZeroCrossing",
"TreeMarcher",
"PointTreeMarcher",
"BoxStencil<",
"CurvatureStencil<",
"GradStencil<",
"WenoStencil<",
"AlignUp",
"Min",
"Max",
"Abs",
"Clamp",
"Sqrt",
"Sign",
"Maximum<",
"Delta<",
"RoundDown<",
"pi<",
"isApproxZero<",
"Round<",
"createSampler",
"SampleFromVoxels<",
],
"tools": [
"createNanoGrid",
"StatsMode",
"createLevelSetSphere",
"createFogVolumeSphere",
"createFogVolumeSphere createFogVolumeSphere",
"createFogVolumeTorus",
"createLevelSetBox",
"CreateNanoGrid",
"updateGridStats",
"evalChecksum",
"validateChecksum",
"checkGrid",
"Extrema",
],
"util": [
"is_floating_point",
"findLowestOn",
"findHighestOn",
"Range",
"streq",
"strcpy",
"strcat",
"empty(",
"Split",
"invoke",
"forEach",
"reduce",
"prefixSum",
"is_same",
"is_specialization",
"PtrAdd",
"PtrDiff",
],
}
rename_dic = {
# list from func4 in updateFiles.sh
"nanovdb::build::": "nanovdb::tools::build::",
"nanovdb::BBoxR": "nanovdb::Vec3dBBox",
"nanovdb::BBox<nanovdb::Vec3d>": "nanovdb::Vec3dBbox",
# scope and rename, i.e. list from func2 in updateFiles.sh
"nanovdb::cudaCreateNodeManager": "nanovdb::cuda::createNodeManager",
"nanovdb::cudaVoxelsToGrid": "nanovdb::cuda::voxelsToGrid",
"nanovdb::cudaPointsToGrid": "nanovdb::cuda::pointsToGrid",
"nanovdb::DitherLUT": "nanovdb::math::DitherLUT",
"nanovdb::PackedRGBA8": "nanovdb::math::Rgba8",
"nanovdb::Rgba8": "nanovdb::math::Rgba8",
"nanovdb::CpuTimer": "nanovdb::util::Timer",
"nanovdb::GpuTimer": "nanovdb::util::cuda::Timer",
"nanovdb::CountOn": "nanovdb::util::countOn",
}
movdir_dic = {
# list comes from func3 calls on updateFiles.sh
"util/GridHandle.h": "GridHandle.h",
"util/BuildGrid.h": "tools/GridBuilder.h",
"util/GridBuilder.h": "tools/GridBuilder.h",
"util/IO.h": "io/IO.h",
"util/CSampleFromVoxels.h": "math/CSampleFromVoxels.h",
"util/DitherLUT.h": "math/DitherLUT.h",
"util/HDDA.h": "math/HDDA.h",
"util/Ray.h": "math/Ray.h",
"util/SampleFromVoxels.h": "math/SampleFromVoxels.h",
"util/Stencils.h": "nanovdb/math/Stencils.h",
"util/CreateNanoGrid.h": "tools/CreateNanoGrid.h",
"util/Primitives.h": "tools/CreatePrimitives.h",
"util/GridChecksum.h": "tools/GridChecksum.h",
"util/GridStats.h": "tools/GridStats.h",
"util/GridChecksum.h": "tools/GridChecksum.h",
"util/GridValidator.h": "tools/GridValidator.h",
"util/NanoToOpenVDB.h": "tools/NanoToOpenVDB.h",
"util/cuda/CudaGridChecksum.cuh": "tools/cuda/CudaGridChecksum.cuh",
"util/cuda/CudaGridStats.cuh": "tools/cuda/CudaGridStats.cuh",
"util/cuda/CudaGridValidator.cuh": "tools/cuda/CudaGridValidator.cuh",
"util/cuda/CudaIndexToGrid.cuh": "tools/cuda/CudaIndexToGrid.cuh",
"util/cuda/CudaPointsToGrid.cuh": "tools/cuda/PointsToGrid.cuh",
"util/cuda/CudaSignedFloodFill.cuh": "tools/cuda/CudaSignedFloodFill.cuh",
"util/cuda/CudaDeviceBuffer.h": "cuda/DeviceBuffer.h",
"util/cuda/CudaGridHandle.cuh": "cuda/GridHandle.cuh",
"util/cuda/CudaUtils.h": "util/cuda/Util.h",
"util/cuda/GpuTimer.h": "util/cuda/Timer.h",
}
# Iterate over files in the directory and its subdirectories
for root, dirs, files in os.walk(dir_path):
for file in files:
if any(file.endswith(ext) for ext in file_extensions):
file_path = os.path.join(root, file)
print(f"Processing file: {file_path}")
content = open_file(file_path)
# Correspond to func1 $file in updateFiles.sh
for key, vals in nspace_dic.items():
for val in vals:
old_word = "nanovdb::" + val
new_word = "nanovdb::" + key + "::" + val
content = content.replace(old_word, new_word)
# Correspond to func4 and func2 in updateFiles.sh
for key, val in rename_dic.items():
content = content.replace(key, val)
# Correspond to func3 in updateFiles.sh
for key, val in movdir_dic.items():
old_path = "<nanovdb/" + key + ">"
new_path = "<nanovdb/" + val + ">"
content = content.replace(old_path, new_path)
write_file(file_path, content)
# Example use:
# To update all the files using NanoVDB in the current directory (and directories downstream):
# python ./nanovdb/nanovdb/cmd/updateFiles.py
# To update all the files using NanoVDB in a directory called foo (and directories downstream):
# python ./nanovdb/nanovdb/cmd/updateFiles.py -d /path/to/foo
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Synthetic Data Generation for USD")
parser.add_argument(
"-d",
"--directory",
type=str,
default=None,
help="Path to directory containing .h, .cc, and .cu files using NanoVDB.",
)
args = parser.parse_args()
dir_path = os.getcwd() if args.directory is None else Path(args.directory).resolve()
update_files(dir_path)
-101
View File
@@ -1,101 +0,0 @@
#!/bin/bash
# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#Usage process all files in this directory or optionally specify a target directory
# Define directory in which to find files
dir="."
if [ "$1" ]; then
dir="$1"
fi
# Check if dir is not a directory
if [ ! -d "$dir" ]; then
echo -e "\nUsage: '$0 <directory>'\n"
exit 1
fi
# E.g.: func1 $file "math" "Coord" "Vec3" "Vec4"
func1 () {
for ((i=3; i<=$#; i++)); do
arg="s/nanovdb::${!i}/nanovdb::$2::${!i}/g"
#echo "sed -i $arg $1"
sed -i $arg $1
done
}
# E.G.: func2 file namespace old new : nanovdb::old -> nanovdb::namespace::new in file
func2 () {
arg="s/nanovdb::$3/nanovdb::$2::$4/g"
#echo "sed -i $arg $1"
sed -i $arg $1
}
# E.G.: func3 file path1/old.h path2/new.h <nanovdb/path1/old.h> -> <nanovdb/path2/new.h> in file
func3 () {
arg="s;<nanovdb/$2>;<nanovdb/$3>;g"
#echo "sed -i $arg $1"
sed -i $arg $1
}
# E.g.: func4 file old new new -> old
func4 () {
arg="s;$2;$3;g"
#echo "sed -i $arg $1"
sed -i $arg $1
}
# Loop through files in the target directory
for file in $(find "$dir" -name '*.h' -or -name '*.cuh' -or -name '*.cc' -or -name '*.cu' -or -name '*.cpp'); do
if [ -f "$file" ]; then
echo "Processing file: $file"
func1 $file math Ray "DDA<" HDDA "Vec3<" "Vec4<" "BBox<" ZeroCrossing TreeMarcher PointTreeMarcher\
"BoxStencil<" "CurvatureStencil<" "GradStencil<" "WenoStencil<" AlignUp Min Max Abs Clamp\
Sqrt Sign "Maximum<" "Delta<" "RoundDown<" "pi<" "isApproxZero<" "Round<" createSampler "SampleFromVoxels<"
func1 $file tools createNanoGrid StatsMode createLevelSetSphere\
createFogVolumeSphere createFogVolumeSphere createFogVolumeSphere\
createFogVolumeTorus createLevelSetBox CreateNanoGrid updateGridStats\
evalChecksum validateChecksum checkGrid Extrema
func1 $file util is_floating_point findLowestOn findHighestOn Range streq strcpy strcat "empty("\
Split invoke forEach reduce prefixSum is_same is_specialization PtrAdd PtrDiff
func4 $file "nanovdb::build::" "nanovdb::tools::build::"
func4 $file "nanovdb::BBoxR" "nanovdb::Vec3dBBox"
func4 $file "nanovdb::BBox<nanovdb::Vec3d>" "nanovdb::Vec3dBbox"
func2 $file cuda cudaCreateNodeManager createNodeManager
func2 $file cuda cudaVoxelsToGrid voxelsToGrid
func2 $file cuda cudaPointsToGrid pointsToGrid
func2 $file math DitherLUT DitherLUT
func2 $file math PackedRGBA8 Rgba8
func2 $file math Rgba8 Rgba8
func2 $file util CpuTimer Timer
func2 $file util GpuTimer "cuda::Timer"
func2 $file util CountOn countOn
func3 $file "util/GridHandle.h" "GridHandle.h"
func3 $file "util/BuildGrid.h" "tools/GridBuilder.h"
func3 $file "util/GridBuilder.h" "tools/GridBuilder.h"
func3 $file "util/IO.h" "io/IO.h"
func3 $file "util/CSampleFromVoxels.h" "math/CSampleFromVoxels.h"
func3 $file "util/DitherLUT.h" "math/DitherLUT.h"
func3 $file "util/HDDA.h" "math/HDDA.h"
func3 $file "util/Ray.h" "math/Ray.h"
func3 $file "util/SampleFromVoxels.h" "math/SampleFromVoxels.h"
func3 $file "util/Stencils.h" "nanovdb/math/Stencils.h"
func3 $file "util/CreateNanoGrid.h" "tools/CreateNanoGrid.h"
func3 $file "util/Primitives.h" "tools/CreatePrimitives.h"
func3 $file "util/GridChecksum.h" "tools/GridChecksum.h"
func3 $file "util/GridStats.h" "tools/GridStats.h"
func3 $file "util/GridChecksum.h" "tools/GridChecksum.h"
func3 $file "util/GridValidator.h" "tools/GridValidator.h"
func3 $file "util/NanoToOpenVDB.h" "tools/NanoToOpenVDB.h"
func3 $file "util/cuda/CudaGridChecksum.cuh" "tools/cuda/CudaGridChecksum.cuh"
func3 $file "util/cuda/CudaGridStats.cuh" "tools/cuda/CudaGridStats.cuh"
func3 $file "util/cuda/CudaGridValidator.cuh" "tools/cuda/CudaGridValidator.cuh"
func3 $file "util/cuda/CudaIndexToGrid.cuh" "tools/cuda/CudaIndexToGrid.cuh"
func3 $file "util/cuda/CudaPointsToGrid.cuh" "tools/cuda/PointsToGrid.cuh"
func3 $file "util/cuda/CudaSignedFloodFill.cuh" "tools/cuda/CudaSignedFloodFill.cuh"
func3 $file "util/cuda/CudaDeviceBuffer.h" "cuda/DeviceBuffer.h"
func3 $file "util/cuda/CudaGridHandle.cuh" "cuda/GridHandle.cuh"
func3 $file "util/cuda/CudaUtils.h" "util/cuda/Util.h"
func3 $file "util/cuda/GpuTimer.h" "util/cuda/Timer.h"
fi
done
@@ -1,115 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb_validate.cc
\author Ken Museth
\date October 13, 2020
\brief Command-line tool that validates Grids in nanovdb files
*/
#include <nanovdb/io/IO.h> // this is required to read (and write) NanoVDB files on the host
#include <nanovdb/tools/GridValidator.h>
#include <iomanip>
#include <sstream>
void usage [[noreturn]] (const std::string& progName, int exitStatus = EXIT_FAILURE)
{
std::cerr << "\nUsage: " << progName << " [options] *.nvdb\n"
<< "Which: Validates grids in one or more NanoVDB files\n\n"
<< "Options:\n"
<< "-g,--grid name\tOnly validate grids matching the specified string name\n"
<< "-h,--help\tPrints this message\n"
<< "-p,--partial\tPerform partial (i.e. fast) validation tests\n"
<< "-v,--verbose\tPrint verbose information information useful for debugging\n"
<< "--version\tPrint version information to the terminal\n";
exit(exitStatus);
}
void version [[noreturn]] (const char* progName, int exitStatus = EXIT_SUCCESS)
{
char str[8];
nanovdb::toStr(str, nanovdb::Version());
printf("\n%s was build against NanoVDB version %s\n", progName, str);
exit(exitStatus);
}
int main(int argc, char* argv[])
{
int exitStatus = EXIT_SUCCESS;
bool verbose = false;
nanovdb::CheckMode mode = nanovdb::CheckMode::Full;
std::string gridName;
std::vector<std::string> fileNames;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg[0] == '-') {
if (arg == "-h" || arg == "--help") {
usage(argv[0], EXIT_SUCCESS);
} else if (arg == "--version") {
version(argv[0]);
} else if (arg == "-v" || arg == "--verbose") {
verbose = true;
} else if (arg == "-p" || arg == "--partial") {
mode = nanovdb::CheckMode::Partial;
} else if (arg == "-g" || arg == "--grid") {
if (i + 1 == argc) {
std::cerr << "\nExpected a grid name to follow the -g,--grid option\n";
usage(argv[0]);
} else {
gridName.assign(argv[++i]);
}
} else {
std::cerr << "\nIllegal option: \"" << arg << "\"\n";
usage(argv[0]);
}
} else if (!arg.empty()) {
fileNames.push_back(arg);
}
}
if (fileNames.size() == 0) {
std::cerr << "\nExpected at least one input NanoVDB file\n";
usage(argv[0]);
}
const auto nameKey = nanovdb::io::stringHash(gridName);
try {
for (auto& file : fileNames) {
auto list = nanovdb::io::readGridMetaData(file);
if (!gridName.empty()) {
std::vector<nanovdb::io::FileGridMetaData> tmp;
for (auto& m : list) {
if (nameKey == m.nameKey && gridName == m.gridName) tmp.emplace_back(m);
}
list = std::move(tmp);
}
if (list.size() == 0) continue;
if (verbose) std::cout << "\nThe file \"" << file << "\" contains the following matching " << list.size() << " grid(s):\n";
for (auto& m : list) {
auto handle = nanovdb::io::readGrid(file, m.gridName);
const bool test = nanovdb::tools::validateGrids(handle, mode, verbose);
if (verbose) {
std::cout << "Grid named \"" << m.gridName << "\": " << (test ? "passed" : "failed") << std::endl;
} else if (!test) {
std::cout << "Grid named \"" << m.gridName << "\": failed" << std::endl;
}
}
}
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
exitStatus = EXIT_FAILURE;
}
catch (...) {
std::cerr << "Exception oof unexpected type caught" << std::endl;
exitStatus = EXIT_FAILURE;
}
return exitStatus;
}
-376
View File
@@ -1,376 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file DeviceBuffer.h
\author Ken Museth
\date January 8, 2020
\brief DeviceBuffer has one pinned host buffer and multiple device CUDA buffers
\note This file has no device-only kernel functions,
which explains why it's a .h and not .cuh file.
*/
#ifndef NANOVDB_CUDA_DEVICEBUFFER_H_HAS_BEEN_INCLUDED
#define NANOVDB_CUDA_DEVICEBUFFER_H_HAS_BEEN_INCLUDED
#include <cuda.h>
#include <memory>// for std::shared_ptr
#include <nanovdb/HostBuffer.h>// for BufferTraits
#include <nanovdb/util/cuda/Util.h>// for cudaMalloc/cudaMallocManaged/cudaFree
namespace nanovdb {// ================================================================
namespace cuda {// ===================================================================
// ----------------------------> DeviceBuffer <--------------------------------------
/// @brief Simple memory buffer using un-managed pinned host memory when compiled with NVCC.
/// Obviously this class is making explicit used of CUDA so replace it with your own memory
/// allocator if you are not using CUDA.
/// @note While CUDA's pinned host memory allows for asynchronous memory copy between host and device
/// it is significantly slower then cached (un-pinned) memory on the host.
class DeviceBuffer
{
uint64_t mSize; // total number of bytes managed by this buffer (assumed to be identical for host and device)
void *mCpuData, **mGpuData; // raw pointers to the host and device buffers
int mDeviceCount, mManaged;// if mManaged is non-zero this class is responsible for allocating and freeing memory buffers. Otherwise this is assumed to be handled externally
/// @brief Initialize buffer
/// @param size byte size of buffer to be initialized
/// @param host If true buffer is initialized only on the host/CPU, else on the device/GPU
/// @note All existing buffers are first cleared
/// @warning size is expected to be non-zero. Use clear() clear buffer!
void init(uint64_t size, int device, cudaStream_t stream);
public:
using PtrT = std::shared_ptr<DeviceBuffer>;
/// @brief Default constructor of an empty buffer
DeviceBuffer() : mSize(0), mCpuData(nullptr), mGpuData(nullptr), mDeviceCount(0), mManaged(0){}
/// @brief Constructor with a specified device and size
/// @param size byte size of buffer to be initialized
/// @param device id of the device on which to initialize the buffer
/// @param stream cuda stream
DeviceBuffer(uint64_t size, int device = cudaCpuDeviceId, cudaStream_t stream = 0) : DeviceBuffer()
{
this->init(size, device, stream);
}
/// @brief Constructor
/// @param size byte size of buffer to be initialized
/// @param host If true buffer is initialized only on the host/CPU, else on the current device/GPU
/// @param stream optional stream argument (defaults to stream NULL)
DeviceBuffer(uint64_t size, bool host, void* stream) : DeviceBuffer()
{
int device = cudaCpuDeviceId;
if (!host) cudaCheck(cudaGetDevice(&device));
this->init(size, device, reinterpret_cast<cudaStream_t>(stream));
}
/// @brief Constructor for externally managed host and device buffers
/// @param size byte size of the two external buffers
/// @param cpuData host buffer, assumed to NOT be NULL
/// @param gpuData device buffer, assumed to NOT be NULL;
/// @note The device buffer, @c gpuData, will be associated
/// with the current device ID given by cudaGetDevice
DeviceBuffer(uint64_t size, void* cpuData, void* gpuData)
: mSize(size)
, mCpuData(cpuData)
, mManaged(0)
{
cudaCheck(cudaGetDeviceCount(&mDeviceCount));
mGpuData = new void*[mDeviceCount]();// NULL initialization
NANOVDB_ASSERT(cpuData);
NANOVDB_ASSERT(gpuData);
int device = 0;
cudaCheck(cudaGetDevice(&device));
mGpuData[device] = gpuData;
}
/// @brief Constructor for externally managed host and multiple device buffers
/// @param size byte size of the two external buffers
/// @param cpuData host buffer, assumed to NOT be NULL
/// @param list list of device IDs and external device buffers, all assumed to not be NULL
DeviceBuffer(uint64_t size, void* cpuData, std::initializer_list<std::pair<int,void*>> list)
: mSize(size)
, mCpuData(cpuData)
, mManaged(0)
{
NANOVDB_ASSERT(cpuData);
cudaCheck(cudaGetDeviceCount(&mDeviceCount));
mGpuData = new void*[mDeviceCount]();// NULL initialization
for (auto &p : list) {
NANOVDB_ASSERT(p.first>=0 && p.first<mDeviceCount);
NANOVDB_ASSERT(p.second);
mGpuData[p.first] = p.second;
}
}
/// @brief Disallow copy-construction
DeviceBuffer(const DeviceBuffer&) = delete;
/// @brief Move copy-constructor
DeviceBuffer(DeviceBuffer&& other) noexcept
: mSize(other.mSize)
, mCpuData(other.mCpuData)
, mGpuData(other.mGpuData)
, mDeviceCount(other.mDeviceCount)
, mManaged(other.mManaged)
{
other.mCpuData = other.mGpuData = nullptr;
other.mSize = other.mDeviceCount = other.mManaged = 0;
}
/// @brief Destructor frees memory on both the host and device
~DeviceBuffer() { this->clear(); };
/// @brief Static factory method that return an instance of this buffer
/// @param size byte size of buffer to be initialized
/// @param dummy this argument is currently ignored but required to match the API of the HostBuffer
/// @param host If true buffer is initialized only on the host/CPU, else only on the device/GPU
/// @param stream optional stream argument (defaults to stream NULL)
/// @return An instance of this class using move semantics
static DeviceBuffer create(uint64_t size, const DeviceBuffer* dummy, bool host, void* stream){return DeviceBuffer(size, host, stream);}
static DeviceBuffer create(uint64_t size, const DeviceBuffer* dummy = nullptr, int device = cudaCpuDeviceId, cudaStream_t stream = 0){return DeviceBuffer(size, device, stream);}
/// @brief Static factory method that returns an instance of this buffer that wraps externally managed memory
/// @param size byte size of buffer specified by external memory
/// @param cpuData pointer to externally managed host memory
/// @param gpuData pointer to externally managed device memory
/// @return An instance of this class using move semantics
static DeviceBuffer create(uint64_t size, void* cpuData, void* gpuData) {return DeviceBuffer(size, cpuData, gpuData);}
/// @brief Static factory method that returns an instance of this buffer that wraps externally managed host and device memory
/// @param size byte size of buffer to be initialized
/// @param cpuData pointer to externally managed host memory
/// @param list list of device IDs and device memory pointers
static DeviceBuffer create(uint64_t size, void* cpuData, std::initializer_list<std::pair<int,void*>> list) {return DeviceBuffer(size, cpuData, list);}
///////////////////////////////////////////////////////////////////////
//@{
/// @brief Factory methods that create a shared pointer to an DeviceBuffer instance
static PtrT createPtr(uint64_t size, const DeviceBuffer* = nullptr, int device = cudaCpuDeviceId, cudaStream_t stream = 0) {return std::make_shared<DeviceBuffer>(size, device, stream);}
static PtrT createPtr(uint64_t size, void* cpuData, void* gpuData) {return std::make_shared<DeviceBuffer>(size, cpuData, gpuData);}
static PtrT createPtr(uint64_t size, void* cpuData, std::initializer_list<std::pair<int,void*>> list) {return std::make_shared<DeviceBuffer>(size, cpuData, list);}
///@}
///////////////////////////////////////////////////////////////////////
/// @brief Disallow copy assignment operation
DeviceBuffer& operator=(const DeviceBuffer&) = delete;
/// @brief Move copy assignment operation
DeviceBuffer& operator=(DeviceBuffer&& other) noexcept
{
mSize = other.mSize;
mCpuData = other.mCpuData;
delete [] mGpuData;
mGpuData = other.mGpuData;
mDeviceCount = other.mDeviceCount;
mManaged = other.mManaged;
other.mCpuData = other.mGpuData = nullptr;
other.mSize = other.mDeviceCount = other.mManaged = 0;
return *this;
}
///////////////////////////////////////////////////////////////////////
/// @brief Retuns a raw void pointer to the host/CPU buffer managed by this allocator.
/// @warning Note that the pointer can be NULL!
void* data() const { return mCpuData; }
/// @brief Returns an offset pointer of a specific type from the allocated host memory
/// @tparam T Type of the pointer returned
/// @param count Numbers of elements of @c parameter type T to skip
/// @warning assumes that this instance is not empty!
template <typename T>
T* data(ptrdiff_t count = 0, int device = cudaCpuDeviceId) const
{
NANOVDB_ASSERT(device >= cudaCpuDeviceId && device < mDeviceCount);
void *ptr = device == cudaCpuDeviceId ? mCpuData : mGpuData[device];
return ptr ? reinterpret_cast<T*>(ptr) + count : nullptr;
}
/// @brief Returns a byte offset void pointer from the allocated host memory
/// @param byteOffset offset of return pointer in units of bytes
/// @warning assumes that this instance is not empty!
void* data(ptrdiff_t byteOffset, int device = cudaCpuDeviceId) const
{
NANOVDB_ASSERT(device >= cudaCpuDeviceId && device < mDeviceCount);
void *ptr = device == cudaCpuDeviceId ? mCpuData : mGpuData[device];
return ptr ? reinterpret_cast<char*>(ptr) + byteOffset : nullptr;
}
///////////////////////////////////////////////////////////////////////
/// @brief Retuns a raw pointer to the specified device/GPU buffer managed by this allocator.
/// @warning Note that the pointer can be NULL!
void* deviceData(int device) const {
NANOVDB_ASSERT(device >= 0 && device < mDeviceCount);
return mGpuData[device];
}
/// @brief Retuns a raw pointer to the current device/GPU buffer managed by this allocator.
/// @warning Note that the pointer can be NULL!
void* deviceData() const {
int device = cudaCpuDeviceId;
cudaCheck(cudaGetDevice(&device));
return this->deviceData(device);
}
///////////////////////////////////////////////////////////////////////
/// @brief Uploads buffer on the host to a specific device. If it doesn't exist it's created first.
/// @param device Device ID that the data is copied to
/// @param stream cuda stream
/// @param sync if false the memory copy is asynchronous.
/// @warning Assumes that the host buffer already exists!
/// @note determine the current device with cudaGetDevice
void deviceUpload(int device = 0, cudaStream_t stream = 0, bool sync = true);
void deviceUpload(int device, void* stream, bool sync){this->deviceUpload(device, cudaStream_t(stream), sync);}
/// @brief Upload buffer from the host to ALL the existing devices, i.e. CPU -> GPU.
/// If no device buffers exist one is created for the current device (typically 0)
/// and subsequently populated with the host data.
/// @param stream CUDA stream.
/// @param sync if false the memory copy is asynchronous.
/// @warning Assumes that the host buffer already exists!
void deviceUpload(cudaStream_t stream, bool sync);
void deviceUpload(void* stream, bool sync) {this->deviceUpload(cudaStream_t(stream), sync);}
///////////////////////////////////////////////////////////////////////
/// @brief Download data from a specified device to the host. If the host buffer des not exist it will first be allocated
/// @param device device ID to download source data from
/// @param stream cuda stream
/// @param sync if false the memory copy is asynchronous.
/// @warning Assumes that the specifed device buffer already exists!
void deviceDownload(int device = 0, cudaStream_t stream = 0, bool sync = true);
void deviceDownload(int device, void* stream , bool sync) {this->deviceDownload(device, cudaStream_t(stream), sync);}
/// @brief Download the buffer from the current device to the host, i.e. GPU -> CPU.
/// If the host buffer des not exist it will first be allocated
/// @param stream CUDA stream
/// @param sync if false the memory copy is asynchronous
/// @note If the host/CPU buffer does not exist it is first allocated
/// @warning Assumes that the device/GPU buffer already exists
void deviceDownload(void* stream, bool sync);
///////////////////////////////////////////////////////////////////////
/// @brief Returns the size in bytes of the raw memory buffer managed by this allocator.
uint64_t size() const { return mSize; }
uint64_t capacity() const {return this->size();}
/// @brief Returns the number of buffers that are not NULL
int bufferCount() const {
int count = mCpuData ? 1 : 0;
for (int i=0; i<mDeviceCount; ++i) if (mGpuData[i]) ++count;
return count;
}
int deviceCount() const {return mDeviceCount;}
//@{
/// @brief Returns true if this allocator is empty, i.e. has no allocated memory
bool empty() const { return mSize == 0; }
bool isEmpty() const { return this->empty(); }
//@}
/// @brief De-allocate all memory managed by this allocator and set all pointers to NULL
void clear(cudaStream_t stream = 0);
void clear(void* stream){this->clear(cudaStream_t(stream));}
}; // DeviceBuffer class
// --------------------------> Implementations below <------------------------------------
inline void DeviceBuffer::init(uint64_t size, int device, cudaStream_t stream)
{
if (size==0) return;
cudaCheck(cudaGetDeviceCount(&mDeviceCount));
mGpuData = new void*[mDeviceCount]();// NULL initialization
NANOVDB_ASSERT(device >= cudaCpuDeviceId && device < mDeviceCount);
if (device == cudaCpuDeviceId) {
cudaCheck(cudaMallocHost((void**)&mCpuData, size)); // un-managed pinned memory on the host (can be slow to access!). Always 32B aligned
checkPtr(mCpuData, "cuda::DeviceBuffer::init: failed to allocate host buffer");
} else {
cudaCheck(cudaMallocAsync(mGpuData+device, size, stream)); // un-managed memory on the device, always 32B aligned!
checkPtr(mGpuData[device], "cuda::DeviceBuffer::init: failed to allocate device buffer");
}
mSize = size;
mManaged = 1;// i.e. this instance is responsible for allocating and delete memory
} // DeviceBuffer::init
inline void DeviceBuffer::deviceUpload(int device, cudaStream_t stream, bool sync)
{
NANOVDB_ASSERT(device >= 0 && device < mDeviceCount);// should be device and not the host
checkPtr(mCpuData, "uninitialized cpu source data");
if (mGpuData[device] == nullptr) {
if (mManaged==0) throw std::runtime_error("DeviceBuffer::deviceUpload called on externally managed memory that wasn\'t allocated.");
cudaCheck(cudaMallocAsync(mGpuData+device, mSize, stream)); // un-managed memory on the device, always 32B aligned!
}
checkPtr(mGpuData[device], "uninitialized gpu destination data");
cudaCheck(cudaMemcpyAsync(mGpuData[device], mCpuData, mSize, cudaMemcpyHostToDevice, stream));
if (sync) cudaCheck(cudaStreamSynchronize(stream));
} // DeviceBuffer::deviceUpload
inline void DeviceBuffer::deviceUpload(cudaStream_t stream, bool sync)
{
int device = 0;
cudaGetDevice(&device);
this->deviceUpload(device, stream, sync);
} // DeviceBuffer::deviceUpload
inline void DeviceBuffer::deviceDownload(int device, cudaStream_t stream, bool sync)
{
NANOVDB_ASSERT(device >= 0 && device < mDeviceCount);
checkPtr(mGpuData[device], "uninitialized gpu source data");// no source data on the specified device
if (mCpuData == nullptr) {
if (mManaged==0) throw std::runtime_error("DeviceBuffer::deviceDownload called on uninitialized cpu destination memory that is externally managed.");
cudaCheck(cudaMallocHost((void**)&mCpuData, mSize)); // un-managed pinned memory on the host (can be slow to access!). Always 32B aligned
}
checkPtr(mCpuData, "uninitialized cpu destination data");
cudaCheck(cudaMemcpyAsync(mCpuData, mGpuData[device], mSize, cudaMemcpyDeviceToHost, stream));
if (sync) cudaCheck(cudaStreamSynchronize(stream));
} // DeviceBuffer::deviceDownload
inline void DeviceBuffer::deviceDownload(void* stream, bool sync)
{
int device = 0;
cudaCheck(cudaGetDevice(&device));
this->deviceDownload(device, cudaStream_t(stream), sync);
} // DeviceBuffer::deviceDownload
inline void DeviceBuffer::clear(cudaStream_t stream)
{
if (mManaged!=0) {// free all the managed data buffers
cudaCheck(cudaFreeHost(mCpuData));
for (int i=0; i<mDeviceCount; ++i) cudaCheck(cudaFreeAsync(mGpuData[i], stream));
}
delete [] mGpuData;
mCpuData = mGpuData = nullptr;
mSize = mDeviceCount = mManaged = 0;
} // DeviceBuffer::clear
}// namespace cuda
using CudaDeviceBuffer [[deprecated("Use nanovdb::cuda::DeviceBuffer instead")]] = cuda::DeviceBuffer;
template<>
struct BufferTraits<cuda::DeviceBuffer>
{
static constexpr bool hasDeviceDual = true;
};
}// namespace nanovdb
#endif // end of NANOVDB_CUDA_DEVICEBUFFER_H_HAS_BEEN_INCLUDED
-120
View File
@@ -1,120 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file DeviceStreamMap.h
\author Ken Museth
\date October 15, 2024
\brief nanovdb::cuda::DeviceStreamMap maps device IDs to CUDA streams,
which is useful for multi-GPU applications.
*/
#ifndef NANOVDB_CUDA_DEVICESTREAMMAP_H_HAS_BEEN_INCLUDED
#define NANOVDB_CUDA_DEVICESTREAMMAP_H_HAS_BEEN_INCLUDED
#include <cuda.h>
#include <map>
#include <vector>
#include <nanovdb/util/cuda/Util.h>// for cudaCheck, deviceCount etc
namespace nanovdb {// ================================================================
namespace cuda {// ===================================================================
/// @brief map from a device ID to an associated cuda stream. Useful for multi-GPU applications.
class DeviceStreamMap : public std::map<int, cudaStream_t>
{
using FuncT = CUresult(size_t*, const CUmemAllocationProp*, CUmemAllocationGranularity_flags);
FuncT *mFunctPtr;
public:
enum DeviceType { Any = 0, PeerToPeer = 1, Unified = 3 };
/// @brief Initiates a map between CUDA device IDs and corresponding streams that satisfy certain constraints.
/// All devices should be able to access memory on all the other devices!
/// @param t Type of device to include in map. Any means all available devices, PeerToPeer means only devices that
/// access all aother devices are included, and Unified means all devices support unified memory, concurrent access,
/// and can be access by all other devices.
/// @param exclude optional list of device IDs to exclude from the map
/// @param verbose 0 means quiet, 1 means print if a device is ignores and 2 means print is a device is included
DeviceStreamMap(DeviceType t = DeviceType::Unified, std::vector<int> exclude = {}, int verbose = 0);
/// @brief Destructor
~DeviceStreamMap();
/// @brief returns the minimum page size of all the devices in this map
size_t getMinPageSize() const;
/// @brief Print information about all the devices included in this map
void printDevInfo(std::FILE* file = stdout) const {for (auto &p : *this) util::cuda::printDevInfo(p.first, nullptr, file);}
/// @brief Returns the number of device associated with this map
int deviceCount() const {return this->size();}
};// DeviceStreamMap
DeviceStreamMap::DeviceStreamMap(DeviceType t, std::vector<int> exclude, int verbose)
{
std::initializer_list<cudaDeviceAttr> filter = {cudaDevAttrUnifiedAddressing, cudaDevAttrConcurrentManagedAccess};
const int devCount = util::cuda::deviceCount(), current = util::cuda::currentDevice();
for (int dev = 0; dev < devCount; ++dev) {
int check = 1;
for (auto it=exclude.begin(); check && it!=exclude.end(); ++it) if (dev == *it) check = 0;
for (auto it=filter.begin(); (t&2) && check && it!=filter.end(); ++it) cudaCheck(cudaDeviceGetAttribute( &check, *it, dev));
for (auto it= this->begin(); (t&1) && check && it!= this->end(); ++it) cudaCheck(cudaDeviceCanAccessPeer(&check, dev, it->first));
if (check) {
cudaCheck(cudaSetDevice(dev));
cudaStream_t stream;
cudaCheck(cudaStreamCreate(&stream));
if (verbose>1) util::cuda::printDevInfo(dev, "Using");
(*this)[dev] = stream;
} else if (verbose) util::cuda::printDevInfo(dev, "Ignoring");
}
cudaCheck(cudaSetDevice(current));// reset to the previous device
void* entryPoint = nullptr;
#if CUDART_VERSION >= 12000// queryResult argument was added in CUDA 12
cudaDriverEntryPointQueryResult queryResult;
cudaCheck(cudaGetDriverEntryPoint("cuMemGetAllocationGranularity", &entryPoint, cudaEnableDefault, &queryResult));
NANOVDB_ASSERT(queryResult == cudaDriverEntryPointSuccess);
#else
cudaCheck(cudaGetDriverEntryPoint("cuMemGetAllocationGranularity", &entryPoint, cudaEnableDefault));
#endif
mFunctPtr = reinterpret_cast<FuncT*>(entryPoint);
}// DeviceStreamMap::DeviceStreamMap
DeviceStreamMap::~DeviceStreamMap()
{
const int current = util::cuda::currentDevice();
for (auto& [device, stream] : *this) {
cudaCheck(cudaSetDevice(device));
cudaCheck(cudaStreamDestroy(stream));
}
cudaCheck(cudaSetDevice(current));// reset to the previous device
}
inline size_t DeviceStreamMap::getMinPageSize() const
{
NANOVDB_ASSERT(mFunctPtr);
CUmemAllocationProp prop = {};
prop.type = CU_MEM_ALLOCATION_TYPE_PINNED;
prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
size_t minGranularity = 0;
for (auto it = this->begin(); it!=this->end(); ++it) {
prop.location.id = it->first;
size_t granularity = 0;
(*mFunctPtr)(&granularity, &prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM);
if (minGranularity < granularity) minGranularity = granularity;
}
return minGranularity;
}// DeviceStreamMap::getMinPageSize
}// namespace cuda
}// namespace nanovdb
#endif // end of NANOVDB_CUDA_DEVICESTREAMMAP_H_HAS_BEEN_INCLUDED
-149
View File
@@ -1,149 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb/cuda/GridHandle.cuh
\author Ken Museth, Doyub Kim
\date August 3, 2023
\brief Contains cuda kernels for GridHandle
\warning The header file contains cuda device code so be sure
to only include it in .cu files (or other .cuh files)
*/
#ifndef NANOVDB_CUDA_GRIDHANDLE_CUH_HAS_BEEN_INCLUDED
#define NANOVDB_CUDA_GRIDHANDLE_CUH_HAS_BEEN_INCLUDED
#include <nanovdb/cuda/DeviceBuffer.h>// required for instantiation of move c-tor of GridHandle
#include <nanovdb/tools/cuda/GridChecksum.cuh>// for cuda::updateChecksum
#include <nanovdb/GridHandle.h>
namespace nanovdb {
namespace cuda {
namespace {// anonymous namespace
__global__ void cpyGridHandleMeta(const GridData *d_data, GridHandleMetaData *d_meta)
{
nanovdb::cpyGridHandleMeta(d_data, d_meta);
}
__global__ void updateGridCount(GridData *d_data, uint32_t gridIndex, uint32_t gridCount, bool *d_dirty)
{
NANOVDB_ASSERT(gridIndex < gridCount);
if (*d_dirty = d_data->mGridIndex != gridIndex || d_data->mGridCount != gridCount) {
d_data->mGridIndex = gridIndex;
d_data->mGridCount = gridCount;
if (d_data->mChecksum.isEmpty()) *d_dirty = false;// no need to update checksum if it didn't already exist
}
}
}// anonymous namespace
template<typename BufferT, template <class, class...> class VectorT = std::vector>
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, VectorT<GridHandle<BufferT>>>::type
splitGridHandles(const GridHandle<BufferT> &handle, const BufferT* other = nullptr, cudaStream_t stream = 0)
{
const void *ptr = handle.deviceData();
if (ptr == nullptr) return VectorT<GridHandle<BufferT>>();
VectorT<GridHandle<BufferT>> handles(handle.gridCount());
bool dirty, *d_dirty;// use this to check if the checksum needs to be recomputed
cudaCheck(util::cuda::mallocAsync((void**)&d_dirty, sizeof(bool), stream));
int device = 0;
cudaCheck(cudaGetDevice(&device));
for (uint32_t n=0; n<handle.gridCount(); ++n) {
auto buffer = BufferT::create(handle.gridSize(n), other, device, stream);
GridData *dst = reinterpret_cast<GridData*>(buffer.deviceData());
const GridData *src = reinterpret_cast<const GridData*>(ptr);
cudaCheck(cudaMemcpyAsync(dst, src, handle.gridSize(n), cudaMemcpyDeviceToDevice, stream));
updateGridCount<<<1, 1, 0, stream>>>(dst, 0u, 1u, d_dirty);
cudaCheckError();
cudaCheck(cudaMemcpyAsync(&dirty, d_dirty, sizeof(bool), cudaMemcpyDeviceToHost, stream));
if (dirty) tools::cuda::updateChecksum(dst, CheckMode::Partial, stream);
handles[n] = nanovdb::GridHandle<BufferT>(std::move(buffer));
ptr = util::PtrAdd(ptr, handle.gridSize(n));
}
cudaCheck(util::cuda::freeAsync(d_dirty, stream));
return std::move(handles);
}// cuda::splitGridHandles
template<typename BufferT, template <class, class...> class VectorT>
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, GridHandle<BufferT>>::type
mergeGridHandles(const VectorT<GridHandle<BufferT>> &handles, const BufferT* other = nullptr, cudaStream_t stream = 0)
{
uint64_t size = 0u;
uint32_t counter = 0u, gridCount = 0u;
for (auto &h : handles) {
gridCount += h.gridCount();
for (uint32_t n=0; n<h.gridCount(); ++n) size += h.gridSize(n);
}
int device = 0;
cudaCheck(cudaGetDevice(&device));
auto buffer = BufferT::create(size, other, device, stream);
void *dst = buffer.deviceData();
bool dirty, *d_dirty;// use this to check if the checksum needs to be recomputed
cudaCheck(util::cuda::mallocAsync((void**)&d_dirty, sizeof(bool), stream));
for (auto &h : handles) {
const void *src = h.deviceData();
for (uint32_t n=0; n<h.gridCount(); ++n) {
cudaCheck(cudaMemcpyAsync(dst, src, h.gridSize(n), cudaMemcpyDeviceToDevice, stream));
GridData *data = reinterpret_cast<GridData*>(dst);
updateGridCount<<<1, 1, 0, stream>>>(data, counter++, gridCount, d_dirty);
cudaCheckError();
cudaCheck(cudaMemcpyAsync(&dirty, d_dirty, sizeof(bool), cudaMemcpyDeviceToHost, stream));
if (dirty) tools::cuda::updateChecksum(data, CheckMode::Partial, stream);
dst = util::PtrAdd(dst, h.gridSize(n));
src = util::PtrAdd(src, h.gridSize(n));
}
}
cudaCheck(util::cuda::freeAsync(d_dirty, stream));
return GridHandle<BufferT>(std::move(buffer));
}// cuda::mergeGridHandles
}// namespace cuda
template<typename BufferT, template <class, class...> class VectorT = std::vector>
[[deprecated("Use nanovdb::cuda::splitGridHandles instead")]]
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, VectorT<GridHandle<BufferT>>>::type
splitDeviceGrids(const GridHandle<BufferT> &handle, const BufferT* other = nullptr, cudaStream_t stream = 0)
{ return cuda::splitGridHandles(handle, other, stream); }
template<typename BufferT, template <class, class...> class VectorT>
[[deprecated("Use nanovdb::cuda::mergeGridHandles instead")]]
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, GridHandle<BufferT>>::type
mergeDeviceGrids(const VectorT<GridHandle<BufferT>> &handles, const BufferT* other = nullptr, cudaStream_t stream = 0)
{ return cuda::mergeGridHandles<BufferT, VectorT>(handles, other, stream); }
template<typename BufferT>
template<typename T, typename util::enable_if<BufferTraits<T>::hasDeviceDual, int>::type>
GridHandle<BufferT>::GridHandle(T&& buffer)
{
static_assert(util::is_same<T,BufferT>::value, "Expected U==BufferT");
mBuffer = std::move(buffer);
if (auto *data = reinterpret_cast<const GridData*>(mBuffer.data())) {
if (!data->isValid()) throw std::runtime_error("GridHandle was constructed with an invalid host buffer");
mMetaData.resize(data->mGridCount);
cpyGridHandleMeta(data, mMetaData.data());
} else {
if (auto *d_data = reinterpret_cast<const GridData*>(mBuffer.deviceData())) {
GridData tmp;
cudaCheck(cudaMemcpy(&tmp, d_data, sizeof(GridData), cudaMemcpyDeviceToHost));
if (!tmp.isValid()) throw std::runtime_error("GridHandle was constructed with an invalid device buffer");
GridHandleMetaData *d_metaData;
cudaMalloc((void**)&d_metaData, tmp.mGridCount*sizeof(GridHandleMetaData));
cuda::cpyGridHandleMeta<<<1,1>>>(d_data, d_metaData);
mMetaData.resize(tmp.mGridCount);
cudaCheck(cudaMemcpy(mMetaData.data(), d_metaData,tmp.mGridCount*sizeof(GridHandleMetaData), cudaMemcpyDeviceToHost));
cudaCheck(cudaFree(d_metaData));
}
}
}// GridHandle(T&& buffer)
// Dummy function that ensures instantiation of the move-constructor above when BufferT=cuda::DeviceBuffer
namespace {auto __dummy(){return GridHandle<cuda::DeviceBuffer>(std::move(cuda::DeviceBuffer()));}}
} // namespace nanovdb
#endif // NANOVDB_CUDA_GRIDHANDLE_CUH_HAS_BEEN_INCLUDED
-106
View File
@@ -1,106 +0,0 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
/*!
\file nanovdb/cuda/NodeManager.cuh
\author Ken Museth
\date October 3, 2023
\brief Contains cuda kernels for NodeManager
\warning The header file contains cuda device code so be sure
to only include it in .cu files (or other .cuh files)
*/
#ifndef NANOVDB_CUDA_NODE_MANAGER_CUH_HAS_BEEN_INCLUDED
#define NANOVDB_CUDA_NODE_MANAGER_CUH_HAS_BEEN_INCLUDED
#include <nanovdb/util/cuda/Util.h>// for cuda::lambdaKernel
#include <nanovdb/cuda/DeviceBuffer.h>
#include <nanovdb/NodeManager.h>
namespace nanovdb {
namespace cuda {
/// @brief Construct a NodeManager from a device grid pointer
///
/// @param d_grid device grid pointer whose nodes will be accessed sequentially
/// @param buffer buffer from which to allocate the output handle
/// @param stream cuda stream
/// @return Handle that contains a device NodeManager
template <typename BuildT, typename BufferT = DeviceBuffer>
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, NodeManagerHandle<BufferT>>::type
createNodeManager(const NanoGrid<BuildT> *d_grid,
const BufferT& pool = BufferT(),
cudaStream_t stream = 0)
{
int device = 0;
cudaCheck(cudaGetDevice(&device));
auto buffer = BufferT::create(sizeof(NodeManagerData), &pool, device, stream);
auto *d_data = (NodeManagerData*)buffer.deviceData();
size_t size = 0u, *d_size;
cudaCheck(util::cuda::mallocAsync((void**)&d_size, sizeof(size_t), stream));
util::cuda::lambdaKernel<<<1, 1, 0, stream>>>(1, [=] __device__(size_t) {
#ifdef NANOVDB_USE_NEW_MAGIC_NUMBERS
*d_data = NodeManagerData{NANOVDB_MAGIC_NODE, 0u, (void*)d_grid, {0u,0u,0u}};
#else
*d_data = NodeManagerData{NANOVDB_MAGIC_NUMB, 0u, (void*)d_grid, {0u,0u,0u}};
#endif
*d_size = sizeof(NodeManagerData);
auto &tree = d_grid->tree();
if (NodeManager<BuildT>::FIXED_SIZE && d_grid->isBreadthFirst()) {
d_data->mLinear = uint8_t(1u);
d_data->mOff[0] = util::PtrDiff(tree.template getFirstNode<0>(), d_grid);
d_data->mOff[1] = util::PtrDiff(tree.template getFirstNode<1>(), d_grid);
d_data->mOff[2] = util::PtrDiff(tree.template getFirstNode<2>(), d_grid);
} else {
*d_size += sizeof(uint64_t)*tree.totalNodeCount();
}
});
cudaCheckError();
cudaCheck(cudaMemcpyAsync(&size, d_size, sizeof(size_t), cudaMemcpyDeviceToHost, stream));
cudaCheck(util::cuda::freeAsync(d_size, stream));
if (size > sizeof(NodeManagerData)) {
auto tmp = BufferT::create(size, &pool, device, stream);// only allocate buffer on the device
cudaCheck(cudaMemcpyAsync(tmp.deviceData(), buffer.deviceData(), sizeof(NodeManagerData), cudaMemcpyDeviceToDevice, stream));
buffer = std::move(tmp);
d_data = reinterpret_cast<NodeManagerData*>(buffer.deviceData());
util::cuda::lambdaKernel<<<1, 1, 0, stream>>>(1, [=] __device__ (size_t) {
auto &tree = d_grid->tree();
int64_t *ptr0 = d_data->mPtr[0] = reinterpret_cast<int64_t*>(d_data + 1);
int64_t *ptr1 = d_data->mPtr[1] = d_data->mPtr[0] + tree.nodeCount(0);
int64_t *ptr2 = d_data->mPtr[2] = d_data->mPtr[1] + tree.nodeCount(1);
// Performs depth first traversal but breadth first insertion
for (auto it2 = tree.root().cbeginChild(); it2; ++it2) {
*ptr2++ = util::PtrDiff(&*it2, d_grid);
for (auto it1 = it2->cbeginChild(); it1; ++it1) {
*ptr1++ = util::PtrDiff(&*it1, d_grid);
for (auto it0 = it1->cbeginChild(); it0; ++it0) {
*ptr0++ = util::PtrDiff(&*it0, d_grid);
}// loop over child nodes of the lower internal node
}// loop over child nodes of the upper internal node
}// loop over child nodes of the root node
});
}
return NodeManagerHandle<BufferT>(toGridType<BuildT>(), std::move(buffer));
}// cuda::createNodeManager
}// namespace cuda
template <typename BuildT, typename BufferT = cuda::DeviceBuffer>
[[deprecated("Use cuda::createNodeManager instead")]]
inline typename util::enable_if<BufferTraits<BufferT>::hasDeviceDual, NodeManagerHandle<BufferT>>::type
cudaCreateNodeManager(const NanoGrid<BuildT> *d_grid,
const BufferT& pool = BufferT(),
cudaStream_t stream = 0)
{
return cuda::createNodeManager<BuildT, BufferT>(d_grid, pool, stream);
}
} // namespace nanovdb
#endif // NANOVDB_CUDA_NODE_MANAGER_CUH_HAS_BEEN_INCLUDED

Some files were not shown because too many files have changed in this diff Show More