From 4c3a5affa624f99f0de53532d81c9ef8ffbb138b Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:43:53 -0400 Subject: [PATCH 01/98] Prevents integer overflow Prevent integer overflow on grids with many nodes or leafs. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/LeafManager.h | 2 +- openvdb/openvdb/tree/NodeManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openvdb/openvdb/tree/LeafManager.h b/openvdb/openvdb/tree/LeafManager.h index 0f6293d443..69049425b8 100644 --- a/openvdb/openvdb/tree/LeafManager.h +++ b/openvdb/openvdb/tree/LeafManager.h @@ -596,7 +596,7 @@ class LeafManager // Compute the leaf counts for each node - std::vector leafCounts; + std::vector leafCounts; if (serial) { leafCounts.reserve(leafParents.size()); for (LeafParentT* leafParent : leafParents) { diff --git a/openvdb/openvdb/tree/NodeManager.h b/openvdb/openvdb/tree/NodeManager.h index ce483bd7df..8d47dafd7a 100644 --- a/openvdb/openvdb/tree/NodeManager.h +++ b/openvdb/openvdb/tree/NodeManager.h @@ -107,7 +107,7 @@ class NodeList { // Compute the node counts for each node - std::vector nodeCounts; + std::vector nodeCounts; if (serial) { nodeCounts.reserve(parents.nodeCount()); for (size_t i = 0; i < parents.nodeCount(); i++) { From f04f2f6864db16495426a5e3a065c998c507931d Mon Sep 17 00:00:00 2001 From: Tom Matterson Date: Mon, 20 May 2024 09:54:51 +1200 Subject: [PATCH 02/98] Added feature to read points into vdb_tool using Point Data Abstraction Library (PDAL) * Uses any available pdal plugin to read input file * Writes RGB into Cd channel of points (also extended to PTS implementation) * Adds a requirement on PDAL, so hidden behind a feature VDB_TOOL_USE_PDAL - off by default Signed-off-by: Tom Matterson --- ci/install_windows.sh | 2 +- openvdb_cmd/vdb_tool/CMakeLists.txt | 15 ++++ openvdb_cmd/vdb_tool/include/Geometry.h | 96 ++++++++++++++++++++++++- openvdb_cmd/vdb_tool/include/Tool.h | 49 ++++++++++++- 4 files changed, 155 insertions(+), 7 deletions(-) diff --git a/ci/install_windows.sh b/ci/install_windows.sh index 939668c4b3..5c25d8392c 100755 --- a/ci/install_windows.sh +++ b/ci/install_windows.sh @@ -3,6 +3,6 @@ set -ex vcpkg update -vcpkg install zlib libpng openexr tbb gtest cppunit blosc glfw3 glew python3 jemalloc \ +vcpkg install zlib libpng libpdal openexr tbb gtest cppunit blosc glfw3 glew python3 jemalloc \ boost-iostreams boost-interprocess boost-algorithm pybind11 \ --clean-after-build diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index f9b846b8aa..877fcd853d 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -34,6 +34,7 @@ option(OPENVDB_TOOL_NANO_USE_BLOSC "Compile NanoVDB with Blosc compression suppo option(OPENVDB_TOOL_USE_PNG "Compile with PNG support" OFF) option(OPENVDB_TOOL_USE_EXR "Compile with EXR support" OFF) option(OPENVDB_TOOL_USE_JPG "Compile with JPG support" OFF) +option(OPENVDB_TOOL_USE_PDAL "Compile with extended points support" OFF) option(OPENVDB_TOOL_USE_ABC "Compile with Alembic support" OFF) option(OPENVDB_TOOL_USE_ALL "Compile with all optional components" OFF) if(OPENVDB_TOOL_USE_ALL) @@ -42,6 +43,8 @@ if(OPENVDB_TOOL_USE_ALL) set(OPENVDB_TOOL_USE_EXR ON) set(OPENVDB_TOOL_USE_JPG ON) set(OPENVDB_TOOL_USE_ABC ON) + set(OPENVDB_TOOL_USE_PDAL ON) + endif() if(OPENVDB_TOOL_USE_NANO) @@ -83,6 +86,18 @@ if(OPENVDB_TOOL_USE_PNG) target_link_libraries(vdb_tool_common INTERFACE png) endif() +if(OPENVDB_TOOL_USE_PDAL) + target_compile_definitions(vdb_tool_common INTERFACE "VDB_TOOL_USE_PDAL") + if(WIN32) + find_package(libdpal CONFIG REQUIRED) + else() + find_package(PDAL REQUIRED) + endif() + message(STATUS "PDAL: ${PDAL_LIBRARIES} ${PDAL_INCLUDE_DIRS}") + target_link_libraries(vdb_tool_common INTERFACE ${PDAL_LIBRARIES}) + target_include_directories(vdb_tool_common INTERFACE ${PDAL_INCLUDE_DIRS}) +endif() + if(OPENVDB_TOOL_USE_JPG) target_compile_definitions(vdb_tool_common INTERFACE "VDB_TOOL_USE_JPG") find_package(JPEG REQUIRED) diff --git a/openvdb_cmd/vdb_tool/include/Geometry.h b/openvdb_cmd/vdb_tool/include/Geometry.h index 07c7f44743..4225f5bb17 100644 --- a/openvdb_cmd/vdb_tool/include/Geometry.h +++ b/openvdb_cmd/vdb_tool/include/Geometry.h @@ -45,6 +45,14 @@ #include #endif +#ifdef VDB_TOOL_USE_PDAL +#include "pdal/pdal.hpp" +#include "pdal/PipelineManager.hpp" +#include "pdal/PipelineReaderJSON.hpp" +#include "pdal/util/FileUtils.hpp" +#include +#endif + #if defined(_WIN32) #include #else @@ -82,9 +90,13 @@ class Geometry const std::vector& vtx() const { return mVtx; } const std::vector& tri() const { return mTri; } const std::vector& quad() const { return mQuad; } + const std::vector& rgb() const { return mRGB; } + std::vector& vtx() { return mVtx; } std::vector& tri() { return mTri; } std::vector& quad() { return mQuad; } + std::vector& rgb() { return mRGB; } + const BBoxT& bbox() const; void clear(); @@ -108,6 +120,7 @@ class Geometry void readPTS(const std::string &fileName); void readGEO(const std::string &fileName); void readABC(const std::string &fileName); + void readPDAL(const std::string &fileName); void readVDB(const std::string &fileName); void readNVDB(const std::string &fileName); @@ -138,6 +151,7 @@ class Geometry std::vector mVtx; std::vector mTri; std::vector mQuad; + std::vector mRGB; mutable BBoxT mBBox; std::string mName; @@ -393,8 +407,16 @@ void Geometry::read(const std::string &fileName) this->readGEO(fileName); break; default: - throw std::invalid_argument("Geometry::read: File \""+fileName+"\" has an invalid extension"); - break; +#if VDB_TOOL_USE_PDAL + pdal::StageFactory factory; + const std::string driver = factory.inferReaderDriver(fileName); + if (driver != "") { + this->readPDAL(fileName); + break; + } +#endif + throw std::invalid_argument("Geometry::read: File \""+fileName+"\" has an invalid extension"); + break; } }// Geometry::read @@ -442,6 +464,59 @@ void Geometry::readOBJ(std::istream &is) mBBox = BBoxT();//invalidate BBox }// Geometry::readOBJ +void Geometry::readPDAL(const std::string &fileName) +{ + #if VDB_TOOL_USE_PDAL + if (!pdal::FileUtils::fileExists(fileName)) throw std::invalid_argument("Error opening file \""+fileName+"\" - it doesn't exist!"); + + pdal::StageFactory factory; + std::string type = factory.inferReaderDriver(fileName); + std::string pipelineJson = R"({ + "pipeline" : [ + { + "type" : ")" + type + R"(", + "filename" : ")" + fileName + R"(" + } + ] + })"; + + Vec3f p; + Vec3s rgb; + try { + pdal::PipelineManager manager; + std::stringstream s(pipelineJson); + manager.readPipeline(s); + manager.execute(pdal::ExecMode::Standard); + + for (const std::shared_ptr& view : manager.views()) { + bool hasColor = false; + if (view->hasDim(pdal::Dimension::Id::Red) && view->hasDim(pdal::Dimension::Id::Green) && view->hasDim(pdal::Dimension::Id::Blue)) + hasColor = true; + for (const pdal::PointRef& point : *view) { + p[0] = point.getFieldAs(pdal::Dimension::Id::X); + p[1] = point.getFieldAs(pdal::Dimension::Id::Y); + p[2] = point.getFieldAs(pdal::Dimension::Id::Z); + mVtx.push_back(p); + if (hasColor) { + rgb[0] = point.getFieldAs(pdal::Dimension::Id::Red); + rgb[1] = point.getFieldAs(pdal::Dimension::Id::Green); + rgb[2] = point.getFieldAs(pdal::Dimension::Id::Blue); + mRGB.push_back(rgb); + } + } + } + + } + catch (const pdal::pdal_error& e) { + throw std::runtime_error("PDAL failed: " + std::string(e.what())); + } + catch (const std::exception& e) { + throw std::runtime_error("Reading file failed: " + std::string(e.what())); + } +#endif + mBBox = BBoxT(); //invalidate BBox +}// Geometry::readPDAL + void Geometry::readPLY(const std::string &fileName) { if (fileName == "stdin.ply") { @@ -482,7 +557,7 @@ void Geometry::readPLY(std::istream &is) if (!test(0, {"ply"})) error("vdb_tool::readPLY: not a ply file"); int format = -1;// 0 is ascii, 1 is little endian and 2 is big endian - tokens = tokenize_line(); + tokens = tokenize_line(); if (!(test(0, {"format"}) && test(2, {"1.0"})) ) { error("vdb_tool::readPLY: expected format version 1.0"); } else if (test(1, {"ascii"})) { @@ -753,6 +828,9 @@ void Geometry::readPTS(const std::string &fileName) if (!infile.is_open()) throw std::runtime_error("Error opening particle file \""+fileName+"\""); std::string line; std::istringstream iss; + bool readColor = false; + int i = 0; + Vec3s rgb; while(std::getline(infile, line)) { const size_t n = mVtx.size(), m = std::stoi(line); mVtx.resize(n + m); @@ -764,6 +842,18 @@ void Geometry::readPTS(const std::string &fileName) if (!(iss >> p[0] >> p[1] >> p[2])) {;//ignore intensity, r, g, b throw std::invalid_argument("Geometry::readPTS: error parsing line: \""+line+"\""); } + if (readColor) { + if (!(iss >> i) ) { // converting intensity to a multiplier on rgb might be appropriate, but i can't find a good spec for it + readColor = false; + continue; + } + if (!(iss >> rgb[0] >> rgb[1] >> rgb[2])) { + readColor = false; + continue; + } + mRGB.push_back(rgb/255.0); + } + }// loop over points }// loop over scans mBBox = BBoxT();//invalidate BBox diff --git a/openvdb_cmd/vdb_tool/include/Tool.h b/openvdb_cmd/vdb_tool/include/Tool.h index 4c27b32e32..ae82f69057 100644 --- a/openvdb_cmd/vdb_tool/include/Tool.h +++ b/openvdb_cmd/vdb_tool/include/Tool.h @@ -47,6 +47,7 @@ #include // for tools::interiorMask() #include #include +#include #include #include @@ -69,6 +70,10 @@ #include #endif +#ifdef VDB_TOOL_USE_PDAL +#include +#endif + #ifdef VDB_TOOL_USE_JPG #include #endif @@ -969,6 +974,14 @@ void Tool::read() this->readNVDB(fileName); break; default: +#if VDB_TOOL_USE_PDAL + pdal::StageFactory factory; + if (factory.inferReaderDriver(fileName) != "") + { + this->readGeo(fileName); + break; + } +#endif throw std::invalid_argument("File \""+fileName+"\" has an invalid extension"); break; } @@ -1421,6 +1434,7 @@ void Tool::pointsToVdb() const int bits = mParser.get("bits"); std::string grid_name = mParser.get("name"); using GridT = points::PointDataGrid; + using IdGridT = tools::PointIndexGrid; if (mParser.verbose) mTimer.start("Points to VDB"); auto it = this->getGeom(age); Points points((*it)->vtx()); @@ -1428,19 +1442,48 @@ void Tool::pointsToVdb() auto xform = math::Transform::createLinearTransform(voxelSize); GridT::Ptr grid; + IdGridT::Ptr indexGrid; + + points::PointAttributeVector positionsWrapper((*it)->vtx()); + openvdb::NamePair rgbAttribute ; switch (bits) { case 8: - grid = points::createPointDataGrid, GridT>((*it)->vtx(), *xform); + indexGrid = tools::createPointIndexGrid(positionsWrapper, *xform); + grid = points::createPointDataGrid, GridT>(*indexGrid, positionsWrapper, *xform); + openvdb::points::TypedAttributeArray::registerType(); + rgbAttribute = + openvdb::points::TypedAttributeArray::attributeType(); + openvdb::points::appendAttribute(grid->tree(), "Cd", rgbAttribute); break; case 16: - grid = points::createPointDataGrid, GridT>((*it)->vtx(), *xform); + indexGrid = tools::createPointIndexGrid(positionsWrapper, *xform); + grid = points::createPointDataGrid, GridT>(*indexGrid, positionsWrapper, *xform); + openvdb::points::TypedAttributeArray::registerType(); + rgbAttribute = + openvdb::points::TypedAttributeArray::attributeType(); + openvdb::points::appendAttribute(grid->tree(), "Cd", rgbAttribute); break; case 32: - grid = points::createPointDataGrid((*it)->vtx(), *xform); + indexGrid = tools::createPointIndexGrid(positionsWrapper, *xform); + grid = points::createPointDataGrid(*indexGrid, positionsWrapper, *xform); + + openvdb::points::TypedAttributeArray::registerType(); + rgbAttribute = + openvdb::points::TypedAttributeArray::attributeType(); + openvdb::points::appendAttribute(grid->tree(), "Cd", rgbAttribute); break; default: throw std::invalid_argument("pointsToVdb: unsupported bit-width: "+std::to_string(bits)); } + + if ((*it)->rgb().size() == (*it)->vtx().size()) { + + points::PointAttributeVector rgbWrapper((*it)->rgb()); + points::populateAttribute>( + grid->tree(), indexGrid->tree(), "Cd", rgbWrapper); + + } if (grid_name.empty()) grid_name = "points2vdb_"+(*it)->getName(); grid->setName(grid_name); mGrid.push_back(grid); From c447849d620614c933d01cb10a9929324ed5af2b Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Fri, 4 Oct 2024 16:01:13 -0700 Subject: [PATCH 03/98] Drop support for ABI=9 Signed-off-by: Dan Bailey --- ci/build.sh | 1 - openvdb/openvdb/openvdb.cc | 9 +- openvdb/openvdb/points/AttributeArray.h | 127 +----------------- openvdb/openvdb/points/AttributeSet.cc | 2 - openvdb/openvdb/points/AttributeSet.h | 2 - openvdb/openvdb/points/PointDataGrid.h | 4 - openvdb/openvdb/tree/RootNode.h | 27 ---- openvdb/openvdb/unittest/TestValueAccessor.cc | 4 - openvdb/openvdb/version.h.in | 6 - openvdb_cmd/vdb_print/main.cc | 32 ++--- 10 files changed, 11 insertions(+), 203 deletions(-) diff --git a/ci/build.sh b/ci/build.sh index d2e8e96603..2c6d93ac22 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -184,7 +184,6 @@ set -x # - 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_9=ON \ -DOPENVDB_USE_DEPRECATED_ABI_10=ON \ -DOPENVDB_BUILD_VDB_PRINT=ON \ -DOPENVDB_BUILD_VDB_LOD=ON \ diff --git a/openvdb/openvdb/openvdb.cc b/openvdb/openvdb/openvdb.cc index c776409dfc..9dbdd0df62 100644 --- a/openvdb/openvdb/openvdb.cc +++ b/openvdb/openvdb/openvdb.cc @@ -14,18 +14,13 @@ #include #endif -#if OPENVDB_ABI_VERSION_NUMBER <= 8 - #error ABI <= 8 is no longer supported +#if OPENVDB_ABI_VERSION_NUMBER <= 9 + #error ABI <= 9 is no longer supported #endif // If using an OPENVDB_ABI_VERSION_NUMBER that has been deprecated, issue an // error directive. This can be optionally suppressed by defining: // OPENVDB_USE_DEPRECATED_ABI_=ON. -#ifndef OPENVDB_USE_DEPRECATED_ABI_9 - #if OPENVDB_ABI_VERSION_NUMBER == 9 - #error ABI = 9 is deprecated, CMake option OPENVDB_USE_DEPRECATED_ABI_9 suppresses this error - #endif -#endif #ifndef OPENVDB_USE_DEPRECATED_ABI_10 #if OPENVDB_ABI_VERSION_NUMBER == 10 #error ABI = 10 is deprecated, CMake option OPENVDB_USE_DEPRECATED_ABI_10 suppresses this error diff --git a/openvdb/openvdb/points/AttributeArray.h b/openvdb/openvdb/points/AttributeArray.h index 25ebbe8079..6f7f9c52a6 100644 --- a/openvdb/openvdb/points/AttributeArray.h +++ b/openvdb/openvdb/points/AttributeArray.h @@ -145,14 +145,6 @@ class OPENVDB_API AttributeArray /// Return a copy of this attribute. virtual AttributeArray::Ptr copy() const = 0; -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Return a copy of this attribute. -#ifndef _MSC_VER - OPENVDB_DEPRECATED_MESSAGE("In-memory compression no longer supported, use AttributeArray::copy() instead") -#endif - virtual AttributeArray::Ptr copyUncompressed() const = 0; -#endif - /// Return the number of elements in this array. /// @note This does not count each data element in a strided array virtual Index size() const = 0; @@ -197,13 +189,11 @@ class OPENVDB_API AttributeArray /// Return the number of bytes of memory used by this attribute. virtual size_t memUsage() const = 0; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 /// Return the number of bytes of memory used by this attribute array once it /// has been deserialized (this may be different to memUsage() if delay-loading /// is in use). Note that this method does NOT consider the fact that a /// uniform attribute could be expanded and only deals with delay-loading. virtual size_t memUsageIfLoaded() const = 0; -#endif /// Create a new attribute array of the given (registered) type, length and stride. /// @details If @a lock is non-null, the AttributeArray registry mutex @@ -228,15 +218,6 @@ class OPENVDB_API AttributeArray template bool hasValueType() const { return this->type().first == typeNameAsString(); } -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// @brief Set value at given index @a n from @a sourceIndex of another @a sourceArray. - // Windows does not allow base classes to be easily deprecated. -#ifndef _MSC_VER - OPENVDB_DEPRECATED_MESSAGE("Use copyValues() with source-target index pairs") -#endif - virtual void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) = 0; -#endif - /// @brief Copy values into this array from a source array to a target array /// as referenced by an iterator. /// @details Iterators must adhere to the ForwardIterator interface described @@ -278,19 +259,6 @@ class OPENVDB_API AttributeArray /// Compact the existing array to become uniform if all values are identical virtual bool compact() = 0; -#if OPENVDB_ABI_VERSION_NUMBER < 10 - // Windows does not allow base classes to be deprecated -#ifndef _MSC_VER - OPENVDB_DEPRECATED_MESSAGE("Previously this compressed the attribute array, now it does nothing") -#endif - virtual bool compress() = 0; - // Windows does not allow base classes to be deprecated -#ifndef _MSC_VER - OPENVDB_DEPRECATED_MESSAGE("Previously this uncompressed the attribute array, now it does nothing") -#endif - virtual bool decompress() = 0; -#endif - /// @brief Specify whether this attribute should be hidden (e.g., from UI or iterators). /// @details This is useful if the attribute is used for blind data or as scratch space /// for a calculation. @@ -359,10 +327,8 @@ class OPENVDB_API AttributeArray bool operator==(const AttributeArray& other) const; bool operator!=(const AttributeArray& other) const { return !this->operator==(other); } -#if OPENVDB_ABI_VERSION_NUMBER >= 9 /// Indirect virtual function to retrieve the data buffer cast to a char byte array const char* constDataAsByteArray() const { return this->dataAsByteArray(); } -#endif private: friend class ::TestAttributeArray; @@ -565,11 +531,6 @@ class TypedAttributeArray final: public AttributeArray /// while being copied using this copy-constructor in another thread. /// It is not thread-safe for write. TypedAttributeArray(const TypedAttributeArray&); -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Deep copy constructor. - OPENVDB_DEPRECATED_MESSAGE("Use copy-constructor without unused bool parameter") - TypedAttributeArray(const TypedAttributeArray&, bool /*unused*/); -#endif /// Deep copy assignment operator. /// @note this operator is thread-safe. @@ -585,13 +546,6 @@ class TypedAttributeArray final: public AttributeArray /// @note This method is thread-safe. AttributeArray::Ptr copy() const override; -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Return a copy of this attribute. - /// @note This method is thread-safe. - OPENVDB_DEPRECATED_MESSAGE("In-memory compression no longer supported, use AttributeArray::copy() instead") - AttributeArray::Ptr copyUncompressed() const override; -#endif - /// Return a new attribute array of the given length @a n and @a stride with uniform value zero. static Ptr create(Index n, Index strideOrTotalSize = 1, bool constantStride = true, const Metadata* metadata = nullptr); @@ -657,13 +611,11 @@ class TypedAttributeArray final: public AttributeArray /// Return the number of bytes of memory used by this attribute. size_t memUsage() const override; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 /// Return the number of bytes of memory used by this attribute array once it /// has been deserialized (this may be different to memUsage() if delay-loading /// is in use). Note that this method does NOT consider the fact that a /// uniform attribute could be expanded and only deals with delay-loading. size_t memUsageIfLoaded() const override; -#endif /// Return the value at index @a n (assumes in-core) ValueType getUnsafe(Index n) const; @@ -691,12 +643,6 @@ class TypedAttributeArray final: public AttributeArray /// (assumes in-core) static void setUnsafe(AttributeArray* array, const Index n, const ValueType& value); -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Set value at given index @a n from @a sourceIndex of another @a sourceArray - OPENVDB_DEPRECATED_MESSAGE("Use copyValues() with source-target index pairs") - void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) override; -#endif - /// Return @c true if this array is stored as a single uniform value. bool isUniform() const override { return mIsUniform; } /// @brief Replace the single value storage with an array of length size(). @@ -719,15 +665,6 @@ class TypedAttributeArray final: public AttributeArray /// Non-member equivalent to fill() that static_casts array to this TypedAttributeArray static void fill(AttributeArray* array, const ValueType& value); -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Compress the attribute array. - OPENVDB_DEPRECATED_MESSAGE("Previously this compressed the attribute array, now it does nothing") - bool compress() override; - /// Uncompress the attribute array. - OPENVDB_DEPRECATED_MESSAGE("Previously this uncompressed the attribute array, now it does nothing") - bool decompress() override; -#endif - /// Read attribute data from a stream. void read(std::istream&) override; /// Write attribute data to a stream. @@ -789,14 +726,7 @@ class TypedAttributeArray final: public AttributeArray /// Load data from memory-mapped file. inline void doLoad() const; /// Load data from memory-mapped file (unsafe as this function is not protected by a mutex). -#if OPENVDB_ABI_VERSION_NUMBER >= 10 inline void doLoadUnsafe() const; -#else - /// @param compression parameter no longer used - inline void doLoadUnsafe(const bool compression = true) const; - /// Compress in-core data assuming mutex is locked - inline bool compressUnsafe(); -#endif /// Toggle out-of-core state inline void setOutOfCore(const bool); @@ -1275,15 +1205,6 @@ TypedAttributeArray::copy() const } -#if OPENVDB_ABI_VERSION_NUMBER < 10 -template -AttributeArray::Ptr -TypedAttributeArray::copyUncompressed() const -{ - return this->copy(); -} -#endif - template size_t TypedAttributeArray::arrayMemUsage() const @@ -1385,14 +1306,13 @@ TypedAttributeArray::memUsage() const return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0); } -#if OPENVDB_ABI_VERSION_NUMBER >= 10 + template size_t TypedAttributeArray::memUsageIfLoaded() const { return sizeof(*this) + (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType); } -#endif template @@ -1497,21 +1417,6 @@ TypedAttributeArray::setUnsafe(AttributeArray* array, const } -#if OPENVDB_ABI_VERSION_NUMBER < 10 -template -void -TypedAttributeArray::set(Index n, const AttributeArray& sourceArray, const Index sourceIndex) -{ - const TypedAttributeArray& sourceTypedArray = static_cast(sourceArray); - - ValueType sourceValue; - sourceTypedArray.get(sourceIndex, sourceValue); - - this->set(n, sourceValue); -} -#endif - - template void TypedAttributeArray::expand(bool fill) @@ -1605,32 +1510,6 @@ TypedAttributeArray::fill(AttributeArray* array, const Value } -#if OPENVDB_ABI_VERSION_NUMBER < 10 -template -inline bool -TypedAttributeArray::compress() -{ - return false; -} - - -template -inline bool -TypedAttributeArray::compressUnsafe() -{ - return false; -} - - -template -inline bool -TypedAttributeArray::decompress() -{ - return false; -} -#endif - - template bool TypedAttributeArray::isOutOfCore() const @@ -1976,11 +1855,7 @@ TypedAttributeArray::writePagedBuffers(compression::PagedOut template void -#if OPENVDB_ABI_VERSION_NUMBER >= 10 TypedAttributeArray::doLoadUnsafe() const -#else -TypedAttributeArray::doLoadUnsafe(const bool /*compression*/) const -#endif { if (!(this->isOutOfCore())) return; diff --git a/openvdb/openvdb/points/AttributeSet.cc b/openvdb/openvdb/points/AttributeSet.cc index a1d58d2162..fc51d7db0e 100644 --- a/openvdb/openvdb/points/AttributeSet.cc +++ b/openvdb/openvdb/points/AttributeSet.cc @@ -140,7 +140,6 @@ AttributeSet::memUsage() const } -#if OPENVDB_ABI_VERSION_NUMBER >= 10 size_t AttributeSet::memUsageIfLoaded() const { @@ -150,7 +149,6 @@ AttributeSet::memUsageIfLoaded() const } return bytes; } -#endif size_t diff --git a/openvdb/openvdb/points/AttributeSet.h b/openvdb/openvdb/points/AttributeSet.h index 1398f58728..c492d402b8 100644 --- a/openvdb/openvdb/points/AttributeSet.h +++ b/openvdb/openvdb/points/AttributeSet.h @@ -114,12 +114,10 @@ class OPENVDB_API AttributeSet /// Return the number of bytes of memory used by this attribute set. size_t memUsage() const; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 /// Return the number of bytes of memory used by this attribute set once it /// has been deserialized (this may be different to memUsage() if delay-loading /// is in use). size_t memUsageIfLoaded() const; -#endif /// @brief Return the position of the attribute array whose name is @a name, /// or @c INVALID_POS if no match is found. diff --git a/openvdb/openvdb/points/PointDataGrid.h b/openvdb/openvdb/points/PointDataGrid.h index 5e1a7ac21b..2cf25e7eec 100644 --- a/openvdb/openvdb/points/PointDataGrid.h +++ b/openvdb/openvdb/points/PointDataGrid.h @@ -504,9 +504,7 @@ class PointDataLeafNode : public tree::LeafNode, io::MultiPass { Index64 memUsage() const; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 Index64 memUsageIfLoaded() const; -#endif void evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels = true) const; @@ -1524,14 +1522,12 @@ PointDataLeafNode::memUsage() const return BaseLeaf::memUsage() + mAttributeSet->memUsage(); } -#if OPENVDB_ABI_VERSION_NUMBER >= 10 template inline Index64 PointDataLeafNode::memUsageIfLoaded() const { return BaseLeaf::memUsageIfLoaded() + mAttributeSet->memUsageIfLoaded(); } -#endif template inline void diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 0d182b5864..5eb7794115 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -881,7 +881,6 @@ class RootNode void combine2(const RootNode& other0, const OtherRootNode& other1, CombineOp& op, bool prune = false); -#if OPENVDB_ABI_VERSION_NUMBER >= 10 /// Return the grid index coordinates of this node's local origin. const Coord& origin() const { return mOrigin; } /// @brief change the origin on this root node @@ -890,7 +889,6 @@ class RootNode /// @warning This method will throw if the origin is non-zero, since /// other tools do not yet support variable offsets. void setOrigin(const Coord &origin); -#endif private: /// During topology-only construction, access is needed @@ -913,13 +911,8 @@ class RootNode Index getActiveTileCount() const; Index getInactiveTileCount() const; -#if OPENVDB_ABI_VERSION_NUMBER < 10 - /// Static method that returns a MapType key for the given coordinates. - static Coord coordToKey(const Coord& xyz) {return xyz & ~(ChildType::DIM - 1); } -#else /// Return a MapType key for the given coordinates, offset by the mOrigin. Coord coordToKey(const Coord& xyz) const { return (xyz - mOrigin) & ~(ChildType::DIM - 1); } -#endif /// Insert this node's mTable keys into the given set. void insertKeys(CoordSet&) const; @@ -963,9 +956,7 @@ class RootNode MapType mTable; ValueType mBackground; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 Coord mOrigin; -#endif /// Transient Data (not serialized) Index32 mTransientData = 0; }; // end of RootNode class @@ -1032,9 +1023,7 @@ template inline RootNode::RootNode() : mBackground(zeroVal()) -#if OPENVDB_ABI_VERSION_NUMBER >= 10 , mOrigin(0, 0, 0) -#endif { this->initTable(); } @@ -1044,9 +1033,7 @@ template inline RootNode::RootNode(const ValueType& background) : mBackground(background) -#if OPENVDB_ABI_VERSION_NUMBER >= 10 , mOrigin(0, 0, 0) -#endif { this->initTable(); } @@ -1058,18 +1045,14 @@ inline RootNode::RootNode(const RootNode& other, const ValueType& backgd, const ValueType& foregd, TopologyCopy) : mBackground(backgd) -#if OPENVDB_ABI_VERSION_NUMBER >= 10 , mOrigin(other.mOrigin) -#endif , mTransientData(other.mTransientData) { using OtherRootT = RootNode; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 if (mOrigin != Coord(0,0,0)) { OPENVDB_THROW(ValueError, "RootNode::RootNode: non-zero offsets are currently not supported"); } -#endif enforceSameConfiguration(other); @@ -1090,18 +1073,14 @@ inline RootNode::RootNode(const RootNode& other, const ValueType& backgd, TopologyCopy) : mBackground(backgd) -#if OPENVDB_ABI_VERSION_NUMBER >= 10 , mOrigin(other.mOrigin) -#endif , mTransientData(other.mTransientData) { using OtherRootT = RootNode; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 if (mOrigin != Coord(0,0,0)) { OPENVDB_THROW(ValueError, "RootNode::RootNode: non-zero offsets are currently not supported"); } -#endif enforceSameConfiguration(other); @@ -1158,12 +1137,10 @@ struct RootNodeCopyHelper }; self.mBackground = Local::convertValue(other.mBackground); -#if OPENVDB_ABI_VERSION_NUMBER >= 10 if (other.mOrigin != Coord(0,0,0)) { OPENVDB_THROW(ValueError, "RootNodeCopyHelper::copyWithValueConversion: non-zero offsets are currently not supported"); } self.mOrigin = other.mOrigin; -#endif self.mTransientData = other.mTransientData; self.clear(); @@ -1191,12 +1168,10 @@ RootNode::operator=(const RootNode& other) { if (&other != this) { mBackground = other.mBackground; -#if OPENVDB_ABI_VERSION_NUMBER >= 10 mOrigin = other.mOrigin; if (mOrigin != Coord(0,0,0)) { OPENVDB_THROW(ValueError, "RootNode::operator=: non-zero offsets are currently not supported"); } -#endif mTransientData = other.mTransientData; this->clear(); @@ -2652,7 +2627,6 @@ RootNode::addChild(ChildT* child) return true; } -#if OPENVDB_ABI_VERSION_NUMBER >= 10 template inline void RootNode::setOrigin(const Coord &origin) @@ -2662,7 +2636,6 @@ RootNode::setOrigin(const Coord &origin) OPENVDB_THROW(ValueError, "RootNode::setOrigin: non-zero offsets are currently not supported"); } } -#endif template inline void diff --git a/openvdb/openvdb/unittest/TestValueAccessor.cc b/openvdb/openvdb/unittest/TestValueAccessor.cc index b4907a7cd0..3b698b5ef0 100644 --- a/openvdb/openvdb/unittest/TestValueAccessor.cc +++ b/openvdb/openvdb/unittest/TestValueAccessor.cc @@ -665,8 +665,6 @@ TEST_F(TestValueAccessor, testGetNode) } } -#if OPENVDB_ABI_VERSION_NUMBER >= 10 - template struct AssertBypass { inline void operator()() { @@ -703,5 +701,3 @@ TEST_F(TestValueAccessor, testBypassLeafAPI) static_assert(!ValueAccessor2::BypassLeafAPI); static_assert(!ValueAccessor3::BypassLeafAPI); } - -#endif diff --git a/openvdb/openvdb/version.h.in b/openvdb/openvdb/version.h.in index 54a7b3742d..36421977d9 100644 --- a/openvdb/openvdb/version.h.in +++ b/openvdb/openvdb/version.h.in @@ -189,12 +189,6 @@ // directive. This can be suppressed by defining OPENVDB_USE_DEPRECATED_ABI_. // Note that, whilst the VDB CMake does not allow this option to be hit, // it exists to propagate this message to downstream targets -#ifndef OPENVDB_USE_DEPRECATED_ABI_9 - #if OPENVDB_ABI_VERSION_NUMBER == 9 - PRAGMA(message("NOTE: ABI = 9 is deprecated, define OPENVDB_USE_DEPRECATED_ABI_9 " - "to suppress this message")) - #endif -#endif #ifndef OPENVDB_USE_DEPRECATED_ABI_10 #if OPENVDB_ABI_VERSION_NUMBER == 10 PRAGMA(message("NOTE: ABI = 10 is deprecated, define OPENVDB_USE_DEPRECATED_ABI_10 " diff --git a/openvdb_cmd/vdb_print/main.cc b/openvdb_cmd/vdb_print/main.cc index de96ad4ed4..6a1da07078 100644 --- a/openvdb_cmd/vdb_print/main.cc +++ b/openvdb_cmd/vdb_print/main.cc @@ -210,31 +210,15 @@ printShortListing(const StringVec& filenames, bool metadata) // Print the grid's size, in bytes // no support for memUsageIfLoaded until ABI >= 10 for points::PointDataGrid types -#if OPENVDB_ABI_VERSION_NUMBER < 10 - using ListT = openvdb::GridTypes::Remove; -#else using ListT = openvdb::GridTypes; -#endif - const bool success = - grid->apply([&](const auto& typed){ - // @todo combine these methods to avoid iterating across the tree twice - const openvdb::Index64 incore = openvdb::tools::memUsage(typed.tree()); - const openvdb::Index64 total = openvdb::tools::memUsageIfLoaded(typed.tree()); - - std::cout << " " << std::right << std::setw(6) << bytesAsString(incore) << " (In Core)"; - std::cout << " " << std::right << std::setw(6) << bytesAsString(total) << " (Total)"; - }); - - (void)success; -#if OPENVDB_ABI_VERSION_NUMBER < 10 - if (!success) { - // could be a points grid, print in-core memory only - grid->apply([&](const auto& typed){ - const openvdb::Index64 incore = openvdb::tools::memUsage(typed.tree()); - std::cout << " " << std::right << std::setw(6) << bytesAsString(incore) << " (In Core)"; - }); - } -#endif + grid->apply([&](const auto& typed){ + // @todo combine these methods to avoid iterating across the tree twice + const openvdb::Index64 incore = openvdb::tools::memUsage(typed.tree()); + const openvdb::Index64 total = openvdb::tools::memUsageIfLoaded(typed.tree()); + + std::cout << " " << std::right << std::setw(6) << bytesAsString(incore) << " (In Core)"; + std::cout << " " << std::right << std::setw(6) << bytesAsString(total) << " (Total)"; + }); std::cout << std::endl; From ffea83c8ce460686a6ae2eaab8cb668cb3a570e9 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 10:47:24 -0700 Subject: [PATCH 04/98] Updated deprecation strategy to document new policy Signed-off-by: Dan Bailey --- tsc/process/deprecation.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tsc/process/deprecation.md b/tsc/process/deprecation.md index bf54ece78d..3ed9a307ca 100644 --- a/tsc/process/deprecation.md +++ b/tsc/process/deprecation.md @@ -5,7 +5,7 @@ OpenVDB is committed to supporting three years of Houdini and Maya based on those versions of the platform. The latest supported year is that in which the VDB version listed matches the major version. -For example, version 6.1.0 of OpenVDB supports VFX Reference Platform years +For example, all 6.x versions of OpenVDB support VFX Reference Platform years 2019, 2018 and 2017. This infers the following support: @@ -14,9 +14,5 @@ This infers the following support: * C++11 and C++14 * Houdini 16.5, 17.0 and 17.5 -When version 7.0.0 is released, OpenVDB will support VFX Reference Platform -years 2020, 2019 and 2018. Support for Houdini 16.5 and C++11 will be dropped. - -Support for obsolete ABIs will not be dropped until the first minor release -after the introduction of a new ABI. For example, the latest version to retain -support for ABI=4 will be the release prior to 7.1.0. +All 7.x versions of OpenVDB support VFX Reference Platform years 2020, 2019 and +2018. Support for Houdini 16.5, C++11 and ABI=4 is removed. From a824f1bfbafb8515a0ed068412203b1866b1095f Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 11:59:49 -0700 Subject: [PATCH 05/98] Add RootNode and InternalNode unit tests Signed-off-by: Dan Bailey --- openvdb/openvdb/unittest/CMakeLists.txt | 2 + openvdb/openvdb/unittest/TestInternalNode.cc | 122 +++++++++++ openvdb/openvdb/unittest/TestRootNode.cc | 112 +++++++++++ openvdb/openvdb/unittest/TestTree.cc | 201 ------------------- 4 files changed, 236 insertions(+), 201 deletions(-) create mode 100644 openvdb/openvdb/unittest/TestInternalNode.cc create mode 100644 openvdb/openvdb/unittest/TestRootNode.cc diff --git a/openvdb/openvdb/unittest/CMakeLists.txt b/openvdb/openvdb/unittest/CMakeLists.txt index 3fa4b9130b..449fd68873 100644 --- a/openvdb/openvdb/unittest/CMakeLists.txt +++ b/openvdb/openvdb/unittest/CMakeLists.txt @@ -111,6 +111,7 @@ else() TestInt32Metadata.cc TestInt64Metadata.cc TestInternalOrigin.cc + TestInternalNode.cc TestLaplacian.cc TestLeaf.cc TestLeafBool.cc @@ -166,6 +167,7 @@ else() TestQuantizedUnitVec.cc TestQuat.cc TestRay.cc + TestRootNode.cc TestStats.cc TestStencils.cc TestStream.cc diff --git a/openvdb/openvdb/unittest/TestInternalNode.cc b/openvdb/openvdb/unittest/TestInternalNode.cc new file mode 100644 index 0000000000..52e3a98258 --- /dev/null +++ b/openvdb/openvdb/unittest/TestInternalNode.cc @@ -0,0 +1,122 @@ + +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +using namespace openvdb; +using namespace openvdb::tree; + + +class TestInternalNode: public ::testing::Test +{ +}; + + +TEST_F(TestInternalNode, test) +{ + const Coord c0(1000, 1000, 1000); + const Coord c1(896, 896, 896); + + using LeafNodeType = openvdb::tree::LeafNode; + using InternalNodeType = openvdb::tree::InternalNode; + using ChildType = LeafNodeType; + + { // test inserting child nodes directly and indirectly + Coord c2 = c1.offsetBy(8,0,0); + Coord c3 = c1.offsetBy(16,16,16); + + InternalNodeType internalNode(c1, 0.0f); + internalNode.touchLeaf(c2); + internalNode.touchLeaf(c3); + + EXPECT_EQ(Index(2), internalNode.leafCount()); + EXPECT_EQ(Index32(2), internalNode.childCount()); + EXPECT_TRUE(!internalNode.hasActiveTiles()); + + { // verify c0 and c1 are the root node coordinates + auto childIter = internalNode.cbeginChildOn(); + EXPECT_EQ(c2, childIter.getCoord()); + ++childIter; + EXPECT_EQ(c3, childIter.getCoord()); + } + + // copy the internal node + InternalNodeType internalNodeCopy(internalNode); + + // steal the internal node children leaving it empty again + std::vector children; + internalNode.stealNodes(children, 0.0f, false); + EXPECT_EQ(Index(0), internalNode.leafCount()); + EXPECT_EQ(Index32(0), internalNode.childCount()); + + // insert the root node children directly + for (ChildType* child : children) { + internalNode.addChild(child); + } + EXPECT_EQ(Index(2), internalNode.leafCount()); + EXPECT_EQ(Index32(2), internalNode.childCount()); + + { // verify the coordinates of the root node children + auto childIter = internalNode.cbeginChildOn(); + EXPECT_EQ(c2, childIter.getCoord()); + ++childIter; + EXPECT_EQ(c3, childIter.getCoord()); + } + } + + { // test inserting a tile and replacing with a child node + InternalNodeType internalNode(c1, 0.0f); + EXPECT_TRUE(!internalNode.hasActiveTiles()); + EXPECT_EQ(Index(0), internalNode.leafCount()); + EXPECT_EQ(Index32(0), internalNode.childCount()); + + // add a tile + internalNode.addTile(Index(0), /*value=*/1.0f, /*state=*/true); + EXPECT_TRUE(internalNode.hasActiveTiles()); + EXPECT_EQ(Index(0), internalNode.leafCount()); + EXPECT_EQ(Index32(0), internalNode.childCount()); + + // replace the tile with a child node + EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 2.0f))); + EXPECT_TRUE(!internalNode.hasActiveTiles()); + EXPECT_EQ(Index(1), internalNode.leafCount()); + EXPECT_EQ(Index32(1), internalNode.childCount()); + EXPECT_EQ(c1, internalNode.cbeginChildOn().getCoord()); + EXPECT_NEAR(internalNode.cbeginChildOn()->getValue(0), 2.0f, /*tolerance=*/0.0); + + // replace the child node with another child node + EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 3.0f))); + EXPECT_NEAR(internalNode.cbeginChildOn()->getValue(0), 3.0f, /*tolerance=*/0.0); + } + + { // test inserting child nodes that do and do not belong to the internal node + InternalNodeType internalNode(c1, 0.0f); + + // succeed if child belongs to this internal node + EXPECT_TRUE(internalNode.addChild(new ChildType(c0.offsetBy(8,0,0)))); + EXPECT_TRUE(internalNode.probeLeaf(c0.offsetBy(8,0,0))); + Index index1 = internalNode.coordToOffset(c0); + Index index2 = internalNode.coordToOffset(c0.offsetBy(8,0,0)); + EXPECT_TRUE(!internalNode.isChildMaskOn(index1)); + EXPECT_TRUE(internalNode.isChildMaskOn(index2)); + + // fail otherwise + auto* child = new ChildType(c0.offsetBy(8000,0,0)); + EXPECT_TRUE(!internalNode.addChild(child)); + delete child; + } + + { // test transient data + InternalNodeType internalNode(c1, 0.0f); + EXPECT_EQ(Index32(0), internalNode.transientData()); + internalNode.setTransientData(Index32(5)); + EXPECT_EQ(Index32(5), internalNode.transientData()); + InternalNodeType internalNode2(internalNode); + EXPECT_EQ(Index32(5), internalNode2.transientData()); + InternalNodeType internalNode3 = internalNode; + EXPECT_EQ(Index32(5), internalNode3.transientData()); + } +} diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc new file mode 100644 index 0000000000..16be294068 --- /dev/null +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -0,0 +1,112 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include + +using namespace openvdb; +using namespace tree; + +class TestRoot: public ::testing::Test +{ +}; + + +TEST_F(TestRoot, test) +{ + using RootNodeType = FloatTree::RootNodeType; + using ChildType = RootNodeType::ChildNodeType; + const Coord c0(0,0,0), c1(49152, 16384, 28672); + + { // test inserting child nodes directly and indirectly + RootNodeType root(0.0f); + EXPECT_TRUE(root.empty()); + EXPECT_EQ(Index32(0), root.childCount()); + + // populate the tree by inserting the two leaf nodes containing c0 and c1 + root.touchLeaf(c0); + root.touchLeaf(c1); + EXPECT_EQ(Index(2), root.getTableSize()); + EXPECT_EQ(Index32(2), root.childCount()); + EXPECT_TRUE(!root.hasActiveTiles()); + + { // verify c0 and c1 are the root node coordinates + auto rootIter = root.cbeginChildOn(); + EXPECT_EQ(c0, rootIter.getCoord()); + ++rootIter; + EXPECT_EQ(c1, rootIter.getCoord()); + } + + // copy the root node + RootNodeType rootCopy(root); + + // steal the root node children leaving the root node empty again + std::vector children; + root.stealNodes(children); + EXPECT_TRUE(root.empty()); + + // insert the root node children directly + for (ChildType* child : children) { + root.addChild(child); + } + EXPECT_EQ(Index(2), root.getTableSize()); + EXPECT_EQ(Index32(2), root.childCount()); + + { // verify the coordinates of the root node children + auto rootIter = root.cbeginChildOn(); + EXPECT_EQ(c0, rootIter.getCoord()); + ++rootIter; + EXPECT_EQ(c1, rootIter.getCoord()); + } + } + + { // test inserting tiles and replacing them with child nodes + RootNodeType root(0.0f); + EXPECT_TRUE(root.empty()); + + // no-op + root.addChild(nullptr); + + // populate the root node by inserting tiles + root.addTile(c0, /*value=*/1.0f, /*state=*/true); + root.addTile(c1, /*value=*/2.0f, /*state=*/true); + EXPECT_EQ(Index(2), root.getTableSize()); + EXPECT_EQ(Index32(0), root.childCount()); + EXPECT_TRUE(root.hasActiveTiles()); + EXPECT_NEAR(root.getValue(c0), 1.0f, /*tolerance=*/0.0); + EXPECT_NEAR(root.getValue(c1), 2.0f, /*tolerance=*/0.0); + + // insert child nodes with the same coordinates + root.addChild(new ChildType(c0, 3.0f)); + root.addChild(new ChildType(c1, 4.0f)); + + // insert a new child at c0 + root.addChild(new ChildType(c0, 5.0f)); + + // verify active tiles have been replaced by child nodes + EXPECT_EQ(Index(2), root.getTableSize()); + EXPECT_EQ(Index32(2), root.childCount()); + EXPECT_TRUE(!root.hasActiveTiles()); + + { // verify the coordinates of the root node children + auto rootIter = root.cbeginChildOn(); + EXPECT_EQ(c0, rootIter.getCoord()); + EXPECT_NEAR(root.getValue(c0), 5.0f, /*tolerance=*/0.0); + ++rootIter; + EXPECT_EQ(c1, rootIter.getCoord()); + } + } + + { // test transient data + RootNodeType rootNode(0.0f); + EXPECT_EQ(Index32(0), rootNode.transientData()); + rootNode.setTransientData(Index32(5)); + EXPECT_EQ(Index32(5), rootNode.transientData()); + RootNodeType rootNode2(rootNode); + EXPECT_EQ(Index32(5), rootNode2.transientData()); + RootNodeType rootNode3 = rootNode; + EXPECT_EQ(Index32(5), rootNode3.transientData()); + } +} diff --git a/openvdb/openvdb/unittest/TestTree.cc b/openvdb/openvdb/unittest/TestTree.cc index 74ec5d63ab..e73cd52f11 100644 --- a/openvdb/openvdb/unittest/TestTree.cc +++ b/openvdb/openvdb/unittest/TestTree.cc @@ -2755,204 +2755,3 @@ TEST_F(TestTree, testNodeCount) EXPECT_EQ(tree.leafCount(), nodeCount2.front());// leaf nodes for (size_t i=0; i children; - root.stealNodes(children); - EXPECT_TRUE(root.empty()); - - // insert the root node children directly - for (ChildType* child : children) { - root.addChild(child); - } - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(2), root.childCount()); - - { // verify the coordinates of the root node children - auto rootIter = root.cbeginChildOn(); - EXPECT_EQ(c0, rootIter.getCoord()); - ++rootIter; - EXPECT_EQ(c1, rootIter.getCoord()); - } - } - - { // test inserting tiles and replacing them with child nodes - RootNodeType root(0.0f); - EXPECT_TRUE(root.empty()); - - // no-op - root.addChild(nullptr); - - // populate the root node by inserting tiles - root.addTile(c0, /*value=*/1.0f, /*state=*/true); - root.addTile(c1, /*value=*/2.0f, /*state=*/true); - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(0), root.childCount()); - EXPECT_TRUE(root.hasActiveTiles()); - ASSERT_DOUBLES_EXACTLY_EQUAL(1.0f, root.getValue(c0)); - ASSERT_DOUBLES_EXACTLY_EQUAL(2.0f, root.getValue(c1)); - - // insert child nodes with the same coordinates - root.addChild(new ChildType(c0, 3.0f)); - root.addChild(new ChildType(c1, 4.0f)); - - // insert a new child at c0 - root.addChild(new ChildType(c0, 5.0f)); - - // verify active tiles have been replaced by child nodes - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(2), root.childCount()); - EXPECT_TRUE(!root.hasActiveTiles()); - - { // verify the coordinates of the root node children - auto rootIter = root.cbeginChildOn(); - EXPECT_EQ(c0, rootIter.getCoord()); - ASSERT_DOUBLES_EXACTLY_EQUAL(5.0f, root.getValue(c0)); - ++rootIter; - EXPECT_EQ(c1, rootIter.getCoord()); - } - } - - { // test transient data - RootNodeType rootNode(0.0f); - EXPECT_EQ(openvdb::Index32(0), rootNode.transientData()); - rootNode.setTransientData(openvdb::Index32(5)); - EXPECT_EQ(openvdb::Index32(5), rootNode.transientData()); - RootNodeType rootNode2(rootNode); - EXPECT_EQ(openvdb::Index32(5), rootNode2.transientData()); - RootNodeType rootNode3 = rootNode; - EXPECT_EQ(openvdb::Index32(5), rootNode3.transientData()); - } -} - -TEST_F(TestTree, testInternalNode) -{ - const openvdb::Coord c0(1000, 1000, 1000); - const openvdb::Coord c1(896, 896, 896); - - using InternalNodeType = InternalNodeType1; - using ChildType = LeafNodeType; - - { // test inserting child nodes directly and indirectly - openvdb::Coord c2 = c1.offsetBy(8,0,0); - openvdb::Coord c3 = c1.offsetBy(16,16,16); - - InternalNodeType internalNode(c1, 0.0f); - internalNode.touchLeaf(c2); - internalNode.touchLeaf(c3); - - EXPECT_EQ(openvdb::Index(2), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - - { // verify c0 and c1 are the root node coordinates - auto childIter = internalNode.cbeginChildOn(); - EXPECT_EQ(c2, childIter.getCoord()); - ++childIter; - EXPECT_EQ(c3, childIter.getCoord()); - } - - // copy the internal node - InternalNodeType internalNodeCopy(internalNode); - - // steal the internal node children leaving it empty again - std::vector children; - internalNode.stealNodes(children, 0.0f, false); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // insert the root node children directly - for (ChildType* child : children) { - internalNode.addChild(child); - } - EXPECT_EQ(openvdb::Index(2), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); - - { // verify the coordinates of the root node children - auto childIter = internalNode.cbeginChildOn(); - EXPECT_EQ(c2, childIter.getCoord()); - ++childIter; - EXPECT_EQ(c3, childIter.getCoord()); - } - } - - { // test inserting a tile and replacing with a child node - InternalNodeType internalNode(c1, 0.0f); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // add a tile - internalNode.addTile(openvdb::Index(0), /*value=*/1.0f, /*state=*/true); - EXPECT_TRUE(internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // replace the tile with a child node - EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 2.0f))); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(1), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(1), internalNode.childCount()); - EXPECT_EQ(c1, internalNode.cbeginChildOn().getCoord()); - ASSERT_DOUBLES_EXACTLY_EQUAL(2.0f, internalNode.cbeginChildOn()->getValue(0)); - - // replace the child node with another child node - EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 3.0f))); - ASSERT_DOUBLES_EXACTLY_EQUAL(3.0f, internalNode.cbeginChildOn()->getValue(0)); - } - - { // test inserting child nodes that do and do not belong to the internal node - InternalNodeType internalNode(c1, 0.0f); - - // succeed if child belongs to this internal node - EXPECT_TRUE(internalNode.addChild(new ChildType(c0.offsetBy(8,0,0)))); - EXPECT_TRUE(internalNode.probeLeaf(c0.offsetBy(8,0,0))); - openvdb::Index index1 = internalNode.coordToOffset(c0); - openvdb::Index index2 = internalNode.coordToOffset(c0.offsetBy(8,0,0)); - EXPECT_TRUE(!internalNode.isChildMaskOn(index1)); - EXPECT_TRUE(internalNode.isChildMaskOn(index2)); - - // fail otherwise - auto* child = new ChildType(c0.offsetBy(8000,0,0)); - EXPECT_TRUE(!internalNode.addChild(child)); - delete child; - } - - { // test transient data - InternalNodeType internalNode(c1, 0.0f); - EXPECT_EQ(openvdb::Index32(0), internalNode.transientData()); - internalNode.setTransientData(openvdb::Index32(5)); - EXPECT_EQ(openvdb::Index32(5), internalNode.transientData()); - InternalNodeType internalNode2(internalNode); - EXPECT_EQ(openvdb::Index32(5), internalNode2.transientData()); - InternalNodeType internalNode3 = internalNode; - EXPECT_EQ(openvdb::Index32(5), internalNode3.transientData()); - } -} From 419df1ab06d69ced8ba5e634e005bbafd57dbc30 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 16:48:24 -0700 Subject: [PATCH 06/98] Add new RootNode probe methods Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 100 +++++++++++++++++++ openvdb/openvdb/unittest/TestRootNode.cc | 117 +++++++++++++++++++++++ 2 files changed, 217 insertions(+) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 5eb7794115..7376f80eb9 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -724,9 +724,20 @@ class RootNode template NodeT* probeNode(const Coord& xyz); template + const NodeT* probeNode(const Coord& xyz) const; + template const NodeT* probeConstNode(const Coord& xyz) const; //@} + //@{ + /// @brief Return a pointer to the root child node that contains voxel (x, y, z). + /// If no such node exists, query and set the tile value and active status and + /// return @c nullptr. + bool probe(const Coord& xyz, ChildNodeType*& child, ValueType& value, bool& active); + bool probeConst(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const; + bool probe(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const; + //} + //@{ /// @brief Same as probeNode() but, if necessary, update the given accessor with pointers /// to the nodes along the path from the root node to the node containing the coordinate. @@ -736,6 +747,14 @@ class RootNode const NodeT* probeConstNodeAndCache(const Coord& xyz, AccessorT& acc) const; //@} + //@{ + /// @brief Return a pointer to the root child node that contains voxel (x, y, z). + /// If no such node exists, return @c nullptr. + ChildNodeType* probeChild(const Coord& xyz); + const ChildNodeType* probeConstChild(const Coord& xyz) const; + const ChildNodeType* probeChild(const Coord& xyz) const; + //@} + //@{ /// @brief Return a pointer to the leaf node that contains voxel (x, y, z). /// If no such node exists, return @c nullptr. @@ -2786,6 +2805,15 @@ RootNode::probeNode(const Coord& xyz) } +template +template +inline const NodeT* +RootNode::probeNode(const Coord& xyz) const +{ + return this->template probeConstNode(xyz); +} + + template template inline const NodeT* @@ -2804,6 +2832,78 @@ RootNode::probeConstNode(const Coord& xyz) const } +template +inline bool +RootNode::probe(const Coord& xyz, ChildNodeType*& child, ValueType& value, bool& active) +{ + MapIter iter = this->findCoord(xyz); + if (iter == mTable.end()) { + child = nullptr; + return false; + } else if (isChild(iter)) { + child = &getChild(iter); + return true; + } + const Tile& tile = getTile(iter); + child = nullptr; + value = tile.value; + active = tile.active; + return true; +} + + +template +inline bool +RootNode::probeConst(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const +{ + MapCIter iter = this->findCoord(xyz); + if (iter == mTable.end()) { + child = nullptr; + return false; + } else if (isChild(iter)) { + child = &getChild(iter); + return true; + } + const Tile& tile = getTile(iter); + child = nullptr; + value = tile.value; + active = tile.active; + return true; +} + + +template +inline bool +RootNode::probe(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const +{ + return this->probeConst(xyz, child, value, active); +} + + +template +inline ChildT* +RootNode::probeChild(const Coord& xyz) +{ + return this->template probeNode(xyz); +} + + +template +inline const ChildT* +RootNode::probeChild(const Coord& xyz) const +{ + return this->template probeConstNode(xyz); +} + + +template +inline const ChildT* +RootNode::probeConstChild(const Coord& xyz) const +{ + return this->template probeConstNode(xyz); +} + + template inline typename ChildT::LeafNodeType* RootNode::probeLeaf(const Coord& xyz) diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index 16be294068..f0c91b9ff6 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -110,3 +110,120 @@ TEST_F(TestRoot, test) EXPECT_EQ(Index32(5), rootNode3.transientData()); } } + +TEST_F(TestRoot, testProbe) +{ + using RootNode = FloatTree::RootNodeType; + + RootNode root(1.0f); + + root.addTile(Coord(1, 2, 3), 2.0f, true); + root.addTile(Coord(4096, 2, 3), 3.0f, false); + + auto* child = new RootNode::ChildNodeType(Coord(0, 0, 4096), 5.0f, true); + EXPECT_TRUE(root.addChild(child)); // always returns true + + { // probeNode, probeConstNode + auto* node1 = root.probeNode(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node1)); + auto* node2 = root.probeNode(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node2)); + const RootNode& constRoot = root; + auto* node3 = constRoot.probeNode(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node3)); + auto* node4 = constRoot.probeNode(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node4)); + auto* node5 = root.probeConstNode(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node5)); + auto* node6 = root.probeConstNode(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node6)); + } + + { // probeChild, probeConstChild + auto* node1 = root.probeChild(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node1)); + auto* node2 = root.probeChild(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node2)); + const RootNode& constRoot = root; + auto* node3 = constRoot.probeChild(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node3)); + auto* node4 = constRoot.probeChild(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node4)); + auto* node5 = root.probeConstChild(Coord(0, 0, 4096)); + EXPECT_TRUE(bool(node5)); + auto* node6 = root.probeConstChild(Coord(4096, 0, 0)); + EXPECT_FALSE(bool(node6)); + } + + RootNode::ChildNodeType* childPtr = nullptr; + const RootNode::ChildNodeType* constChildPtr = nullptr; + float value = -1.0f; + bool active = false; + + { // probe, probeConst - child + bool keyExists = root.probe(Coord(0, 0, 4096), childPtr, value, active); + EXPECT_TRUE(keyExists); + EXPECT_TRUE(bool(childPtr)); + childPtr = nullptr; + keyExists = root.probe(Coord(0, 10, 4096), childPtr, value, active); + EXPECT_TRUE(keyExists); + EXPECT_TRUE(bool(childPtr)); + childPtr = nullptr; + EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + + const RootNode& constRoot = root; + keyExists = constRoot.probe(Coord(0, 0, 4096), constChildPtr, value, active); + EXPECT_TRUE(keyExists); + EXPECT_TRUE(bool(constChildPtr)); + constChildPtr = nullptr; + EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), constChildPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + + keyExists = root.probeConst(Coord(0, 0, 4096), constChildPtr, value, active); + EXPECT_TRUE(keyExists); + EXPECT_TRUE(bool(constChildPtr)); + constChildPtr = nullptr; + EXPECT_FALSE(root.probeConst(Coord(4096, 4096, 4096), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); + } + + { // probe, probeConst - tile + EXPECT_TRUE(root.probe(Coord(0, 0, 0), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + EXPECT_EQ(value, 2.0f); + EXPECT_EQ(active, true); + value = -1.0f; + EXPECT_TRUE(root.probe(Coord(4096, 0, 0), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + EXPECT_EQ(value, 3.0f); + EXPECT_EQ(active, false); + EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + + const RootNode& constRoot = root; + EXPECT_TRUE(root.probe(Coord(0, 0, 0), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + EXPECT_EQ(value, 2.0f); + EXPECT_EQ(active, true); + value = -1.0f; + EXPECT_TRUE(root.probe(Coord(4096, 0, 0), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + EXPECT_EQ(value, 3.0f); + EXPECT_EQ(active, false); + EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), childPtr, value, active)); + EXPECT_FALSE(bool(childPtr)); + + EXPECT_TRUE(root.probeConst(Coord(0, 0, 0), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); + EXPECT_EQ(value, 2.0f); + EXPECT_EQ(active, true); + value = -1.0f; + EXPECT_TRUE(root.probeConst(Coord(4096, 0, 0), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); + EXPECT_EQ(value, 3.0f); + EXPECT_EQ(active, false); + EXPECT_FALSE(root.probeConst(Coord(4096, 4096, 4096), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); + } +} From 7a79af834485d8aafb62156b11eedc6ef43e73ce Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 17 Oct 2024 16:27:08 -0700 Subject: [PATCH 07/98] Add new InternalNode probe methods Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 151 +++++++++++++++++++ openvdb/openvdb/unittest/TestInternalNode.cc | 138 +++++++++++++++++ 2 files changed, 289 insertions(+) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 7cf653f901..356a3a9e8d 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -620,6 +620,41 @@ class InternalNode /// If no such node exists, return nullptr. template NodeType* probeNode(const Coord& xyz); template const NodeType* probeConstNode(const Coord& xyz) const; + template const NodeType* probeNode(const Coord& xyz) const; + //@} + + //@{ + /// @brief Return a pointer to the child node that contains voxel (x, y, z). + /// If no such node exists, return nullptr. + ChildNodeType* probeChild(const Coord& xyz); + const ChildNodeType* probeConstChild(const Coord& xyz) const; + const ChildNodeType* probeChild(const Coord& xyz) const; + //@} + + //@{ + /// @brief Return a pointer to the child node that contains voxel (x, y, z). + /// If no such node exists, return nullptr. + ChildNodeType* probeChild(const Coord& xyz, ValueType& value, bool& active); + const ChildNodeType* probeConstChild(const Coord& xyz, ValueType& value, bool& active) const; + const ChildNodeType* probeChild(const Coord& xyz, ValueType& value, bool& active) const; + //@} + + //@{ + /// @brief Return a pointer to the child node for a specific offset. + /// If no such node exists, return nullptr. + /// @note Out-of-bounds memory access attempts will wrap around using modulo indexing. + ChildNodeType* probeChild(Index offset); + const ChildNodeType* probeConstChild(Index offset) const; + const ChildNodeType* probeChild(Index offset) const; + //@} + + //@{ + /// @brief Return a pointer to the child node for a specific offset. + /// If no such node exists, return nullptr. + /// @note Out-of-bounds memory access attempts will wrap around using modulo indexing. + ChildNodeType* probeChild(Index offset, ValueType& value, bool& active); + const ChildNodeType* probeConstChild(Index offset, ValueType& value, bool& active) const; + const ChildNodeType* probeChild(Index offset, ValueType& value, bool& active) const; //@} //@{ @@ -1226,6 +1261,15 @@ InternalNode::probeConstNode(const Coord& xyz) const } +template +template +inline const NodeT* +InternalNode::probeNode(const Coord& xyz) const +{ + return this->probeConstNode(xyz); +} + + template template inline const NodeT* @@ -1248,6 +1292,113 @@ InternalNode::probeConstNodeAndCache(const Coord& xyz, Accessor //////////////////////////////////////// +template +inline ChildT* +InternalNode::probeChild(const Coord& xyz) +{ + const Index n = this->coordToOffset(xyz); + return this->probeChild(n); +} + +template +inline const ChildT* +InternalNode::probeConstChild(const Coord& xyz) const +{ + const Index n = this->coordToOffset(xyz); + return this->probeConstChild(n); +} + +template +inline const ChildT* +InternalNode::probeChild(const Coord& xyz) const +{ + return this->probeConstChild(xyz); +} + +template +inline ChildT* +InternalNode::probeChild(const Coord& xyz, ValueType& value, bool& active) +{ + const Index n = this->coordToOffset(xyz); + return this->probeChild(n, value, active); +} + +template +inline const ChildT* +InternalNode::probeConstChild(const Coord& xyz, ValueType& value, bool& active) const +{ + const Index n = this->coordToOffset(xyz); + return this->probeConstChild(n, value, active); +} + +template +inline const ChildT* +InternalNode::probeChild(const Coord& xyz, ValueType& value, bool& active) const +{ + return this->probeConstChild(xyz, value, active); +} + +template +inline ChildT* +InternalNode::probeChild(Index offset) +{ + OPENVDB_ASSERT(offset < NUM_VALUES); + offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index + if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); + return nullptr; +} + +template +inline const ChildT* +InternalNode::probeConstChild(Index offset) const +{ + OPENVDB_ASSERT(offset < NUM_VALUES); + offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index + if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); + return nullptr; +} + +template +inline const ChildT* +InternalNode::probeChild(Index offset) const +{ + return this->probeConstChild(offset); +} + +template +inline ChildT* +InternalNode::probeChild(Index offset, ValueType& value, bool& active) +{ + OPENVDB_ASSERT(offset < NUM_VALUES); + offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index + if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); + value = mNodes[offset].getValue(); + active = mValueMask.isOn(offset); + return nullptr; +} + +template +inline const ChildT* +InternalNode::probeConstChild(Index offset, ValueType& value, bool& active) const +{ + OPENVDB_ASSERT(offset < NUM_VALUES); + offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index + if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); + value = mNodes[offset].getValue(); + active = mValueMask.isOn(offset); + return nullptr; +} + +template +inline const ChildT* +InternalNode::probeChild(Index offset, ValueType& value, bool& active) const +{ + return this->probeConstChild(offset, value, active); +} + +//////////////////////////////////////// + + template inline typename ChildT::LeafNodeType* InternalNode::probeLeaf(const Coord& xyz) diff --git a/openvdb/openvdb/unittest/TestInternalNode.cc b/openvdb/openvdb/unittest/TestInternalNode.cc index 52e3a98258..2a8c5728ed 100644 --- a/openvdb/openvdb/unittest/TestInternalNode.cc +++ b/openvdb/openvdb/unittest/TestInternalNode.cc @@ -120,3 +120,141 @@ TEST_F(TestInternalNode, test) EXPECT_EQ(Index32(5), internalNode3.transientData()); } } + +TEST_F(TestInternalNode, testProbe) +{ + using RootNode = FloatTree::RootNodeType; + using InternalNode = RootNode::ChildNodeType; + + const Coord ijk(0, 0, 4096); + InternalNode internalNode(ijk, 1.0f); + + internalNode.addTile(32, 3.0f, true); // (0, 128, 4096) + internalNode.addTile(33, 4.0f, true); // (0, 128, 4224) + + auto* child = new InternalNode::ChildNodeType(Coord(0, 256, 4096), 5.0f, true); + EXPECT_TRUE(internalNode.addChild(child)); // always returns true + + { // probeNode, probeConstNode + auto* node1 = internalNode.probeNode(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node1)); + auto* node2 = internalNode.probeNode(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node2)); + const InternalNode& constInternalNode = internalNode; + auto* node3 = constInternalNode.probeNode(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node3)); + auto* node4 = constInternalNode.probeNode(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node4)); + auto* node5 = internalNode.probeConstNode(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node5)); + auto* node6 = internalNode.probeConstNode(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node6)); + } + + { // probeChild, probeConstChild - coord access + auto* node1 = internalNode.probeChild(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node1)); + auto* node2 = internalNode.probeChild(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node2)); + const InternalNode& constInternalNode = internalNode; + auto* node3 = constInternalNode.probeChild(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node3)); + auto* node4 = constInternalNode.probeChild(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node4)); + auto* node5 = internalNode.probeConstChild(Coord(0, 256, 4096)); + EXPECT_TRUE(bool(node5)); + auto* node6 = internalNode.probeConstChild(Coord(0, 128, 4096)); + EXPECT_FALSE(bool(node6)); + } + + { // probeChild, probeConstChild - index access + auto* node1 = internalNode.probeChild(64); + EXPECT_TRUE(bool(node1)); + auto* node2 = internalNode.probeChild(33); + EXPECT_FALSE(bool(node2)); + const InternalNode& constInternalNode = internalNode; + auto* node3 = constInternalNode.probeChild(64); + EXPECT_TRUE(bool(node3)); + auto* node4 = constInternalNode.probeChild(33); + EXPECT_FALSE(bool(node4)); + auto* node5 = internalNode.probeConstChild(64); + EXPECT_TRUE(bool(node5)); + auto* node6 = internalNode.probeConstChild(33); + EXPECT_FALSE(bool(node6)); + + // wrap-around modulo indexing + auto* node7 = internalNode.probeConstChild(64 + 32*32*32); + EXPECT_TRUE(bool(node7)); + auto* node8 = internalNode.probeConstChild(33 + 32*32*32); + EXPECT_FALSE(bool(node8)); + } + + float value = -1.0f; + bool active = false; + + { // probeChild, probeConstChild - coord access with value and active status + auto* node1 = internalNode.probeChild(Coord(0, 256, 4096), value, active); + EXPECT_TRUE(bool(node1)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node2 = internalNode.probeChild(Coord(0, 128, 4096), value, active); + EXPECT_FALSE(bool(node2)); + EXPECT_EQ(value, 3.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + const InternalNode& constInternalNode = internalNode; + auto* node3 = constInternalNode.probeChild(Coord(0, 256, 4096), value, active); + EXPECT_TRUE(bool(node3)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node4 = constInternalNode.probeChild(Coord(0, 128, 4096), value, active); + EXPECT_FALSE(bool(node4)); + EXPECT_EQ(value, 3.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + auto* node5 = internalNode.probeConstChild(Coord(0, 256, 4096), value, active); + EXPECT_TRUE(bool(node5)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node6 = internalNode.probeConstChild(Coord(0, 128, 4096), value, active); + EXPECT_FALSE(bool(node6)); + EXPECT_EQ(value, 3.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + } + + { // probeChild, probeConstChild - index access with value and active status + auto* node1 = internalNode.probeChild(64, value, active); + EXPECT_TRUE(bool(node1)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node2 = internalNode.probeChild(33, value, active); + EXPECT_FALSE(bool(node2)); + EXPECT_EQ(value, 4.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + const InternalNode& constInternalNode = internalNode; + auto* node3 = constInternalNode.probeChild(64, value, active); + EXPECT_TRUE(bool(node3)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node4 = constInternalNode.probeChild(33, value, active); + EXPECT_FALSE(bool(node4)); + EXPECT_EQ(value, 4.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + auto* node5 = internalNode.probeConstChild(64, value, active); + EXPECT_TRUE(bool(node5)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node6 = internalNode.probeConstChild(33, value, active); + EXPECT_FALSE(bool(node6)); + EXPECT_EQ(value, 4.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + + // wrap-around modulo indexing + auto* node7 = internalNode.probeConstChild(64 + 32*32*32, value, active); + EXPECT_TRUE(bool(node7)); + EXPECT_EQ(value, -1.0f); + EXPECT_FALSE(active); + auto* node8 = internalNode.probeConstChild(33 + 32*32*32, value, active); + EXPECT_FALSE(bool(node8)); + EXPECT_EQ(value, 4.0f); value = -1.0f; + EXPECT_TRUE(active); active = false; + } +} From bf8b540a25c23ac1ce8f7c9a2c79438b8f556df4 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 17 Oct 2024 11:32:14 -0700 Subject: [PATCH 08/98] Add missing isValueOn()/isValueOff() methods Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 15 ++++++++++++++- openvdb/openvdb/tree/LeafNode.h | 6 +++++- openvdb/openvdb/tree/LeafNodeBool.h | 6 +++++- openvdb/openvdb/tree/LeafNodeMask.h | 6 +++++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 7cf653f901..94ce412008 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -331,7 +331,11 @@ class InternalNode /// Return @c true if the voxel at the given coordinates is active. bool isValueOn(const Coord& xyz) const; /// Return @c true if the voxel at the given offset is active. - bool isValueOn(Index offset) const { return mValueMask.isOn(offset); } + bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } + /// Return @c true if the voxel at the given coordinates is inactive. + bool isValueOff(const Coord& xyz) const; + /// Return @c true if the voxel at the given offset is inactive. + bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOff(offset); } /// Return @c true if this node or any of its child nodes have any active tiles. bool hasActiveTiles() const; @@ -1554,6 +1558,15 @@ InternalNode::isValueOn(const Coord& xyz) const return mNodes[n].getChild()->isValueOn(xyz); } +template +inline bool +InternalNode::isValueOff(const Coord& xyz) const +{ + const Index n = this->coordToOffset(xyz); + if (this->isChildMaskOff(n)) return this->isValueMaskOn(n); + return mNodes[n].getChild()->isValueOff(xyz); +} + template template inline bool diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 93f7927afd..2f1f13044a 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -475,7 +475,11 @@ class LeafNode /// Return @c true if the voxel at the given coordinates is active. bool isValueOn(const Coord& xyz) const {return this->isValueOn(LeafNode::coordToOffset(xyz));} /// Return @c true if the voxel at the given offset is active. - bool isValueOn(Index offset) const { return mValueMask.isOn(offset); } + bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } + /// Return @c true if the voxel at the given coordinates is inactive. + bool isValueOff(const Coord& xyz) const {return this->isValueOff(LeafNode::coordToOffset(xyz));} + /// Return @c true if the voxel at the given offset is inactive. + bool isValueOff(Index offset) const { return mValueMask.isOff(offset); } /// Return @c false since leaf nodes never contain tiles. static bool hasActiveTiles() { return false; } diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index a5290dbbbc..106f921452 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -295,9 +295,13 @@ class LeafNode void setValuesOff() { mValueMask.setOff(); } /// Return @c true if the voxel at the given coordinates is active. - bool isValueOn(const Coord& xyz) const { return mValueMask.isOn(this->coordToOffset(xyz)); } + bool isValueOn(const Coord& xyz) const { return this->isValueOn(this->coordToOffset(xyz)); } /// Return @c true if the voxel at the given offset is active. bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } + /// Return @c true if the voxel at the given coordinates is inactive. + bool isValueOff(const Coord& xyz) const { return this->isValueOff(this->coordToOffset(xyz)); } + /// Return @c true if the voxel at the given offset is inactive. + bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOff(offset); } /// Return @c false since leaf nodes never contain tiles. static bool hasActiveTiles() { return false; } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index d044130ab8..28ec25d8aa 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -277,9 +277,13 @@ class LeafNode void setValuesOff() { mBuffer.mData.setOff(); } /// Return @c true if the voxel at the given coordinates is active. - bool isValueOn(const Coord& xyz) const { return mBuffer.mData.isOn(this->coordToOffset(xyz)); } + bool isValueOn(const Coord& xyz) const { return this->isValueOn(this->coordToOffset(xyz)); } /// Return @c true if the voxel at the given offset is active. bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mBuffer.mData.isOn(offset); } + /// Return @c true if the voxel at the given coordinates is inactive. + bool isValueOff(const Coord& xyz) const { return this->isValueOff(this->coordToOffset(xyz)); } + /// Return @c true if the voxel at the given offset is inactive. + bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mBuffer.mData.isOff(offset); } /// Return @c false since leaf nodes never contain tiles. static bool hasActiveTiles() { return false; } From 11148eb9d1c5d215b4bda7e003b3404d330d9e83 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Fri, 18 Oct 2024 17:00:55 -0700 Subject: [PATCH 09/98] Add missing probeValue(Index, val) methods Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/LeafNodeBool.h | 14 ++++++++++++-- openvdb/openvdb/tree/LeafNodeMask.h | 13 ++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index 106f921452..e3e8c355fa 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -240,6 +240,10 @@ class LeafNode /// @param xyz the coordinates of the voxel to be probed /// @param[out] val the value of the voxel at the given coordinates bool probeValue(const Coord& xyz, bool& val) const; + /// @brief Return @c true if the voxel at the given offset is active. + /// @param offset the linear offset of the voxel to be probed + /// @param[out] val the value of the voxel at the given coordinates + bool probeValue(Index offset, bool& val) const; /// Return the level (0) at which leaf node values reside. static Index getValueLevel(const Coord&) { return LEVEL; } @@ -1192,12 +1196,18 @@ template inline bool LeafNode::probeValue(const Coord& xyz, bool& val) const { - const Index offset = this->coordToOffset(xyz); + return this->probeValue(this->coordToOffset(xyz), val); +} + +template +inline bool +LeafNode::probeValue(Index offset, bool& val) const +{ + OPENVDB_ASSERT(offset < SIZE); val = mBuffer.mData.isOn(offset); return mValueMask.isOn(offset); } - template inline void LeafNode::setValueOn(const Coord& xyz, bool val) diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index 28ec25d8aa..2e92f5d347 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -222,6 +222,10 @@ class LeafNode /// @param xyz the coordinates of the voxel to be probed /// @param[out] val the value of the voxel at the given coordinates bool probeValue(const Coord& xyz, bool& val) const; + /// @brief Return @c true if the voxel at the given offset is active. + /// @param offset the linear offset of the voxel to be probed + /// @param[out] val the value of the voxel at the given coordinates + bool probeValue(Index offset, bool& val) const; /// Return the level (0) at which leaf node values reside. static Index getValueLevel(const Coord&) { return LEVEL; } @@ -1113,7 +1117,14 @@ template inline bool LeafNode::probeValue(const Coord& xyz, bool& val) const { - const Index offset = this->coordToOffset(xyz); + return this->probeValue(this->coordToOffset(xyz), val); +} + + +template +inline bool +LeafNode::probeValue(Index offset, bool& val) const +{ val = mBuffer.mData.isOn(offset); return val; } From ab720f862625d4ec3e146230850fe2421fda3162 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Fri, 18 Oct 2024 17:09:42 -0700 Subject: [PATCH 10/98] Add unsafe methods and unit tests for RootNode, InternalNode and LeafNode(s) Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 228 +++++++++++++++++++ openvdb/openvdb/tree/LeafNode.h | 23 ++ openvdb/openvdb/tree/LeafNodeBool.h | 23 ++ openvdb/openvdb/tree/LeafNodeMask.h | 23 ++ openvdb/openvdb/tree/RootNode.h | 87 +++++++ openvdb/openvdb/unittest/TestInternalNode.cc | 91 ++++++++ openvdb/openvdb/unittest/TestLeaf.cc | 38 ++++ openvdb/openvdb/unittest/TestLeafBool.cc | 38 ++++ openvdb/openvdb/unittest/TestLeafMask.cc | 39 ++++ openvdb/openvdb/unittest/TestRootNode.cc | 33 +++ 10 files changed, 623 insertions(+) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 94ce412008..4c1149a862 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -462,6 +462,79 @@ class InternalNode void readBuffers(std::istream&, const CoordBBox&, bool fromHalf = false); + // + // Unsafe methods + // + // WARNING: For improved performance, these unsafe methods do not check the value or + // child masks. If used incorrectly, at best they will leave the InternalNode in an + // invalid state and at worst cause the application to crash. Always use the safer + // alternative method(s) unless you really know what you're doing. + // Enabling OpenVDB asserts will catch where assumptions are incorrectly invalidated. + + /// @brief Return the tile value at offset. + /// @note Use getValue() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ValueType& getValueUnsafe(Index offset) const; + /// @brief Return the tile value and active state at offset. + /// @note Use getValue() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + bool getValueUnsafe(Index offset, ValueType& value) const; + + /// @brief Return the child node at offset. + /// @note Use probeChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + ChildNodeType* getChildUnsafe(Index offset); + /// @brief Return the child node at offset. + /// @note Use probeConstChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ChildNodeType* getConstChildUnsafe(Index offset) const; + /// @brief Return the child node at offset. + /// @note Use probeChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ChildNodeType* getChildUnsafe(Index offset) const; + + /// @brief Set the tile active state at offset but don't change its value. + /// @note Use setActiveState() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setActiveStateUnsafe(Index offset, bool on); + /// @brief Set the tile value at offset but don't change its value. + /// @note Use setValueOnly() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setValueOnlyUnsafe(Index offset, const ValueType& value); + /// @brief Mark the tile active at offset but don't change its value. + /// @note Use setValueOn() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setValueOnUnsafe(Index offset); + /// @brief Set the tile value at offset and mark the voxel as active. + /// @note Use setValueOn() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setValueOnUnsafe(Index offset, const ValueType& value); + /// @brief Mark the tile inactive at offset but don't change its value. + /// @note Use setValueOff() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setValueOffUnsafe(Index offset); + /// @brief Set the tile value at offset and mark the voxel as inactive. + /// @note Use setValueOff() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setValueOffUnsafe(Index offset, const ValueType& value); + + /// @brief Replace a tile at offset with the given child node. + /// @note Use addChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void setChildUnsafe(Index offset, ChildNodeType* child); + /// @brief Replace a child node at offset with the given child node. + /// @note Use addChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void resetChildUnsafe(Index offset, ChildNodeType* child); + /// @brief Replace a child node at offset with the given value and active state. + /// @note Use addChild() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + ChildNodeType* stealChildUnsafe(Index offset, const ValueType& value, bool active); + /// @brief Delete a child node at offset and replace with the given value and active state. + /// @note Use addTile() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + void deleteChildUnsafe(Index offset, const ValueType& value, bool active); + // // Aux methods // @@ -2285,6 +2358,161 @@ InternalNode::getLastValue() const //////////////////////////////////////// +template +inline const typename ChildT::ValueType& +InternalNode::getValueUnsafe(Index n) const +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + return mNodes[n].getValue(); +} + +template +inline bool +InternalNode::getValueUnsafe(Index n, ValueType& value) const +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + value = mNodes[n].getValue(); + return mValueMask.isOn(n); +} + +template +inline ChildT* +InternalNode::getChildUnsafe(Index n) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOn(n)); + return mNodes[n].getChild(); +} + +template +inline const ChildT* +InternalNode::getConstChildUnsafe(Index n) const +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOn(n)); + return mNodes[n].getChild(); +} + +template +inline const ChildT* +InternalNode::getChildUnsafe(Index n) const +{ + return this->getConstChildUnsafe(n); +} + +template +inline void +InternalNode::setActiveStateUnsafe(Index n, bool on) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mValueMask.set(n, on); +} + +template +inline void +InternalNode::setValueOnlyUnsafe(Index n, const ValueType& value) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mNodes[n].setValue(value); +} + +template +inline void +InternalNode::setValueOnUnsafe(Index n) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mValueMask.setOn(n); +} + +template +inline void +InternalNode::setValueOnUnsafe(Index n, const ValueType& value) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mNodes[n].setValue(value); + mValueMask.setOn(n); +} + +template +inline void +InternalNode::setValueOffUnsafe(Index n) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mValueMask.setOff(n); +} + +template +inline void +InternalNode::setValueOffUnsafe(Index n, const ValueType& value) +{ + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mNodes[n].setValue(value); + mValueMask.setOff(n); +} + +template +inline void +InternalNode::setChildUnsafe(Index n, ChildNodeType* child) +{ + // replace tile with child + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOff(n)); + mNodes[n].setChild(child); + mChildMask.setOn(n); + mValueMask.setOff(n); +} + +template +inline void +InternalNode::resetChildUnsafe(Index n, ChildNodeType* child) +{ + // replace child with child + OPENVDB_ASSERT(child); + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOn(n)); + delete mNodes[n].getChild(); + mNodes[n].setChild(child); +} + +template +inline ChildT* +InternalNode::stealChildUnsafe(Index n, const ValueType& value, bool active) +{ + // replace child with tile (and return child) + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOn(n)); + auto* child = mNodes[n].getChild(); + mChildMask.setOff(n); + mValueMask.set(n, active); + mNodes[n].setValue(value); + return child; +} + +template +inline void +InternalNode::deleteChildUnsafe(Index n, const ValueType& value, bool active) +{ + // replace child with tile (and delete child) + OPENVDB_ASSERT(n < NUM_VALUES); + OPENVDB_ASSERT(mChildMask.isOn(n)); + delete mNodes[n].getChild(); + mChildMask.setOff(n); + mValueMask.set(n, active); + mNodes[n].setValue(value); +} + + +//////////////////////////////////////// + + template inline void InternalNode::negate() diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 2f1f13044a..27dab9d33d 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -829,6 +829,29 @@ class LeafNode /// Return @c true if all of this node's values are inactive. bool isInactive() const { return mValueMask.isOff(); } + // + // Unsafe methods + // + // These methods are not in fact unsafe, but are only offered so that + // the same methods can be called on both internal nodes and leaf nodes. + + /// Return the value of the voxel at the given offset. + const ValueType& getValueUnsafe(Index offset) const { return this->getValue(offset); } + /// Return true if the voxel at the given offset is active and set value. + bool getValueUnsafe(Index offset, ValueType& value) const { return this->probeValue(offset, value); } + /// Set the active state of the voxel at the given offset but don't change its value. + void setActiveStateUnsafe(Index offset, bool on) { this->setActiveState(offset, on); } + /// Set the value of the voxel at the given coordinates but don't change its active state. + void setValueOnlyUnsafe(Index offset, const ValueType& value) { return this->setValueOnly(offset, value); } + /// Mark the voxel at the given offset as active but don't change its value. + void setValueOnUnsafe(Index offset) { this->setValueOn(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOnUnsafe(Index offset, const ValueType& value) { this->setValueOn(offset, value); } + /// Mark the voxel at the given offset as inactive but don't change its value. + void setValueOffUnsafe(Index offset) { this->setValueOff(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOffUnsafe(Index offset, const ValueType& value) { this->setValueOff(offset, value); } + protected: friend class ::TestLeaf; template friend class ::TestLeafIO; diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index e3e8c355fa..b2b83a1f2b 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -465,6 +465,29 @@ class LeafNode /// Return @c true if all of this node's values are inactive. bool isInactive() const { return mValueMask.isOff(); } + // + // Unsafe methods + // + // These methods are not in fact unsafe, but are only offered so that + // the same methods can be called on both internal nodes and leaf nodes. + + /// Return the value of the voxel at the given offset. + const bool& getValueUnsafe(Index offset) const { return this->getValue(offset); } + /// Return true if the voxel at the given offset is active and set value. + bool getValueUnsafe(Index offset, bool& value) const { return this->probeValue(offset, value); } + /// Set the active state of the voxel at the given offset but don't change its value. + void setActiveStateUnsafe(Index offset, bool on) { this->setActiveState(offset, on); } + /// Set the value of the voxel at the given coordinates but don't change its active state. + void setValueOnlyUnsafe(Index offset, const bool& value) { return this->setValueOnly(offset, value); } + /// Mark the voxel at the given offset as active but don't change its value. + void setValueOnUnsafe(Index offset) { this->setValueOn(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOnUnsafe(Index offset, const bool& value) { this->setValueOn(offset, value); } + /// Mark the voxel at the given offset as inactive but don't change its value. + void setValueOffUnsafe(Index offset) { this->setValueOff(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOffUnsafe(Index offset, const bool& value) { this->setValueOff(offset, value); } + void resetBackground(bool oldBackground, bool newBackground); void negate() { mBuffer.mData.toggle(); } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index 2e92f5d347..adc0ea12de 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -448,6 +448,29 @@ class LeafNode /// Return @c true if all of this node's values are inactive. bool isInactive() const { return mBuffer.mData.isOff(); } + // + // Unsafe methods + // + // These methods are not in fact unsafe, but are only offered so that + // the same methods can be called on both internal nodes and leaf nodes. + + /// Return the value of the voxel at the given offset. + const bool& getValueUnsafe(Index offset) const { return this->getValue(offset); } + /// Return true if the voxel at the given offset is active and set value. + bool getValueUnsafe(Index offset, bool& value) const { return this->probeValue(offset, value); } + /// Set the active state of the voxel at the given offset but don't change its value. + void setActiveStateUnsafe(Index offset, bool on) { this->setActiveState(offset, on); } + /// Set the value of the voxel at the given coordinates but don't change its active state. + void setValueOnlyUnsafe(Index offset, const bool& value) { return this->setValueOnly(offset, value); } + /// Mark the voxel at the given offset as active but don't change its value. + void setValueOnUnsafe(Index offset) { this->setValueOn(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOnUnsafe(Index offset, const bool& value) { this->setValueOn(offset, value); } + /// Mark the voxel at the given offset as inactive but don't change its value. + void setValueOffUnsafe(Index offset) { this->setValueOff(offset); } + /// Set the value of the voxel at the given coordinates and mark the voxel as active. + void setValueOffUnsafe(Index offset, const bool& value) { this->setValueOff(offset, value); } + /// @brief no-op since for this template specialization voxel /// values and states are indistinguishable. void resetBackground(bool, bool) {} diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 5eb7794115..9c9fff1b17 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -755,6 +755,35 @@ class RootNode const LeafNodeType* probeLeafAndCache(const Coord& xyz, AccessorT& acc) const; //@} + // + // Unsafe methods + // + // WARNING: For improved performance, these unsafe methods assume that the tile + // or child exists. If used incorrectly, this can cause the application to crash. + // Always use the safer alternative method(s) unless you really know what you're doing. + // Enabling OpenVDB asserts will catch where assumptions are incorrectly invalidated. + + /// @brief Return the tile value at the given coordinate. + /// @note Use cbeginValueAll() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ValueType& getValueUnsafe(const Coord& xyz) const; + /// @brief Return the tile value and active state at the given coordinate. + /// @note Use cbeginValueAll() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + bool getValueUnsafe(const Coord& xyz, ValueType& value) const; + /// @brief Return the child node at the given coordinate. + /// @note Use beginChildAll() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + ChildNodeType* getChildUnsafe(const Coord& xyz); + /// @brief Return the child node at the given coordinate. + /// @note Use cbeginChildAll() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ChildNodeType* getConstChildUnsafe(const Coord& xyz) const; + /// @brief Return the child node at the given coordinate. + /// @note Use cbeginChildAll() for a safer alternative. + /// @warning This method should only be used by experts seeking low-level optimizations. + const ChildNodeType* getChildUnsafe(const Coord& xyz) const; + // // Aux methods @@ -2887,6 +2916,64 @@ RootNode::probeConstNodeAndCache(const Coord& xyz, AccessorT& acc) const //////////////////////////////////////// + +template +inline const typename ChildT::ValueType& +RootNode::getValueUnsafe(const Coord& xyz) const +{ + MapCIter iter = this->findCoord(xyz); + OPENVDB_ASSERT(iter != mTable.end()); + OPENVDB_ASSERT(isTile(iter)); + return getTile(iter).value; +} + + +template +inline bool +RootNode::getValueUnsafe(const Coord& xyz, ValueType& value) const +{ + MapCIter iter = this->findCoord(xyz); + OPENVDB_ASSERT(iter != mTable.end()); + OPENVDB_ASSERT(isTile(iter)); + const Tile& tile = getTile(iter); + value = tile.value; + return tile.active; +} + + +template +inline ChildT* +RootNode::getChildUnsafe(const Coord& xyz) +{ + MapIter iter = this->findCoord(xyz); + OPENVDB_ASSERT(iter != mTable.end()); + OPENVDB_ASSERT(isChild(iter)); + return &getChild(iter); +} + + +template +inline const ChildT* +RootNode::getConstChildUnsafe(const Coord& xyz) const +{ + MapCIter iter = this->findCoord(xyz); + OPENVDB_ASSERT(iter != mTable.end()); + OPENVDB_ASSERT(isChild(iter)); + return &getChild(iter); +} + + +template +inline const ChildT* +RootNode::getChildUnsafe(const Coord& xyz) const +{ + return this->getConstChildUnsafe(xyz); +} + + +//////////////////////////////////////// + + template template inline void diff --git a/openvdb/openvdb/unittest/TestInternalNode.cc b/openvdb/openvdb/unittest/TestInternalNode.cc index 52e3a98258..4212ddf6af 100644 --- a/openvdb/openvdb/unittest/TestInternalNode.cc +++ b/openvdb/openvdb/unittest/TestInternalNode.cc @@ -120,3 +120,94 @@ TEST_F(TestInternalNode, test) EXPECT_EQ(Index32(5), internalNode3.transientData()); } } + +TEST_F(TestInternalNode, testUnsafe) +{ + using RootNode = FloatTree::RootNodeType; + using InternalNode = RootNode::ChildNodeType; + + const Coord ijk(0, 0, 4096); + InternalNode internalNode(ijk, 1.0f); + + internalNode.addTile(32, 3.0f, true); // (0, 128, 4096) + internalNode.addTile(33, 4.0f, false); // (0, 128, 4224) + + auto* child = new InternalNode::ChildNodeType(Coord(0, 256, 4096), 5.0f, true); + EXPECT_TRUE(internalNode.addChild(child)); // always returns true + + { // get value + + EXPECT_EQ(internalNode.getValueUnsafe(32), 3.0f); + EXPECT_EQ(internalNode.getValueUnsafe(33), 4.0f); + + float value = -1.0f; + EXPECT_TRUE(internalNode.getValueUnsafe(32, value)); + EXPECT_EQ(value, 3.0f); value = -1.0f; + EXPECT_FALSE(internalNode.getValueUnsafe(33, value)); + EXPECT_EQ(value, 4.0f); value = -1.0f; + } + + { // set value and active state + EXPECT_TRUE(internalNode.isValueOn(32)); + internalNode.setValueOffUnsafe(32); + EXPECT_TRUE(internalNode.isValueOff(32)); + internalNode.setValueOnUnsafe(32); + EXPECT_TRUE(internalNode.isValueOn(32)); + internalNode.setActiveStateUnsafe(32, false); + EXPECT_TRUE(internalNode.isValueOff(32)); + internalNode.setActiveStateUnsafe(32, true); + EXPECT_TRUE(internalNode.isValueOn(32)); + + internalNode.setValueOnlyUnsafe(32, 5.0f); + EXPECT_EQ(internalNode.getValueUnsafe(32), 5.0f); + EXPECT_TRUE(internalNode.isValueOn(32)); + internalNode.setValueOffUnsafe(32); + EXPECT_TRUE(internalNode.isValueOff(32)); + internalNode.setValueOnUnsafe(32); + EXPECT_TRUE(internalNode.isValueOn(32)); + + internalNode.setValueOnUnsafe(33, 7.0f); + EXPECT_TRUE(internalNode.isValueOn(33)); + EXPECT_EQ(internalNode.getValueUnsafe(33), 7.0f); + internalNode.setValueOffUnsafe(33, 6.0f); + EXPECT_TRUE(internalNode.isValueOff(33)); + EXPECT_EQ(internalNode.getValueUnsafe(33), 6.0f); + } + + { // get child + auto* node1 = internalNode.getChildUnsafe(64); + EXPECT_TRUE(bool(node1)); + const InternalNode& constInternalNode = internalNode; + auto* node2 = constInternalNode.getChildUnsafe(64); + EXPECT_TRUE(bool(node2)); + auto* node3 = internalNode.getConstChildUnsafe(64); + EXPECT_TRUE(bool(node3)); + } + + { // set child + auto* child1 = new InternalNode::ChildNodeType(Coord(0, 128, 0), 8.0f, true); + internalNode.setChildUnsafe(32, child1); + auto* node1 = internalNode.getChildUnsafe(32); + EXPECT_TRUE(node1); + EXPECT_EQ(node1->origin(), Coord(0, 128, 0)); + + auto* child2 = new InternalNode::ChildNodeType(Coord(0, 256, 0), 9.0f, true); + internalNode.resetChildUnsafe(64, child2); + auto* node2 = internalNode.getChildUnsafe(64); + EXPECT_TRUE(node2); + EXPECT_EQ(node2->origin(), Coord(0, 256, 0)); + + auto* child3 = new InternalNode::ChildNodeType(Coord(0, 512, 0), 10.0f, true); + auto* node3 = internalNode.stealChildUnsafe(64, 12.0f, false); + EXPECT_TRUE(node3); + EXPECT_EQ(node3->origin(), Coord(0, 256, 0)); + delete node3; + EXPECT_EQ(internalNode.getValueUnsafe(64), 12.0f); + EXPECT_TRUE(internalNode.isValueOff(64)); + + internalNode.deleteChildUnsafe(32, 13.0f, true); + EXPECT_EQ(internalNode.getValueUnsafe(32), 13.0f); + EXPECT_TRUE(internalNode.isValueOn(32)); + } +} + diff --git a/openvdb/openvdb/unittest/TestLeaf.cc b/openvdb/openvdb/unittest/TestLeaf.cc index 96efa1de71..40521916d4 100644 --- a/openvdb/openvdb/unittest/TestLeaf.cc +++ b/openvdb/openvdb/unittest/TestLeaf.cc @@ -533,3 +533,41 @@ TEST_F(TestLeaf, testTransientData) LeafT leaf3 = leaf; EXPECT_EQ(Index32(5), leaf3.transientData()); } + +TEST_F(TestLeaf, testUnsafe) +{ + using namespace openvdb; + using LeafT = tree::LeafNode; + const Coord origin(-9, -2, -8); + LeafT leaf(origin, 1.0f, false); + + EXPECT_FALSE(leaf.isValueOn(1)); + EXPECT_TRUE(leaf.isValueOff(1)); + EXPECT_EQ(leaf.getValueUnsafe(1), 1.0f); + float value = -1.0f; + EXPECT_FALSE(leaf.getValueUnsafe(1, value)); + EXPECT_EQ(value, 1.0f); value = -1.0f; + + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setValueOnUnsafe(32); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setValueOffUnsafe(32); + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setActiveStateUnsafe(32, true); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setActiveStateUnsafe(32, false); + EXPECT_TRUE(leaf.isValueOff(32)); + + leaf.setValueOnlyUnsafe(32, 5.0f); + EXPECT_EQ(leaf.getValueUnsafe(32), 5.0f); + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setValueOnUnsafe(32); + EXPECT_TRUE(leaf.isValueOn(32)); + + leaf.setValueOnUnsafe(33, 7.0f); + EXPECT_TRUE(leaf.isValueOn(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), 7.0f); + leaf.setValueOffUnsafe(33, 6.0f); + EXPECT_TRUE(leaf.isValueOff(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), 6.0f); +} diff --git a/openvdb/openvdb/unittest/TestLeafBool.cc b/openvdb/openvdb/unittest/TestLeafBool.cc index f215dc5219..6e0aeba603 100644 --- a/openvdb/openvdb/unittest/TestLeafBool.cc +++ b/openvdb/openvdb/unittest/TestLeafBool.cc @@ -653,3 +653,41 @@ TEST_F(TestLeafBool, testTransientData) LeafType leaf3 = leaf; EXPECT_EQ(openvdb::Index32(5), leaf3.transientData()); } + +TEST_F(TestLeafBool, testUnsafe) +{ + using namespace openvdb; + using LeafT = tree::LeafNode; + const Coord origin(-9, -2, -8); + LeafT leaf(origin, true, false); + + EXPECT_FALSE(leaf.isValueOn(1)); + EXPECT_TRUE(leaf.isValueOff(1)); + EXPECT_EQ(leaf.getValueUnsafe(1), true); + bool value = false; + EXPECT_FALSE(leaf.getValueUnsafe(1, value)); + EXPECT_EQ(value, true); value = false; + + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setValueOnUnsafe(32); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setValueOffUnsafe(32); + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setActiveStateUnsafe(32, true); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setActiveStateUnsafe(32, false); + EXPECT_TRUE(leaf.isValueOff(32)); + + leaf.setValueOnlyUnsafe(32, false); + EXPECT_EQ(leaf.getValueUnsafe(32), false); + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setValueOnUnsafe(32); + EXPECT_TRUE(leaf.isValueOn(32)); + + leaf.setValueOnUnsafe(33, false); + EXPECT_TRUE(leaf.isValueOn(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), false); + leaf.setValueOffUnsafe(33, true); + EXPECT_TRUE(leaf.isValueOff(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), true); +} diff --git a/openvdb/openvdb/unittest/TestLeafMask.cc b/openvdb/openvdb/unittest/TestLeafMask.cc index fa7eadba6c..86e59d7b5d 100644 --- a/openvdb/openvdb/unittest/TestLeafMask.cc +++ b/openvdb/openvdb/unittest/TestLeafMask.cc @@ -574,3 +574,42 @@ TEST_F(TestLeafMask, testTransientData) LeafType leaf3 = leaf; EXPECT_EQ(openvdb::Index32(5), leaf3.transientData()); } + +TEST_F(TestLeafMask, testUnsafe) +{ + using namespace openvdb; + using LeafT = tree::LeafNode; + const Coord origin(-9, -2, -8); + LeafT leaf(origin, false, /*dummy=*/false); + + EXPECT_FALSE(leaf.isValueOn(1)); + EXPECT_TRUE(leaf.isValueOff(1)); + EXPECT_EQ(leaf.getValueUnsafe(1), false); + bool value = true; + EXPECT_FALSE(leaf.getValueUnsafe(1, value)); + EXPECT_EQ(value, false); + + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setValueOnUnsafe(32); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setValueOffUnsafe(32); + EXPECT_TRUE(leaf.isValueOff(32)); + leaf.setActiveStateUnsafe(32, true); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setActiveStateUnsafe(32, false); + EXPECT_TRUE(leaf.isValueOff(32)); + + leaf.setValueOnlyUnsafe(32, true); + EXPECT_EQ(leaf.getValueUnsafe(32), true); + EXPECT_TRUE(leaf.isValueOn(32)); + leaf.setValueOffUnsafe(32); + EXPECT_TRUE(leaf.isValueOff(32)); + + leaf.setValueOnUnsafe(33, true); + EXPECT_TRUE(leaf.isValueOn(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), true); + leaf.setValueOffUnsafe(33, false); + EXPECT_TRUE(leaf.isValueOff(33)); + EXPECT_EQ(leaf.getValueUnsafe(33), false); +} + diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index 16be294068..6efe1788b3 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -110,3 +110,36 @@ TEST_F(TestRoot, test) EXPECT_EQ(Index32(5), rootNode3.transientData()); } } + +TEST_F(TestRoot, testUnsafe) +{ + using RootNode = FloatTree::RootNodeType; + + RootNode root(1.0f); + + root.addTile(Coord(1, 2, 3), 2.0f, true); + root.addTile(Coord(4096, 2, 3), 3.0f, false); + + auto* child = new RootNode::ChildNodeType(Coord(0, 0, 4096), 5.0f, true); + EXPECT_TRUE(root.addChild(child)); // always returns true + + { // get value + EXPECT_EQ(root.getValueUnsafe(Coord(1, 2, 3)), 2.0f); + EXPECT_EQ(root.getValueUnsafe(Coord(4096, 2, 3)), 3.0f); + float value = -1.0f; + EXPECT_TRUE(root.getValueUnsafe(Coord(1, 2, 3), value)); + EXPECT_EQ(value, 2.0f); value = -1.0f; + EXPECT_FALSE(root.getValueUnsafe(Coord(4096, 2, 3), value)); + EXPECT_EQ(value, 3.0f); value = -1.0f; + } + + { // get child + auto* node1 = root.getChildUnsafe(Coord(0, 0, 4096)); + EXPECT_TRUE(node1); + const RootNode& constRoot = root; + auto* node2 = root.getChildUnsafe(Coord(0, 0, 4096)); + EXPECT_TRUE(node2); + auto* node3 = root.getConstChildUnsafe(Coord(0, 0, 4096)); + EXPECT_TRUE(node3); + } +} From fb7384b193406f2934215f250397cd3483dc4145 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 17 Oct 2024 17:05:45 -0700 Subject: [PATCH 11/98] Add changes file Signed-off-by: Dan Bailey --- pendingchanges/probe.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 pendingchanges/probe.txt diff --git a/pendingchanges/probe.txt b/pendingchanges/probe.txt new file mode 100644 index 0000000000..0786474ffa --- /dev/null +++ b/pendingchanges/probe.txt @@ -0,0 +1,10 @@ +Improvements: + - Added RootNode::probeChild() const. + - Added RootNode::probeChild() and RootNode::probeConstChild(). + - Added RootNode::probe() and RootNode::probeConst() to query key presence, + child node, value and active state. + - Added InternalNode::probeChild() const. + - Added InternalNode::probeChild() and probeChildConst() with coord access + and optionally value and active state. + - Added InternalNode::probeChild() and probeChildConst() with index access + and optionally value and active state. From 27f67ff5a013fc3da94d210f4f47a50efe03a67a Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 8 Oct 2024 22:30:46 -0700 Subject: [PATCH 12/98] In-place create NodeStruct elements in std::map, avoid re-generating key Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 156 ++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 67 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 0d182b5864..f75e0007ae 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -140,6 +140,7 @@ class RootNode NodeStruct(ChildType& c): child(&c) {} NodeStruct(const Tile& t): child(nullptr), tile(t) {} NodeStruct(const NodeStruct&) = default; + NodeStruct(NodeStruct&&) noexcept = default; NodeStruct& operator=(const NodeStruct&) = default; ~NodeStruct() {} ///< @note doesn't delete child @@ -1077,9 +1078,9 @@ RootNode::RootNode(const RootNode& other, this->initTable(); for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) { - mTable[i->first] = OtherRootT::isTile(i) + mTable.emplace(i->first, OtherRootT::isTile(i) ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile) - : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, foregd, TopologyCopy()))); + : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, foregd, TopologyCopy())))); } } @@ -1108,9 +1109,10 @@ RootNode::RootNode(const RootNode& other, const Tile bgTile(backgd, /*active=*/false), fgTile(backgd, true); this->initTable(); for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) { - mTable[i->first] = OtherRootT::isTile(i) + mTable.emplace(i->first, + OtherRootT::isTile(i) ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile) - : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, TopologyCopy()))); + : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, TopologyCopy())))); } } @@ -1173,11 +1175,11 @@ struct RootNodeCopyHelper if (other.isTile(i)) { // Copy the other node's tile, but convert its value to this node's ValueType. const OtherTile& otherTile = other.getTile(i); - self.mTable[i->first] = NodeStruct( + self.mTable.emplace(i->first, Tile(Local::convertValue(otherTile.value), otherTile.active)); } else { // Copy the other node's child, but convert its values to this node's ValueType. - self.mTable[i->first] = NodeStruct(*(new ChildT(other.getChild(i)))); + self.mTable.emplace(i->first, *(new ChildT(other.getChild(i)))); } } } @@ -1203,8 +1205,8 @@ RootNode::operator=(const RootNode& other) this->initTable(); for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) { - mTable[i->first] = - isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(new ChildT(getChild(i)))); + mTable.emplace(i->first, + isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(new ChildT(getChild(i))))); } } return *this; @@ -1321,8 +1323,8 @@ inline typename RootNode::MapIter RootNode::findOrAddCoord(const Coord& xyz) { const Coord key = coordToKey(xyz); - std::pair result = mTable.insert( - typename MapType::value_type(key, NodeStruct(Tile(mBackground, /*active=*/false)))); + std::pair result = mTable.try_emplace(key, + Tile(mBackground, /*active=*/false)); return result.first; } @@ -1332,8 +1334,8 @@ inline bool RootNode::expand(const Coord& xyz) { const Coord key = coordToKey(xyz); - std::pair result = mTable.insert( - typename MapType::value_type(key, NodeStruct(Tile(mBackground, /*active=*/false)))); + std::pair result = mTable.try_emplace(key, + Tile(mBackground, /*active=*/false)); return result.second; // return true if the key did not already exist } @@ -1790,11 +1792,12 @@ inline void RootNode::setActiveState(const Coord& xyz, bool on) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (on) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else { // Nothing to do; (x, y, z) is background and therefore already inactive. } @@ -1813,11 +1816,12 @@ inline void RootNode::setActiveStateAndCache(const Coord& xyz, bool on, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (on) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else { // Nothing to do; (x, y, z) is background and therefore already inactive. } @@ -1839,11 +1843,12 @@ inline void RootNode::setValueOff(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (!math::isExactlyEqual(mBackground, value)) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } } else if (isChild(iter)) { child = &getChild(iter); @@ -1860,11 +1865,12 @@ inline void RootNode::setValueOffAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (!math::isExactlyEqual(mBackground, value)) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } } else if (isChild(iter)) { child = &getChild(iter); @@ -1884,10 +1890,11 @@ inline void RootNode::setValueOn(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else if (isTileOff(iter) || !math::isExactlyEqual(getTile(iter).value, value)) { @@ -1903,10 +1910,11 @@ inline void RootNode::setValueAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else if (isTileOff(iter) || !math::isExactlyEqual(getTile(iter).value, value)) { @@ -1925,10 +1933,11 @@ inline void RootNode::setValueOnly(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else if (!math::isExactlyEqual(getTile(iter).value, value)) { @@ -1944,10 +1953,11 @@ inline void RootNode::setValueOnlyAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else if (!math::isExactlyEqual(getTile(iter).value, value)) { @@ -1967,10 +1977,11 @@ inline void RootNode::modifyValue(const Coord& xyz, const ModifyOp& op) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -1999,10 +2010,11 @@ inline void RootNode::modifyValueAndCache(const Coord& xyz, const ModifyOp& op, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -2035,10 +2047,11 @@ inline void RootNode::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -2063,10 +2076,11 @@ RootNode::modifyValueAndActiveStateAndCache( const Coord& xyz, const ModifyOp& op, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -2154,13 +2168,13 @@ RootNode::fill(const CoordBBox& bbox, const ValueType& value, bool activ // No child or tile exists. Create a child and initialize it // with the background value. child = new ChildT(xyz, mBackground); - mTable[tileMin] = NodeStruct(*child); + mTable.emplace(tileMin, *child); } else if (isTile(iter)) { // Replace the tile with a newly-created child that is filled // with the tile's value and active state. const Tile& tile = getTile(iter); child = new ChildT(xyz, tile.value, tile.active); - mTable[tileMin] = NodeStruct(*child); + mTable.emplace(tileMin, *child); } else if (isChild(iter)) { child = &getChild(iter); } @@ -2394,14 +2408,14 @@ RootNode::readTopology(std::istream& is, bool fromHalf) // Read in and insert a child node. ChildT* child = new ChildT(PartialCreate(), origin, mBackground); child->readTopology(is); - mTable[origin] = NodeStruct(*child); + mTable.emplace(origin, *child); } else { // Read in a tile value and insert a tile, but only if the value // is either active or non-background. ValueType value; is.read(reinterpret_cast(&value), sizeof(ValueType)); if (valueMask.isOn(i) || (!math::isApproxEqual(value, mBackground))) { - mTable[origin] = NodeStruct(Tile(value, valueMask.isOn(i))); + mTable.emplace(origin, Tile(value, valueMask.isOn(i))); } } } @@ -2428,7 +2442,7 @@ RootNode::readTopology(std::istream& is, bool fromHalf) is.read(reinterpret_cast(vec), 3 * sizeof(Int32)); is.read(reinterpret_cast(&value), sizeof(ValueType)); is.read(reinterpret_cast(&active), sizeof(bool)); - mTable[Coord(vec)] = NodeStruct(Tile(value, active)); + mTable.emplace(Coord(vec), Tile(value, active)); } // Read child nodes. @@ -2437,7 +2451,7 @@ RootNode::readTopology(std::istream& is, bool fromHalf) Coord origin(vec); ChildT* child = new ChildT(PartialCreate(), origin, mBackground); child->readTopology(is, fromHalf); - mTable[Coord(vec)] = NodeStruct(*child); + mTable.emplace(Coord(vec), *child); } return true; // not empty @@ -2575,14 +2589,15 @@ RootNode::addLeaf(LeafNodeType* leaf) if (leaf == nullptr) return; ChildT* child = nullptr; const Coord& xyz = leaf->origin(); - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (ChildT::LEVEL>0) { child = new ChildT(xyz, mBackground, false); } else { child = reinterpret_cast(leaf); } - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { if (ChildT::LEVEL>0) { child = &getChild(iter); @@ -2610,14 +2625,15 @@ RootNode::addLeafAndCache(LeafNodeType* leaf, AccessorT& acc) if (leaf == nullptr) return; ChildT* child = nullptr; const Coord& xyz = leaf->origin(); - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (ChildT::LEVEL>0) { child = new ChildT(xyz, mBackground, false); } else { child = reinterpret_cast(leaf); } - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { if (ChildT::LEVEL>0) { child = &getChild(iter); @@ -2643,9 +2659,10 @@ RootNode::addChild(ChildT* child) { if (!child) return false; const Coord& xyz = child->origin(); - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else {//child or tile setChild(iter, *child);//this also deletes the existing child node } @@ -2668,9 +2685,10 @@ template inline void RootNode::addTile(const Coord& xyz, const ValueType& value, bool state) { - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background - mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state)); + mTable.emplace(key, Tile(value, state)); } else {//child or tile setTile(iter, Tile(value, state));//this also deletes the existing child node } @@ -2682,14 +2700,15 @@ RootNode::addTile(Index level, const Coord& xyz, const ValueType& value, bool state) { if (LEVEL >= level) { - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background if (LEVEL > level) { ChildT* child = new ChildT(xyz, mBackground, false); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); child->addTile(level, xyz, value, state); } else { - mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state)); + mTable.emplace(key, Tile(value, state)); } } else if (isChild(iter)) {//child if (LEVEL > level) { @@ -2717,15 +2736,16 @@ RootNode::addTileAndCache(Index level, const Coord& xyz, const ValueType bool state, AccessorT& acc) { if (LEVEL >= level) { - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background if (LEVEL > level) { ChildT* child = new ChildT(xyz, mBackground, false); acc.insert(xyz, child); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); child->addTileAndCache(level, xyz, value, state, acc); } else { - mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state)); + mTable.emplace(key, Tile(value, state)); } } else if (isChild(iter)) {//child if (LEVEL > level) { @@ -2757,10 +2777,11 @@ inline typename ChildT::LeafNodeType* RootNode::touchLeaf(const Coord& xyz) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground, false); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -2777,10 +2798,11 @@ inline typename ChildT::LeafNodeType* RootNode::touchLeafAndCache(const Coord& xyz, AccessorT& acc) { ChildT* child = nullptr; - MapIter iter = this->findCoord(xyz); + Coord key = this->coordToKey(xyz); + MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground, false); - mTable[this->coordToKey(xyz)] = NodeStruct(*child); + mTable.emplace(key, *child); } else if (isChild(iter)) { child = &getChild(iter); } else { @@ -3021,7 +3043,7 @@ RootNode::merge(RootNode& other) if (j == mTable.end()) { // insert other node's child ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); child.resetBackground(other.mBackground, mBackground); - mTable[i->first] = NodeStruct(child); + mTable.emplace(i->first, child); } else if (isTile(j)) { if (isTileOff(j)) { // replace inactive tile with other node's child ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); @@ -3034,7 +3056,7 @@ RootNode::merge(RootNode& other) } } else if (other.isTileOn(i)) { if (j == mTable.end()) { // insert other node's active tile - mTable[i->first] = i->second; + mTable.emplace(i->first, i->second); } else if (!isTileOn(j)) { // Replace anything except an active tile with the other node's active tile. setTile(j, Tile(other.getTile(i).value, true)); @@ -3050,7 +3072,7 @@ RootNode::merge(RootNode& other) if (j == mTable.end()) { // insert other node's child ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); child.resetBackground(other.mBackground, mBackground); - mTable[i->first] = NodeStruct(child); + mTable.emplace(i->first, child); } else if (isTile(j)) { // replace tile with other node's child ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); child.resetBackground(other.mBackground, mBackground); @@ -3071,7 +3093,7 @@ RootNode::merge(RootNode& other) // Steal and insert the other node's child. ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); child.resetBackground(other.mBackground, mBackground); - mTable[i->first] = NodeStruct(child); + mTable.emplace(i->first, child); } else if (isTile(j)) { // Replace this node's tile with the other node's child. ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false)); @@ -3091,7 +3113,7 @@ RootNode::merge(RootNode& other) } else if (other.isTileOn(i)) { if (j == mTable.end()) { // Insert a copy of the other node's active tile. - mTable[i->first] = i->second; + mTable.emplace(i->first, i->second); } else if (isTileOff(j)) { // Replace this node's inactive tile with a copy of the other's active tile. setTile(j, Tile(other.getTile(i).value, true)); @@ -3130,7 +3152,7 @@ RootNode::topologyUnion(const RootNode& other, const boo MapIter j = mTable.find(i->first); if (other.isChild(i)) { if (j == mTable.end()) { // create child branch with identical topology - mTable[i->first] = NodeStruct( + mTable.emplace(i->first, *(new ChildT(other.getChild(i), mBackground, TopologyCopy()))); } else if (this->isChild(j)) { // union with child branch this->getChild(j).topologyUnion(other.getChild(i), preserveTiles); @@ -3144,7 +3166,7 @@ RootNode::topologyUnion(const RootNode& other, const boo } } else if (other.isTileOn(i)) { // other is an active tile if (j == mTable.end()) { // insert an active tile - mTable[i->first] = NodeStruct(Tile(mBackground, true)); + mTable.emplace(i->first, Tile(mBackground, true)); } else if (this->isChild(j)) { this->getChild(j).setValuesOn(); } else if (this->isTileOff(j)) { From f9431666b067bd0ba6cf5b4db6dddcd1aee511e4 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 15:51:42 -0700 Subject: [PATCH 13/98] Update changes Signed-off-by: Dan Bailey --- pendingchanges/root_node_emplace.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 pendingchanges/root_node_emplace.txt diff --git a/pendingchanges/root_node_emplace.txt b/pendingchanges/root_node_emplace.txt new file mode 100644 index 0000000000..ebe67c570d --- /dev/null +++ b/pendingchanges/root_node_emplace.txt @@ -0,0 +1,2 @@ +Improvements: + - Small optimizations to RootNode to eliminate redundant key conversion and to create map values in-place. \ No newline at end of file From cb6f134b9dcdc14fdbfc1b404a4068f720259d73 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 21:46:53 -0700 Subject: [PATCH 14/98] Fix a compiler warning Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 1 - 1 file changed, 1 deletion(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index f75e0007ae..31e2053750 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -1148,7 +1148,6 @@ struct RootNodeCopyHelper { using ValueT = typename RootT::ValueType; using ChildT = typename RootT::ChildNodeType; - using NodeStruct = typename RootT::NodeStruct; using Tile = typename RootT::Tile; using OtherValueT = typename OtherRootT::ValueType; using OtherMapCIter = typename OtherRootT::MapCIter; From f9a34cb5662733c2adf0c9e1c63ea2fbbb010128 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Mon, 21 Oct 2024 15:50:05 -0700 Subject: [PATCH 15/98] Fix a const test Signed-off-by: Dan Bailey --- openvdb/openvdb/unittest/TestRootNode.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index f0c91b9ff6..4af727e084 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -202,17 +202,17 @@ TEST_F(TestRoot, testProbe) EXPECT_FALSE(bool(childPtr)); const RootNode& constRoot = root; - EXPECT_TRUE(root.probe(Coord(0, 0, 0), childPtr, value, active)); - EXPECT_FALSE(bool(childPtr)); + EXPECT_TRUE(constRoot.probe(Coord(0, 0, 0), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); EXPECT_EQ(value, 2.0f); EXPECT_EQ(active, true); value = -1.0f; - EXPECT_TRUE(root.probe(Coord(4096, 0, 0), childPtr, value, active)); - EXPECT_FALSE(bool(childPtr)); + EXPECT_TRUE(root.probe(Coord(4096, 0, 0), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); EXPECT_EQ(value, 3.0f); EXPECT_EQ(active, false); - EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), childPtr, value, active)); - EXPECT_FALSE(bool(childPtr)); + EXPECT_FALSE(root.probe(Coord(4096, 4096, 4096), constChildPtr, value, active)); + EXPECT_FALSE(bool(constChildPtr)); EXPECT_TRUE(root.probeConst(Coord(0, 0, 0), constChildPtr, value, active)); EXPECT_FALSE(bool(constChildPtr)); From 37615a0818e6874116c043adb5b6bec1e448068a Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Fri, 18 Oct 2024 17:24:05 -0700 Subject: [PATCH 16/98] Add changes file Signed-off-by: Dan Bailey --- pendingchanges/unsafe.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 pendingchanges/unsafe.txt diff --git a/pendingchanges/unsafe.txt b/pendingchanges/unsafe.txt new file mode 100644 index 0000000000..9264bf36fd --- /dev/null +++ b/pendingchanges/unsafe.txt @@ -0,0 +1,16 @@ +Improvements: + - Added InternalNode::isValueOff(), LeafNode::isValueOff(), + LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). + - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). + - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), + RootNode::getConstChildUnsafe(). + - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), + InternalNode::getConstChildUnsafe(). + - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), + InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). + - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), + InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). + - For LeafNode, LeafNodeBool and LeafNodeMask - added + LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), + LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), + LeafNode::setValueOffUnsafe(). From e591925cac691dc779b49600b17e007c6c59aac7 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Mon, 21 Oct 2024 15:53:31 -0700 Subject: [PATCH 17/98] Fix a compiler warning Signed-off-by: Dan Bailey --- openvdb/openvdb/unittest/TestInternalNode.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/openvdb/openvdb/unittest/TestInternalNode.cc b/openvdb/openvdb/unittest/TestInternalNode.cc index 4212ddf6af..f00ba1bdea 100644 --- a/openvdb/openvdb/unittest/TestInternalNode.cc +++ b/openvdb/openvdb/unittest/TestInternalNode.cc @@ -197,7 +197,6 @@ TEST_F(TestInternalNode, testUnsafe) EXPECT_TRUE(node2); EXPECT_EQ(node2->origin(), Coord(0, 256, 0)); - auto* child3 = new InternalNode::ChildNodeType(Coord(0, 512, 0), 10.0f, true); auto* node3 = internalNode.stealChildUnsafe(64, 12.0f, false); EXPECT_TRUE(node3); EXPECT_EQ(node3->origin(), Coord(0, 256, 0)); From 946952bb9ae42081f6227a4f61117ebe6b3af2aa Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Wed, 23 Oct 2024 14:03:21 +1300 Subject: [PATCH 18/98] Add libpdal back to vpckg's in isntall_windows.ps1 Signed-off-by: Jonathan Swartz --- ci/install_windows.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/install_windows.ps1 b/ci/install_windows.ps1 index 6054cb96bf..d412821ef5 100644 --- a/ci/install_windows.ps1 +++ b/ci/install_windows.ps1 @@ -6,6 +6,7 @@ $VerbosePreference = "Continue" $vcpkgPackages = @( "zlib", "libpng", + "libpdal", "openexr", "tbb", "gtest", From 581b5d283faa541075379de43e83dca3deda73ee Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Wed, 23 Oct 2024 14:29:24 +1300 Subject: [PATCH 19/98] Whitespace fix Signed-off-by: Jonathan Swartz --- openvdb_cmd/vdb_tool/include/Geometry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb_cmd/vdb_tool/include/Geometry.h b/openvdb_cmd/vdb_tool/include/Geometry.h index 56b7ae5ebc..2e3f93c62e 100644 --- a/openvdb_cmd/vdb_tool/include/Geometry.h +++ b/openvdb_cmd/vdb_tool/include/Geometry.h @@ -557,7 +557,7 @@ void Geometry::readPLY(std::istream &is) if (!test(0, {"ply"})) error("vdb_tool::readPLY: not a ply file"); int format = -1;// 0 is ascii, 1 is little endian and 2 is big endian - tokens = tokenize_line(); + tokens = tokenize_line(); if (!(test(0, {"format"}) && test(2, {"1.0"})) ) { error("vdb_tool::readPLY: expected format version 1.0"); } else if (test(1, {"ascii"})) { From 7cb47d8626680a1fc6f12a686e298875080f534c Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 23 Oct 2024 10:27:57 -0700 Subject: [PATCH 20/98] Fix a compiler warning Signed-off-by: Dan Bailey --- openvdb/openvdb/unittest/TestRootNode.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index 6efe1788b3..8b361009b1 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -137,7 +137,7 @@ TEST_F(TestRoot, testUnsafe) auto* node1 = root.getChildUnsafe(Coord(0, 0, 4096)); EXPECT_TRUE(node1); const RootNode& constRoot = root; - auto* node2 = root.getChildUnsafe(Coord(0, 0, 4096)); + auto* node2 = constRoot.getChildUnsafe(Coord(0, 0, 4096)); EXPECT_TRUE(node2); auto* node3 = root.getConstChildUnsafe(Coord(0, 0, 4096)); EXPECT_TRUE(node3); From da7c454b2afada81694dbf94c6a781a8c7d6a5b5 Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Thu, 24 Oct 2024 10:18:44 +1300 Subject: [PATCH 21/98] Fix pdal Windows package name. Fix linux build warnings causing errors. Signed-off-by: Jonathan Swartz --- ci/install_windows.ps1 | 2 +- openvdb_cmd/vdb_tool/include/Geometry.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ci/install_windows.ps1 b/ci/install_windows.ps1 index d412821ef5..ce8d908951 100644 --- a/ci/install_windows.ps1 +++ b/ci/install_windows.ps1 @@ -6,8 +6,8 @@ $VerbosePreference = "Continue" $vcpkgPackages = @( "zlib", "libpng", - "libpdal", "openexr", + "pdal", "tbb", "gtest", "cppunit", diff --git a/openvdb_cmd/vdb_tool/include/Geometry.h b/openvdb_cmd/vdb_tool/include/Geometry.h index 2e3f93c62e..2d6472dcde 100644 --- a/openvdb_cmd/vdb_tool/include/Geometry.h +++ b/openvdb_cmd/vdb_tool/include/Geometry.h @@ -513,6 +513,8 @@ void Geometry::readPDAL(const std::string &fileName) catch (const std::exception& e) { throw std::runtime_error("Reading file failed: " + std::string(e.what())); } +#else + throw std::runtime_error("Cannot read file \"" + fileName + "\". PDAL support is not enabled in this build, please recompile with PDAL support"); #endif mBBox = BBoxT(); //invalidate BBox }// Geometry::readPDAL @@ -829,7 +831,6 @@ void Geometry::readPTS(const std::string &fileName) std::string line; std::istringstream iss; bool readColor = false; - int i = 0; Vec3s rgb; while(std::getline(infile, line)) { const size_t n = mVtx.size(), m = std::stoi(line); From 187cb1a76e419e0d0ad57d1622e7a5188b5c2453 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:12:37 -0400 Subject: [PATCH 22/98] leafCount and friends work with Index64 leafCount, unallocatedLeafCount, nodeCount now work with Index64 to accommodate trees with more than 2^32-1 leaf nodes. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- CMakeLists.txt | 2 +- openvdb/openvdb/io/Archive.cc | 4 +- openvdb/openvdb/points/IndexFilter.h | 2 +- openvdb/openvdb/python/pyGrid.h | 2 +- openvdb/openvdb/tree/InternalNode.h | 10 +- openvdb/openvdb/tree/LeafNode.h | 4 +- openvdb/openvdb/tree/LeafNodeBool.h | 4 +- openvdb/openvdb/tree/LeafNodeMask.h | 4 +- openvdb/openvdb/tree/RootNode.h | 12 +- openvdb/openvdb/tree/Tree.h | 18 +-- openvdb/openvdb/unittest/TestFile.cc | 2 +- openvdb/openvdb/unittest/TestFilter.cc | 36 ++--- openvdb/openvdb/unittest/TestGrid.cc | 12 +- openvdb/openvdb/unittest/TestIndexFilter.cc | 6 +- openvdb/openvdb/unittest/TestLeaf.cc | 2 +- openvdb/openvdb/unittest/TestLevelSetUtil.cc | 12 +- openvdb/openvdb/unittest/TestMerge.cc | 96 +++++++------- openvdb/openvdb/unittest/TestMorphology.cc | 30 ++--- openvdb/openvdb/unittest/TestNodeManager.cc | 8 +- openvdb/openvdb/unittest/TestNodeVisitor.cc | 16 +-- .../openvdb/unittest/TestPointAttribute.cc | 6 +- openvdb/openvdb/unittest/TestPointCount.cc | 4 +- openvdb/openvdb/unittest/TestPointDataLeaf.cc | 2 +- openvdb/openvdb/unittest/TestPointGroup.cc | 4 +- openvdb/openvdb/unittest/TestPointMove.cc | 2 +- .../openvdb/unittest/TestPointRasterizeSDF.cc | 20 +-- openvdb/openvdb/unittest/TestPointScatter.cc | 76 +++++------ openvdb/openvdb/unittest/TestTools.cc | 14 +- openvdb/openvdb/unittest/TestTree.cc | 125 +++++++++--------- .../openvdb/unittest/TestTreeGetSetValues.cc | 38 +++--- openvdb/openvdb/unittest/TestValueAccessor.cc | 9 +- 31 files changed, 292 insertions(+), 290 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 230539d88d..75d895f39d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ include(GNUInstallDirs) 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_UNITTESTS "Build the OpenVDB unit tests" ON) 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) diff --git a/openvdb/openvdb/io/Archive.cc b/openvdb/openvdb/io/Archive.cc index 39e79c86ca..8f99565f20 100644 --- a/openvdb/openvdb/io/Archive.cc +++ b/openvdb/openvdb/io/Archive.cc @@ -357,10 +357,10 @@ struct PopulateDelayedLoadMetadataOp using MaskT = typename LeafT::NodeMaskType; const TreeT& tree = grid.constTree(); - const Index32 leafCount = tree.leafCount(); + const Index64 leafCount = tree.leafCount(); // early exit if not leaf nodes - if (leafCount == Index32(0)) return; + if (leafCount == Index64(0)) return; metadata.resizeMask(leafCount); diff --git a/openvdb/openvdb/points/IndexFilter.h b/openvdb/openvdb/points/IndexFilter.h index 28e2dc9c47..9f0e57d708 100644 --- a/openvdb/openvdb/points/IndexFilter.h +++ b/openvdb/openvdb/points/IndexFilter.h @@ -245,7 +245,7 @@ class RandomLeafFilter std::mt19937 generator(seed); std::uniform_int_distribution dist(0, std::numeric_limits::max() - 1); - Index32 leafCounter = 0; + Index64 leafCounter = 0; float totalPointsFloat = 0.0f; int totalPoints = 0; for (auto iter = tree.cbeginLeaf(); iter; ++iter) { diff --git a/openvdb/openvdb/python/pyGrid.h b/openvdb/openvdb/python/pyGrid.h index 4592ea42ac..c6fe8ab1d9 100644 --- a/openvdb/openvdb/python/pyGrid.h +++ b/openvdb/openvdb/python/pyGrid.h @@ -213,7 +213,7 @@ treeDepth(const GridType& grid) template -inline Index32 +inline Index64 leafCount(const GridType& grid) { return grid.tree().leafCount(); diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 46fef2d96d..08ccc7cc68 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -274,8 +274,8 @@ class InternalNode /// Set the transient data value. void setTransientData(Index32 transientData) { mTransientData = transientData; } - Index32 leafCount() const; - void nodeCount(std::vector &vec) const; + Index64 leafCount() const; + void nodeCount(std::vector &vec) const; Index32 nonLeafCount() const; Index32 childCount() const; Index64 onVoxelCount() const; @@ -988,11 +988,11 @@ InternalNode::~InternalNode() template -inline Index32 +inline Index64 InternalNode::leafCount() const { if (ChildNodeType::getLevel() == 0) return mChildMask.countOn(); - Index32 sum = 0; + Index64 sum = 0; for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { sum += iter->leafCount(); } @@ -1001,7 +1001,7 @@ InternalNode::leafCount() const template inline void -InternalNode::nodeCount(std::vector &vec) const +InternalNode::nodeCount(std::vector &vec) const { OPENVDB_ASSERT(vec.size() > ChildNodeType::LEVEL); const auto count = mChildMask.countOn(); diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index b1304e8ded..89d04e9f23 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -129,9 +129,9 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. - static Index32 leafCount() { return 1; } + static Index64 leafCount() { return 1; } /// no-op - void nodeCount(std::vector &) const {} + void nodeCount(std::vector &) const {} /// Return the non-leaf count for this node, which is zero. static Index32 nonLeafCount() { return 0; } /// Return the child count for this node, which is zero. diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index 63dd477bd0..cf990f846b 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -131,9 +131,9 @@ class LeafNode static void getNodeLog2Dims(std::vector& dims) { dims.push_back(Log2Dim); } static Index getChildDim() { return 1; } - static Index32 leafCount() { return 1; } + static Index64 leafCount() { return 1; } /// no-op - void nodeCount(std::vector &) const {} + void nodeCount(std::vector &) const {} static Index32 nonLeafCount() { return 0; } /// Return the number of active voxels. diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index bedf229b35..df28099cc5 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -112,9 +112,9 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. - static Index32 leafCount() { return 1; } + static Index64 leafCount() { return 1; } /// no-op - void nodeCount(std::vector &) const {} + void nodeCount(std::vector &) const {} /// Return the non-leaf count for this node, which is zero. static Index32 nonLeafCount() { return 0; } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 0aca129889..c534ae0c90 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -483,7 +483,7 @@ class RootNode template static bool hasCompatibleValueType(const RootNode& other); - Index32 leafCount() const; + Index64 leafCount() const; Index32 nonLeafCount() const; Index32 childCount() const; Index64 onVoxelCount() const; @@ -491,7 +491,7 @@ class RootNode Index64 onLeafVoxelCount() const; Index64 offLeafVoxelCount() const; Index64 onTileCount() const; - void nodeCount(std::vector &vec) const; + void nodeCount(std::vector &vec) const; bool isValueOn(const Coord& xyz) const; @@ -1567,10 +1567,10 @@ RootNode::getInactiveTileCount() const template -inline Index32 +inline Index64 RootNode::leafCount() const { - Index32 sum = 0; + Index64 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { if (isChild(i)) sum += getChild(i).leafCount(); } @@ -1676,10 +1676,10 @@ RootNode::onTileCount() const template inline void -RootNode::nodeCount(std::vector &vec) const +RootNode::nodeCount(std::vector &vec) const { OPENVDB_ASSERT(vec.size() > LEVEL); - Index32 sum = 0; + Index64 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { if (isChild(i)) { ++sum; diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index 06f8278827..22799f3cf1 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -102,7 +102,7 @@ class OPENVDB_API TreeBase /// @sa readNonresidentBuffers, io::File::open virtual void clipUnallocatedNodes() = 0; /// Return the total number of unallocated leaf nodes residing in this tree. - virtual Index32 unallocatedLeafCount() const = 0; + virtual Index64 unallocatedLeafCount() const = 0; // @@ -113,11 +113,11 @@ class OPENVDB_API TreeBase /// A tree with only a root node and leaf nodes has depth 2, for example. virtual Index treeDepth() const = 0; /// Return the number of leaf nodes. - virtual Index32 leafCount() const = 0; + virtual Index64 leafCount() const = 0; /// Return a vector with node counts. The number of nodes of type NodeType /// is given as element NodeType::LEVEL in the return vector. Thus, the size /// of this vector corresponds to the height (or depth) of this tree. - virtual std::vector nodeCount() const = 0; + virtual std::vector nodeCount() const = 0; /// Return the number of non-leaf nodes. virtual Index32 nonLeafCount() const = 0; /// Return the number of active voxels stored in leaf nodes. @@ -343,13 +343,13 @@ class Tree: public TreeBase /// A tree with only a root node and leaf nodes has depth 2, for example. Index treeDepth() const override { return DEPTH; } /// Return the number of leaf nodes. - Index32 leafCount() const override { return mRoot.leafCount(); } + Index64 leafCount() const override { return mRoot.leafCount(); } /// Return a vector with node counts. The number of nodes of type NodeType /// is given as element NodeType::LEVEL in the return vector. Thus, the size /// of this vector corresponds to the height (or depth) of this tree. - std::vector nodeCount() const override + std::vector nodeCount() const override { - std::vector vec(DEPTH, 0); + std::vector vec(DEPTH, 0); mRoot.nodeCount( vec ); return vec;// Named Return Value Optimization } @@ -469,7 +469,7 @@ class Tree: public TreeBase void clipUnallocatedNodes() override; /// Return the total number of unallocated leaf nodes residing in this tree. - Index32 unallocatedLeafCount() const override; + Index64 unallocatedLeafCount() const override; //@{ /// @brief Set all voxels within a given axis-aligned box to a constant value. @@ -1674,10 +1674,10 @@ Tree::clipUnallocatedNodes() } template -inline Index32 +inline Index64 Tree::unallocatedLeafCount() const { - Index32 sum = 0; + Index64 sum = 0; for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum; return sum; } diff --git a/openvdb/openvdb/unittest/TestFile.cc b/openvdb/openvdb/unittest/TestFile.cc index c5d4d85d9a..dd344cb515 100644 --- a/openvdb/openvdb/unittest/TestFile.cc +++ b/openvdb/openvdb/unittest/TestFile.cc @@ -1866,7 +1866,7 @@ TEST_F(TestFile, testMultiPassIO) file.open(); const auto newGrid = GridBase::grid( file.readGrid("test", BBoxd(Vec3d(0), Vec3d(1)))); - EXPECT_EQ(Index32(1), newGrid->tree().leafCount()); + EXPECT_EQ(Index64(1), newGrid->tree().leafCount()); auto leafIter = newGrid->tree().beginLeaf(); EXPECT_EQ(3, int(leafIter->mReadPasses.size())); diff --git a/openvdb/openvdb/unittest/TestFilter.cc b/openvdb/openvdb/unittest/TestFilter.cc index 0d3006f56c..12f9cdedd6 100644 --- a/openvdb/openvdb/unittest/TestFilter.cc +++ b/openvdb/openvdb/unittest/TestFilter.cc @@ -245,7 +245,7 @@ TEST_F(TestFilter, testFilterTiles) openvdb::FloatGrid::Ptr ref = openvdb::FloatGrid::create(0.0f); auto& tree = ref->tree(); tree.addTile(test.mLevel, Coord(0), 1.0f, true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -262,7 +262,7 @@ TEST_F(TestFilter, testFilterTiles) // disable tile processing, do nothing filter.setProcessTiles(false); filter.offset(1.0f); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -271,7 +271,7 @@ TEST_F(TestFilter, testFilterTiles) // enable filter.setProcessTiles(true); filter.offset(1.0f); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(2.0f, tree.getValue(Coord(0))); @@ -285,7 +285,7 @@ TEST_F(TestFilter, testFilterTiles) // disable tile processing, do nothing filter.setProcessTiles(false); filter.mean(width, iter); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -308,7 +308,7 @@ TEST_F(TestFilter, testFilterTiles) // disable tile processing, do nothing filter.setProcessTiles(false); filter.median(width, iter); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -339,7 +339,7 @@ TEST_F(TestFilter, testFilterTiles) openvdb::FloatGrid::Ptr ref = openvdb::FloatGrid::create(1.0f); auto& tree = ref->tree(); tree.addTile(test.mLevel, Coord(0), 1.0f, true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -355,7 +355,7 @@ TEST_F(TestFilter, testFilterTiles) openvdb::tools::Filter filter(*grid); filter.setProcessTiles(true); filter.mean(width, iter); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -368,7 +368,7 @@ TEST_F(TestFilter, testFilterTiles) openvdb::tools::Filter filter(*grid); filter.setProcessTiles(true); filter.median(width, iter); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(test.mVoxels, tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -387,7 +387,7 @@ TEST_F(TestFilter, testFilterTiles) openvdb::FloatGrid::Ptr ref = openvdb::FloatGrid::create(1.0f); auto& tree = ref->tree(); tree.addTile(1, Coord(0), 1.0f, true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(Index64(LeafT::NUM_VALUES), tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -402,7 +402,7 @@ TEST_F(TestFilter, testFilterTiles) // filter.setProcessTiles(true); filter.mean(1, 1); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(Index64(LeafT::NUM_VALUES), tree.activeVoxelCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); @@ -410,11 +410,11 @@ TEST_F(TestFilter, testFilterTiles) // create leaf neighbour tree.touchLeaf(Coord(-1,0,0)); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); filter.mean(1, 1); - EXPECT_EQ(Index32(2), tree.leafCount()); + EXPECT_EQ(Index64(2), tree.leafCount()); EXPECT_EQ(Index64(0), tree.activeTileCount()); EXPECT_EQ(Index64(LeafT::NUM_VALUES), tree.activeVoxelCount()); } @@ -426,18 +426,18 @@ TEST_F(TestFilter, testFilterTiles) openvdb::FloatGrid::Ptr ref = openvdb::FloatGrid::create(1.0f); auto& tree = ref->tree(); tree.addTile(level, Coord(0), 1.0f, true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_EQ(1.0f, tree.getValue(Coord(0))); EXPECT_TRUE(tree.isValueOn(Coord(0))); // create a leaf and tile neighbour tree.touchLeaf(Coord(-int(LeafT::DIM),0,0)); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); // create tile level 1 neighbour with a different value tree.addTile(1, Coord(-int(LeafT::DIM),0,LeafT::DIM*3), 2.0f, true); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index64(2), tree.activeTileCount()); return ref; }; @@ -453,7 +453,7 @@ TEST_F(TestFilter, testFilterTiles) // (+ itself becomes a leaf) filter.mean(/*width*/LeafT::DIM+1, /*iter*/1); // 2 leaf nodes from the tile/leaf neighbours + their neighbours - EXPECT_EQ(Index32(2+4+5), tree.leafCount()); + EXPECT_EQ(Index64(2+4+5), tree.leafCount()); EXPECT_EQ((Index64(InternalNode1::NUM_VALUES) - 1) + (Index64(InternalNode2::NUM_VALUES) - (4+5)), tree.activeTileCount()); EXPECT_EQ(Index64(InternalNode1::NUM_VOXELS) + @@ -467,7 +467,7 @@ TEST_F(TestFilter, testFilterTiles) filter.setProcessTiles(true); // with width = 2 and iter = 2, edge/vertex neighbours should also be voxelized filter.mean(/*width*/2, /*iter*/2); - EXPECT_EQ(Index32(2+4+6), tree.leafCount()); + EXPECT_EQ(Index64(2+4+6), tree.leafCount()); EXPECT_EQ((Index64(InternalNode1::NUM_VALUES) - 1) + (Index64(InternalNode2::NUM_VALUES) - (4+6)), tree.activeTileCount()); EXPECT_EQ(Index64(InternalNode1::NUM_VOXELS) + @@ -481,7 +481,7 @@ TEST_F(TestFilter, testFilterTiles) filter.setProcessTiles(true); // with width = 1 and iter = 9 - checks an iter count > LeafT::DIM filter.mean(/*width*/1, /*iter*/LeafT::DIM+1); - EXPECT_EQ(Index32(38), tree.leafCount()); + EXPECT_EQ(Index64(38), tree.leafCount()); EXPECT_EQ((Index64(InternalNode2::NUM_VALUES) - 36), tree.activeTileCount()); EXPECT_EQ(Index64(InternalNode2::NUM_VOXELS) + Index64(LeafT::NUM_VOXELS), tree.activeVoxelCount()); diff --git a/openvdb/openvdb/unittest/TestGrid.cc b/openvdb/openvdb/unittest/TestGrid.cc index d7d6056bb5..66fa1082db 100644 --- a/openvdb/openvdb/unittest/TestGrid.cc +++ b/openvdb/openvdb/unittest/TestGrid.cc @@ -75,7 +75,7 @@ class ProxyTree: public openvdb::TreeBase void prune(const ValueType& = 0) {} void clip(const openvdb::CoordBBox&) {} void clipUnallocatedNodes() override {} - openvdb::Index32 unallocatedLeafCount() const override { return 0; } + openvdb::Index64 unallocatedLeafCount() const override { return 0; } void getIndexRange(openvdb::CoordBBox&) const override {} bool evalLeafBoundingBox(openvdb::CoordBBox& bbox) const override @@ -88,9 +88,9 @@ class ProxyTree: public openvdb::TreeBase { dim = openvdb::Coord(0, 0, 0); return false; } openvdb::Index treeDepth() const override { return 0; } - openvdb::Index leafCount() const override { return 0; } - std::vector nodeCount() const override - { return std::vector(DEPTH, 0); } + openvdb::Index64 leafCount() const override { return 0; } + std::vector nodeCount() const override + { return std::vector(DEPTH, 0); } openvdb::Index nonLeafCount() const override { return 0; } openvdb::Index64 activeVoxelCount() const override { return 0UL; } openvdb::Index64 inactiveVoxelCount() const override { return 0UL; } @@ -270,7 +270,7 @@ TEST_F(TestGrid, testCopyGrid) // shallow-copy a const grid but supply a new transform and meta map EXPECT_EQ(1.0, grid1->transform().voxelSize().x()); EXPECT_EQ(size_t(0), grid1->metaCount()); - EXPECT_EQ(Index(2), grid1->tree().leafCount()); + EXPECT_EQ(Index64(2), grid1->tree().leafCount()); math::Transform::Ptr xform(math::Transform::createLinearTransform(/*voxelSize=*/0.25)); MetaMap meta; @@ -283,7 +283,7 @@ TEST_F(TestGrid, testCopyGrid) EXPECT_EQ(0.25, grid3->transform().voxelSize().x()); EXPECT_EQ(size_t(1), grid3->metaCount()); - EXPECT_EQ(Index(2), tree3.leafCount()); + EXPECT_EQ(Index64(2), tree3.leafCount()); EXPECT_EQ(long(3), constGrid1->constTreePtr().use_count()); } diff --git a/openvdb/openvdb/unittest/TestIndexFilter.cc b/openvdb/openvdb/unittest/TestIndexFilter.cc index a9aff3f378..3389511d85 100644 --- a/openvdb/openvdb/unittest/TestIndexFilter.cc +++ b/openvdb/openvdb/unittest/TestIndexFilter.cc @@ -157,7 +157,7 @@ TEST_F(TestIndexFilter, testActiveFilter) // check there are two leafs - EXPECT_EQ(Index32(2), points->tree().leafCount()); + EXPECT_EQ(Index64(2), points->tree().leafCount()); ActiveFilter activeFilter; InactiveFilter inActiveFilter; @@ -551,7 +551,7 @@ TEST_F(TestIndexFilter, testAttributeHashFilter) // four points, two leafs - EXPECT_EQ(tree.leafCount(), Index32(2)); + EXPECT_EQ(tree.leafCount(), Index64(2)); appendAttribute(tree, "id"); @@ -846,7 +846,7 @@ TEST_F(TestIndexFilter, testBBoxFilter) PointDataTree& tree = grid->tree(); // check one leaf per point - EXPECT_EQ(tree.leafCount(), Index32(2)); + EXPECT_EQ(tree.leafCount(), Index64(2)); // build some bounding box filters to test diff --git a/openvdb/openvdb/unittest/TestLeaf.cc b/openvdb/openvdb/unittest/TestLeaf.cc index 96ac1f04c1..3737386fe6 100644 --- a/openvdb/openvdb/unittest/TestLeaf.cc +++ b/openvdb/openvdb/unittest/TestLeaf.cc @@ -508,7 +508,7 @@ TEST_F(TestLeaf, testCount) EXPECT_EQ(Index(512), leaf.numValues()); EXPECT_EQ(Index(0), leaf.getLevel()); EXPECT_EQ(Index(1), leaf.getChildDim()); - EXPECT_EQ(Index(1), leaf.leafCount()); + EXPECT_EQ(Index64(1), leaf.leafCount()); EXPECT_EQ(Index(0), leaf.nonLeafCount()); EXPECT_EQ(Index(0), leaf.childCount()); diff --git a/openvdb/openvdb/unittest/TestLevelSetUtil.cc b/openvdb/openvdb/unittest/TestLevelSetUtil.cc index 165a960e5c..78e14ac9fa 100644 --- a/openvdb/openvdb/unittest/TestLevelSetUtil.cc +++ b/openvdb/openvdb/unittest/TestLevelSetUtil.cc @@ -146,7 +146,7 @@ TEST_F(TestLevelSetUtil, testSegmentationTools) openvdb::tools::segmentSDF(*sdfGrid, segments); EXPECT_EQ(size_t(1), segments.size()); - EXPECT_EQ(openvdb::Index32(0), segments[0]->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(0), segments[0]->tree().leafCount()); EXPECT_EQ(10.2f, segments[0]->background()); } @@ -173,7 +173,7 @@ TEST_F(TestLevelSetUtil, testSegmentationTools) openvdb::tools::segmentSDF(*sdfGrid, segments); EXPECT_EQ(size_t(1), segments.size()); - EXPECT_EQ(openvdb::Index32(0), segments[0]->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(0), segments[0]->tree().leafCount()); EXPECT_EQ(sdfGrid->background(), segments[0]->background()); } @@ -195,14 +195,14 @@ TEST_F(TestLevelSetUtil, testSegmentationTools) openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(/*background=*/3.1f); - EXPECT_EQ(openvdb::Index32(0), grid->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(0), grid->tree().leafCount()); std::vector segments; openvdb::tools::segmentActiveVoxels(*grid, segments); // note that an empty volume should segment into an empty volume EXPECT_EQ(size_t(1), segments.size()); - EXPECT_EQ(openvdb::Index32(0), segments[0]->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(0), segments[0]->tree().leafCount()); EXPECT_EQ(3.1f, segments[0]->background()); } @@ -213,14 +213,14 @@ TEST_F(TestLevelSetUtil, testSegmentationTools) grid->tree().touchLeaf(openvdb::Coord(0,0,0)); grid->tree().touchLeaf(openvdb::Coord(100,100,100)); - EXPECT_EQ(openvdb::Index32(2), grid->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(2), grid->tree().leafCount()); EXPECT_EQ(openvdb::Index64(0), grid->tree().activeVoxelCount()); std::vector segments; openvdb::tools::segmentActiveVoxels(*grid, segments); EXPECT_EQ(size_t(1), segments.size()); - EXPECT_EQ(openvdb::Index32(0), segments[0]->tree().leafCount()); + EXPECT_EQ(openvdb::Index64(0), segments[0]->tree().leafCount()); } } diff --git a/openvdb/openvdb/unittest/TestMerge.cc b/openvdb/openvdb/unittest/TestMerge.cc index 519a75f2a9..3a98d58479 100644 --- a/openvdb/openvdb/unittest/TestMerge.cc +++ b/openvdb/openvdb/unittest/TestMerge.cc @@ -82,7 +82,7 @@ TEST_F(TestMerge, testTreeToMerge) { // non-const tree FloatGrid::Ptr grid = createLevelSet(); grid->tree().touchLeaf(Coord(8)); - EXPECT_EQ(Index(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); tools::TreeToMerge treeToMerge{grid->tree(), Steal()}; EXPECT_EQ(&grid->constTree().root(), treeToMerge.rootPtr()); @@ -98,14 +98,14 @@ TEST_F(TestMerge, testTreeToMerge) const LeafNode* leafNode = treeToMerge.probeConstNode(Coord(8)); EXPECT_TRUE(leafNode); EXPECT_EQ(grid->constTree().probeConstLeaf(Coord(8)), leafNode); - EXPECT_EQ(Index(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); EXPECT_EQ(Index(1), grid->tree().root().childCount()); // steal leaf node std::unique_ptr leafNodePtr = treeToMerge.stealOrDeepCopyNode(Coord(8)); EXPECT_TRUE(leafNodePtr); - EXPECT_EQ(Index(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); EXPECT_EQ(leafNodePtr->origin(), Coord(8)); EXPECT_EQ(Index(1), grid->tree().root().childCount()); @@ -139,7 +139,7 @@ TEST_F(TestMerge, testTreeToMerge) { // const tree FloatGrid::Ptr grid = createLevelSet(); grid->tree().touchLeaf(Coord(8)); - EXPECT_EQ(Index(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); tools::TreeToMerge treeToMerge{grid->constTree(), DeepCopy(), /*initialize=*/false}; EXPECT_TRUE(!treeToMerge.hasMask()); @@ -158,14 +158,14 @@ TEST_F(TestMerge, testTreeToMerge) const LeafNode* leafNode = treeToMerge.probeConstNode(Coord(8)); EXPECT_TRUE(leafNode); EXPECT_EQ(grid->constTree().probeConstLeaf(Coord(8)), leafNode); - EXPECT_EQ(Index(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); EXPECT_EQ(Index(1), grid->tree().root().childCount()); { // deep copy leaf node tools::TreeToMerge treeToMerge2{grid->constTree(), DeepCopy()}; std::unique_ptr leafNodePtr = treeToMerge2.stealOrDeepCopyNode(Coord(8)); EXPECT_TRUE(leafNodePtr); - EXPECT_EQ(Index(1), grid->tree().leafCount()); // leaf has not been stolen + EXPECT_EQ(Index64(1), grid->tree().leafCount()); // leaf has not been stolen EXPECT_EQ(leafNodePtr->origin(), Coord(8)); EXPECT_EQ(Index(1), grid->tree().root().childCount()); } @@ -221,7 +221,7 @@ TEST_F(TestMerge, testTreeToMerge) FloatGrid::Ptr grid = createLevelSet(); grid->tree().touchLeaf(Coord(8)); - EXPECT_EQ(Index(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); treeToMerge.reset(grid->treePtr(), Steal()); } @@ -241,7 +241,7 @@ TEST_F(TestMerge, testTreeToMerge) EXPECT_TRUE(!treeToMerge2.treeToSteal()); EXPECT_TRUE(treeToMerge2.treeToDeepCopy()); - EXPECT_EQ(Index(0), treeToMerge2.treeToDeepCopy()->leafCount()); + EXPECT_EQ(Index64(0), treeToMerge2.treeToDeepCopy()->leafCount()); FloatGrid::Ptr grid = createLevelSet(); grid->tree().touchLeaf(Coord(8)); @@ -249,7 +249,7 @@ TEST_F(TestMerge, testTreeToMerge) EXPECT_TRUE(treeToMerge2.treeToSteal()); EXPECT_TRUE(!treeToMerge2.treeToDeepCopy()); - EXPECT_EQ(Index(1), treeToMerge2.treeToSteal()->leafCount()); + EXPECT_EQ(Index64(1), treeToMerge2.treeToSteal()->leafCount()); } } @@ -908,7 +908,7 @@ TEST_F(TestMerge, testCsgUnion) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); } { // merge a leaf node into a grid with an outside tile @@ -955,8 +955,8 @@ TEST_F(TestMerge, testCsgUnion) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); - EXPECT_EQ(Index32(0), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid2->tree().leafCount()); // test background values are remapped @@ -1027,8 +1027,8 @@ TEST_F(TestMerge, testCsgUnion) FloatGrid::Ptr grid2 = createLevelSet(); grid2->tree().touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); // merge from a const tree @@ -1038,9 +1038,9 @@ TEST_F(TestMerge, testCsgUnion) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); // leaf has been deep copied not stolen - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); } } @@ -1772,7 +1772,7 @@ TEST_F(TestMerge, testCsgIntersection) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); } { // merge a leaf node into a grid with a background tile @@ -1785,7 +1785,7 @@ TEST_F(TestMerge, testCsgIntersection) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); } { // merge a leaf node into a grid with an outside tile @@ -1828,8 +1828,8 @@ TEST_F(TestMerge, testCsgIntersection) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); - EXPECT_EQ(Index32(0), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid2->tree().leafCount()); // test background values are remapped @@ -1901,8 +1901,8 @@ TEST_F(TestMerge, testCsgIntersection) FloatGrid::Ptr grid2 = createLevelSet(); grid2->tree().touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); // merge from a const tree @@ -1912,9 +1912,9 @@ TEST_F(TestMerge, testCsgIntersection) tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); // leaf has been deep copied not stolen - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); } { // merge three leaf nodes from four grids @@ -2472,15 +2472,15 @@ TEST_F(TestMerge, testCsgDifference) FloatGrid::Ptr grid2 = createLevelSet(); grid2->tree().touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); tools::CsgDifferenceOp mergeOp(grid2->tree(), Steal()); tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); - EXPECT_EQ(Index32(0), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(0), grid2->tree().leafCount()); } { // merge two leaf nodes into a grid @@ -2489,8 +2489,8 @@ TEST_F(TestMerge, testCsgDifference) FloatGrid::Ptr grid2 = createLevelSet(); grid2->tree().touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); tools::CsgDifferenceOp mergeOp(grid2->tree(), Steal()); tree::DynamicNodeManager nodeManager(grid->tree()); @@ -2556,15 +2556,15 @@ TEST_F(TestMerge, testCsgDifference) FloatGrid::Ptr grid2 = createLevelSet(); grid2->tree().touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(0), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(0), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); tools::CsgDifferenceOp mergeOp(grid2->constTree(), DeepCopy()); tree::DynamicNodeManager nodeManager(grid->tree()); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), grid->tree().leafCount()); - EXPECT_EQ(Index32(1), grid2->tree().leafCount()); + EXPECT_EQ(Index64(1), grid->tree().leafCount()); + EXPECT_EQ(Index64(1), grid2->tree().leafCount()); } } @@ -2887,7 +2887,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(tree.cbeginLeaf()->getFirstValue(), 0.0f); } @@ -2902,7 +2902,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 10.0f); @@ -2924,7 +2924,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 210.0f); @@ -2949,7 +2949,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 210.0f); @@ -2973,7 +2973,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 15.0f); @@ -2995,7 +2995,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 10.0f); @@ -3017,7 +3017,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 10.0f); @@ -3039,7 +3039,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), 10.0f); @@ -3155,8 +3155,8 @@ TEST_F(TestMerge, testSum) FloatGrid::Ptr grid2 = createLevelSet(); tree2.touchLeaf(Coord(0, 0, 0)); - EXPECT_EQ(Index32(0), tree.leafCount()); - EXPECT_EQ(Index32(1), tree2.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); + EXPECT_EQ(Index64(1), tree2.leafCount()); // merge from a const tree @@ -3168,9 +3168,9 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); // leaf has been deep copied not stolen - EXPECT_EQ(Index32(1), tree2.leafCount()); + EXPECT_EQ(Index64(1), tree2.leafCount()); } } @@ -3185,7 +3185,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_EQ(iter->getValue(0), Vec3s(1.0f, 2.0f, 3.0f)); @@ -3206,7 +3206,7 @@ TEST_F(TestMerge, testSum) tree::DynamicNodeManager nodeManager(tree); nodeManager.foreachTopDown(mergeOp); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index(0), getTileCount(tree.root())); auto iter = tree.cbeginLeaf(); EXPECT_FALSE(iter->isValueOn(0)); diff --git a/openvdb/openvdb/unittest/TestMorphology.cc b/openvdb/openvdb/unittest/TestMorphology.cc index c7498996b9..a03e1db857 100644 --- a/openvdb/openvdb/unittest/TestMorphology.cc +++ b/openvdb/openvdb/unittest/TestMorphology.cc @@ -113,7 +113,7 @@ TestMorphologyInternal::testMorphActiveLeafValues() EXPECT_EQ(Index64(1), tree.activeVoxelCount()); openvdb::tools::erodeActiveValues(tree, 1, NN, openvdb::tools::IGNORE_TILES); EXPECT_EQ(Index64(0), tree.activeVoxelCount()); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); // check values if (!IsMask) { EXPECT_EQ(tree.getValue(xyz), ValueType(1.0)); @@ -124,7 +124,7 @@ TestMorphologyInternal::testMorphActiveLeafValues() { // Create an active, leaf node-sized tile and a single edge/corner voxel tree.clear(); tree.addTile(/*level*/1, Coord(0), ValueType(1.0), true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(leafDim * leafDim * leafDim), tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); @@ -143,7 +143,7 @@ TestMorphologyInternal::testMorphActiveLeafValues() if (NN == openvdb::tools::NN_FACE_EDGE_VERTEX) expected += 22; // 4 overlapping EXPECT_EQ(expected, tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); - Index32 leafs; + Index64 leafs; if (NN == openvdb::tools::NN_FACE) leafs = 3; if (NN == openvdb::tools::NN_FACE_EDGE) leafs = 6; if (NN == openvdb::tools::NN_FACE_EDGE_VERTEX) leafs = 7; @@ -434,7 +434,7 @@ TestMorphologyInternal::testMorphActiveValues() { // Test behaviour with an existing active tile at (0,0,0) tree.clear(); tree.addTile(/*level*/1, Coord(0), ValueType(1.0), true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(leafDim * leafDim * leafDim), tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); @@ -450,7 +450,7 @@ TestMorphologyInternal::testMorphActiveValues() TreeT erodeexp(tree), erodepres(tree); openvdb::tools::erodeActiveValues(erodeexp, 1, NN, openvdb::tools::EXPAND_TILES); Index64 expected = (leafDim-2) * (leafDim-2) * (leafDim-2); - EXPECT_EQ(Index32(1), erodeexp.leafCount()); + EXPECT_EQ(Index64(1), erodeexp.leafCount()); EXPECT_EQ(expected, erodeexp.activeVoxelCount()); EXPECT_EQ(Index64(0), erodeexp.activeTileCount()); EXPECT_TRUE(erodeexp.probeConstLeaf(Coord(0))); @@ -465,7 +465,7 @@ TestMorphologyInternal::testMorphActiveValues() if (NN == openvdb::tools::NN_FACE) expected += (leafDim * leafDim) * 6; // faces if (NN == openvdb::tools::NN_FACE_EDGE) expected += ((leafDim * leafDim) * 6) + (leafDim) * 12; // edges if (NN == openvdb::tools::NN_FACE_EDGE_VERTEX) expected += ((leafDim * leafDim) * 6) + ((leafDim) * 12) + 8; // edges - EXPECT_EQ(Index32(1+offsets), tree.leafCount()); + EXPECT_EQ(Index64(1+offsets), tree.leafCount()); EXPECT_EQ(expected, tree.activeVoxelCount()); EXPECT_EQ(Index64(0), tree.activeTileCount()); // Check actual values around center node faces @@ -492,7 +492,7 @@ TestMorphologyInternal::testMorphActiveValues() TreeT erode(tree); openvdb::tools::erodeActiveValues(erode, 1, NN, openvdb::tools::IGNORE_TILES); Index64 expected = leafDim * leafDim * leafDim; - EXPECT_EQ(Index32(1+offsets), erode.leafCount()); + EXPECT_EQ(Index64(1+offsets), erode.leafCount()); EXPECT_EQ(expected, erode.activeVoxelCount()); EXPECT_EQ(Index64(0), erode.activeTileCount()); EXPECT_TRUE(erode.probeConstLeaf(Coord(0))); @@ -514,7 +514,7 @@ TestMorphologyInternal::testMorphActiveValues() if (NN == openvdb::tools::NN_FACE_EDGE) expected += ((leafDim * leafDim) * 6) + (leafDim) * 12; // edges if (NN == openvdb::tools::NN_FACE_EDGE_VERTEX) expected += ((leafDim * leafDim) * 6) + ((leafDim) * 12) + 8; // edges - EXPECT_EQ(Index32(offsets), tree.leafCount()); + EXPECT_EQ(Index64(offsets), tree.leafCount()); EXPECT_EQ(expected, tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); EXPECT_TRUE(copy.hasSameTopology(tree)); @@ -539,7 +539,7 @@ TestMorphologyInternal::testMorphActiveValues() openvdb::tools::erodeActiveValues(erode, 1, NN, openvdb::tools::PRESERVE_TILES); // PRESERVE_TILES will prune the result Index64 expected = leafDim * leafDim * leafDim; - EXPECT_EQ(Index32(0), erode.leafCount()); + EXPECT_EQ(Index64(0), erode.leafCount()); EXPECT_EQ(expected, erode.activeVoxelCount()); EXPECT_EQ(Index64(1), erode.activeTileCount()); EXPECT_TRUE(!erode.probeConstLeaf(Coord(0))); @@ -549,7 +549,7 @@ TestMorphologyInternal::testMorphActiveValues() { // Test tile preservation with voxel topology - create an active, leaf node-sized tile and a single edge voxel tree.clear(); tree.addTile(/*level*/1, Coord(0), ValueType(1.0), true); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index64(leafDim * leafDim * leafDim), tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); @@ -575,7 +575,7 @@ TestMorphologyInternal::testMorphActiveValues() // Check actual values around center node faces EXPECT_EQ(Index64(1), tree.activeTileCount()); - EXPECT_EQ(Index32(offsets), tree.leafCount()); + EXPECT_EQ(Index64(offsets), tree.leafCount()); EXPECT_TRUE(!tree.probeConstLeaf(Coord(0))); EXPECT_TRUE(tree.isValueOn(Coord(0))); for (int i = 0; i < int(leafDim); ++i) { @@ -592,7 +592,7 @@ TestMorphologyInternal::testMorphActiveValues() { // Test tile is preserved with erosions IGNORE_TILES, irrespective of iterations openvdb::tools::erodeActiveValues(tree, 10, NN, openvdb::tools::IGNORE_TILES); EXPECT_EQ(Index64(1), tree.activeTileCount()); - EXPECT_EQ(Index32(offsets), tree.leafCount()); + EXPECT_EQ(Index64(offsets), tree.leafCount()); EXPECT_EQ(Index64(leafDim * leafDim * leafDim), tree.activeVoxelCount()); EXPECT_TRUE(!tree.probeConstLeaf(Coord(0))); EXPECT_TRUE(tree.isValueOn(Coord(0))); @@ -613,7 +613,7 @@ TestMorphologyInternal::testMorphActiveValues() tree.touchLeaf(Coord(leafDim*6, 0, 0))->setValuesOn(); Index64 expected = (leafDim * leafDim * leafDim) + ((leafDim * leafDim * leafDim) - (leafDim * leafDim)) * 2; - EXPECT_EQ(Index32(3), tree.leafCount()); + EXPECT_EQ(Index64(3), tree.leafCount()); EXPECT_EQ(expected, tree.activeVoxelCount()); EXPECT_EQ(Index64(0), tree.activeTileCount()); @@ -631,7 +631,7 @@ TestMorphologyInternal::testMorphActiveValues() if (NN == openvdb::tools::NN_FACE_EDGE) expected = offsets*3 -10; if (NN == openvdb::tools::NN_FACE_EDGE_VERTEX) expected = offsets*3 -18; if (!IsMask) expected += 1; - EXPECT_EQ(Index32(expected), tree.leafCount()); + EXPECT_EQ(Index64(expected), tree.leafCount()); // first if (IsMask) { // should have been pruned @@ -654,7 +654,7 @@ TestMorphologyInternal::testMorphActiveValues() openvdb::tools::PRESERVE_TILES); expected = (leafDim * leafDim * leafDim) + ((leafDim * leafDim * leafDim) - (leafDim * leafDim)) * 2; - EXPECT_EQ(Index32(2), tree.leafCount()); + EXPECT_EQ(Index64(2), tree.leafCount()); EXPECT_EQ(expected, tree.activeVoxelCount()); EXPECT_EQ(Index64(1), tree.activeTileCount()); } diff --git a/openvdb/openvdb/unittest/TestNodeManager.cc b/openvdb/openvdb/unittest/TestNodeManager.cc index d5a45fa587..63073d6b18 100644 --- a/openvdb/openvdb/unittest/TestNodeManager.cc +++ b/openvdb/openvdb/unittest/TestNodeManager.cc @@ -294,7 +294,7 @@ TEST_F(TestNodeManager, testDynamic) std::make_unique(Coord(0, 0, 0), /*value=*/1.0f); EXPECT_TRUE(sourceTree.root().addChild(child.release())); - EXPECT_EQ(Index32(0), sourceTree.leafCount()); + EXPECT_EQ(Index64(0), sourceTree.leafCount()); EXPECT_EQ(Index32(2), sourceTree.nonLeafCount()); ExpandOp expandOp; @@ -304,7 +304,7 @@ TEST_F(TestNodeManager, testDynamic) openvdb::tree::NodeManager manager(tree); EXPECT_EQ(Index64(1), manager.nodeCount()); manager.foreachTopDown(expandOp); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); // first level has been expanded, but node manager cache does not include the new nodes SumOp sumOp; @@ -324,7 +324,7 @@ TEST_F(TestNodeManager, testDynamic) Int32Tree tree(sourceTree); openvdb::tree::DynamicNodeManager manager(tree); manager.foreachTopDown(expandOp, /*threaded=*/true, /*leafGrainSize=*/32, /*nonLeafGrainSize=*/8); - EXPECT_EQ(Index32(32768), tree.leafCount()); + EXPECT_EQ(Index64(32768), tree.leafCount()); SumOp sumOp; manager.reduceTopDown(sumOp); @@ -340,7 +340,7 @@ TEST_F(TestNodeManager, testDynamic) openvdb::tree::DynamicNodeManager manager(tree); ExpandOp zeroExpandOp(true); manager.foreachTopDown(zeroExpandOp); - EXPECT_EQ(Index32(32768), tree.leafCount()); + EXPECT_EQ(Index64(32768), tree.leafCount()); SumOp sumOp; manager.reduceTopDown(sumOp); diff --git a/openvdb/openvdb/unittest/TestNodeVisitor.cc b/openvdb/openvdb/unittest/TestNodeVisitor.cc index 19732621f3..8ab14d4cfd 100644 --- a/openvdb/openvdb/unittest/TestNodeVisitor.cc +++ b/openvdb/openvdb/unittest/TestNodeVisitor.cc @@ -22,7 +22,7 @@ struct NodeCountOp counts[level]++; } - std::vector counts; + std::vector counts; }; // struct NodeCountOp @@ -35,8 +35,8 @@ TEST_F(TestNodeVisitor, testNodeCount) NodeCountOp nodeCountOp; tools::visitNodesDepthFirst(grid->tree(), nodeCountOp); - std::vector nodeCount1 = nodeCountOp.counts; - std::vector nodeCount2 = grid->tree().nodeCount(); + std::vector nodeCount1 = nodeCountOp.counts; + std::vector nodeCount2 = grid->tree().nodeCount(); EXPECT_EQ(nodeCount1.size(), nodeCount2.size()); @@ -55,7 +55,7 @@ struct LeafCountOp void operator()(const NodeT&, size_t) { } void operator()(const LeafT&, size_t) { count++; } - openvdb::Index32 count{0}; + openvdb::Index64 count{0}; }; // struct LeafCountOp @@ -142,8 +142,8 @@ TEST_F(TestNodeVisitor, testOriginArray) FloatGrid::Ptr grid = tools::createLevelSetCube(/*scale=*/10.0f); - std::vector nodeCount = grid->tree().nodeCount(); - Index32 totalNodeCount(0); + std::vector nodeCount = grid->tree().nodeCount(); + Index64 totalNodeCount(0); for (Index32 count : nodeCount) totalNodeCount += count; // use an offset @@ -203,12 +203,12 @@ TEST_F(TestNodeVisitor, testPartialDeactivate) DeactivateOp deactivateOp; tools::DepthFirstNodeVisitor::visit(*iter, deactivateOp); - EXPECT_EQ(Index32(1413), grid->tree().leafCount()); + EXPECT_EQ(Index64(1413), grid->tree().leafCount()); tools::pruneInactive(grid->tree()); // a subset of the leaf nodes have now been deactivated and removed - EXPECT_EQ(Index32(1195), grid->tree().leafCount()); + EXPECT_EQ(Index64(1195), grid->tree().leafCount()); } diff --git a/openvdb/openvdb/unittest/TestPointAttribute.cc b/openvdb/openvdb/unittest/TestPointAttribute.cc index 19b66213b4..4fff63f23e 100644 --- a/openvdb/openvdb/unittest/TestPointAttribute.cc +++ b/openvdb/openvdb/unittest/TestPointAttribute.cc @@ -36,7 +36,7 @@ TEST_F(TestPointAttribute, testAppendDrop) PointDataTree& tree = grid->tree(); // check one leaf per point - EXPECT_EQ(tree.leafCount(), Index32(4)); + EXPECT_EQ(tree.leafCount(), Index64(4)); // retrieve first and last leaf attribute sets @@ -298,7 +298,7 @@ TEST_F(TestPointAttribute, testRename) PointDataTree& tree = grid->tree(); // check one leaf per point - EXPECT_EQ(tree.leafCount(), Index32(4)); + EXPECT_EQ(tree.leafCount(), Index64(4)); const openvdb::TypedMetadata defaultValue(5.0f); @@ -373,7 +373,7 @@ TEST_F(TestPointAttribute, testBloscCompress) PointDataTree& tree = grid->tree(); // check two leaves - EXPECT_EQ(tree.leafCount(), Index32(2)); + EXPECT_EQ(tree.leafCount(), Index64(2)); // retrieve first and last leaf attribute sets diff --git a/openvdb/openvdb/unittest/TestPointCount.cc b/openvdb/openvdb/unittest/TestPointCount.cc index 350aa888ae..58ea887907 100644 --- a/openvdb/openvdb/unittest/TestPointCount.cc +++ b/openvdb/openvdb/unittest/TestPointCount.cc @@ -186,7 +186,7 @@ TEST_F(TestPointCount, testGroup) PointDataTree& tree = grid->tree(); // check one leaf - EXPECT_EQ(tree.leafCount(), Index32(1)); + EXPECT_EQ(tree.leafCount(), Index64(1)); // retrieve first and last leaf attribute sets @@ -371,7 +371,7 @@ TEST_F(TestPointCount, testGroup) grid = createPointDataGrid(positions, *transform); PointDataTree& tree2 = grid->tree(); - EXPECT_EQ(tree2.leafCount(), Index32(4)); + EXPECT_EQ(tree2.leafCount(), Index64(4)); leafIter = tree2.beginLeaf(); diff --git a/openvdb/openvdb/unittest/TestPointDataLeaf.cc b/openvdb/openvdb/unittest/TestPointDataLeaf.cc index 70a37166c7..b22153e05a 100644 --- a/openvdb/openvdb/unittest/TestPointDataLeaf.cc +++ b/openvdb/openvdb/unittest/TestPointDataLeaf.cc @@ -1523,7 +1523,7 @@ TEST_F(TestPointDataLeaf, testCopyDescriptor) PointDataTree tree2(tree); - EXPECT_EQ(tree2.leafCount(), openvdb::Index32(2)); + EXPECT_EQ(tree2.leafCount(), openvdb::Index64(2)); descrA->setGroup("test", size_t(1)); diff --git a/openvdb/openvdb/unittest/TestPointGroup.cc b/openvdb/openvdb/unittest/TestPointGroup.cc index 04c2df33bb..8133956c2b 100644 --- a/openvdb/openvdb/unittest/TestPointGroup.cc +++ b/openvdb/openvdb/unittest/TestPointGroup.cc @@ -137,7 +137,7 @@ TEST_F(TestPointGroup, testAppendDrop) PointDataTree& tree = grid->tree(); // check one leaf per point - EXPECT_EQ(tree.leafCount(), Index32(4)); + EXPECT_EQ(tree.leafCount(), Index64(4)); // retrieve first and last leaf attribute sets @@ -312,7 +312,7 @@ TEST_F(TestPointGroup, testCompact) PointDataTree& tree = grid->tree(); // check one leaf - EXPECT_EQ(tree.leafCount(), Index32(1)); + EXPECT_EQ(tree.leafCount(), Index64(1)); // retrieve first and last leaf attribute sets diff --git a/openvdb/openvdb/unittest/TestPointMove.cc b/openvdb/openvdb/unittest/TestPointMove.cc index 3331fa2a27..cf165a9998 100644 --- a/openvdb/openvdb/unittest/TestPointMove.cc +++ b/openvdb/openvdb/unittest/TestPointMove.cc @@ -766,7 +766,7 @@ TEST_F(TestPointMove, testCustomDeformer) PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize); PointDataGrid::Ptr cachedPoints = points->deepCopy(); - const int leafCount = points->tree().leafCount(); + const int leafCount = int(points->tree().leafCount()); const int pointCount = int(positions.size()); std::atomic resetCalls, applyCalls; diff --git a/openvdb/openvdb/unittest/TestPointRasterizeSDF.cc b/openvdb/openvdb/unittest/TestPointRasterizeSDF.cc index 9540f25a99..3af09c8288 100644 --- a/openvdb/openvdb/unittest/TestPointRasterizeSDF.cc +++ b/openvdb/openvdb/unittest/TestPointRasterizeSDF.cc @@ -135,7 +135,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(8), sdf->tree().leafCount()); + EXPECT_EQ(Index64(8), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(485), sdf->tree().activeVoxelCount()); @@ -163,7 +163,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(8), sdf->tree().leafCount()); + EXPECT_EQ(Index64(8), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(739), sdf->tree().activeVoxelCount()); @@ -192,7 +192,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.transform->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(27), sdf->tree().leafCount()); + EXPECT_EQ(Index64(27), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(5005), sdf->tree().activeVoxelCount()); @@ -236,7 +236,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(8), sdf->tree().leafCount()); + EXPECT_EQ(Index64(8), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(485), sdf->tree().activeVoxelCount()); @@ -265,7 +265,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(38), sdf->tree().leafCount()); + EXPECT_EQ(Index64(38), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(485*8), sdf->tree().activeVoxelCount()); // 485 per sphere @@ -306,7 +306,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.transform->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(46), sdf->tree().leafCount()); + EXPECT_EQ(Index64(46), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(7198), sdf->tree().activeVoxelCount()); @@ -359,7 +359,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(17), sdf->tree().leafCount()); // less leaf nodes, active points are on a single face + EXPECT_EQ(Index64(17), sdf->tree().leafCount()); // less leaf nodes, active points are on a single face EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(485*4), sdf->tree().activeVoxelCount()); // 485 per sphere @@ -568,7 +568,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeVariableSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(8), sdf->tree().leafCount()); // less leaf nodes, active points are on a single face + EXPECT_EQ(Index64(8), sdf->tree().leafCount()); // less leaf nodes, active points are on a single face EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(1454), sdf->tree().activeVoxelCount()); // 485 per sphere @@ -732,7 +732,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeSmoothSpheres) EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(44), sdf->tree().leafCount()); + EXPECT_EQ(Index64(44), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(6303), sdf->tree().activeVoxelCount()); const CoordBBox bounds(Coord(-7), Coord(7)); @@ -874,7 +874,7 @@ TEST_F(TestPointRasterizeSDF, testRasterizeVariableSmoothSpheres) EXPECT_TRUE(sdf->transform() == s.points->transform()); EXPECT_EQ(GRID_LEVEL_SET, sdf->getGridClass()); EXPECT_EQ(float(s.halfband * s.points->voxelSize()[0]), sdf->background()); - EXPECT_EQ(Index32(64), sdf->tree().leafCount()); + EXPECT_EQ(Index64(64), sdf->tree().leafCount()); EXPECT_EQ(Index64(0), sdf->tree().activeTileCount()); EXPECT_EQ(Index64(15011), sdf->tree().activeVoxelCount()); for (auto iter = sdf->cbeginValueOn(); iter; ++iter) { diff --git a/openvdb/openvdb/unittest/TestPointScatter.cc b/openvdb/openvdb/unittest/TestPointScatter.cc index ca8d92b070..58bf459ab6 100644 --- a/openvdb/openvdb/unittest/TestPointScatter.cc +++ b/openvdb/openvdb/unittest/TestPointScatter.cc @@ -36,7 +36,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) BoolGrid grid; grid.sparseFill(boxBounds, false, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -44,7 +44,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) DoubleGrid grid; grid.sparseFill(boxBounds, 0.0, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -52,7 +52,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) FloatGrid grid; grid.sparseFill(boxBounds, 0.0f, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -60,7 +60,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) Int32Grid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -68,7 +68,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) Int64Grid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -76,7 +76,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) MaskGrid grid; grid.sparseFill(boxBounds, /*maskBuffer*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -84,7 +84,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) Vec3DGrid grid; grid.sparseFill(boxBounds, Vec3d(), /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -92,7 +92,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) Vec3IGrid grid; grid.sparseFill(boxBounds, Vec3i(), /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -100,7 +100,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) Vec3SGrid grid; grid.sparseFill(boxBounds, Vec3f(), /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -108,7 +108,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) PointDataGrid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); } @@ -128,7 +128,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) BoolGrid grid; grid.sparseFill(boxBounds, false, /*active*/true); auto points = points::uniformPointScatter(grid, 1); - EXPECT_EQ(Index32(1), points->tree().leafCount()); + EXPECT_EQ(Index64(1), points->tree().leafCount()); EXPECT_EQ(Index64(1), points->activeVoxelCount()); EXPECT_EQ(Index64(1), pointCount(points->tree())); } @@ -145,7 +145,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) auto points = points::uniformPointScatter(grid, total); EXPECT_EQ(Index64(0), points->tree().activeTileCount()); - EXPECT_EQ(Index32(1), points->tree().leafCount()); + EXPECT_EQ(Index64(1), points->tree().leafCount()); EXPECT_TRUE(Index64(NUM_VALUES) > points->tree().activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); @@ -226,7 +226,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) points = points::uniformPointScatter(grid, total); - EXPECT_EQ(Index32(1), points->tree().leafCount()); + EXPECT_EQ(Index64(1), points->tree().leafCount()); EXPECT_TRUE(Index64(NUM_VALUES) > points->tree().activeVoxelCount()); EXPECT_EQ(total, pointCount(points->tree())); @@ -234,7 +234,7 @@ TEST_F(TestPointScatter, testUniformPointScatter) points = points::uniformPointScatter(grid, Index64(NUM_VALUES)); - EXPECT_EQ(Index32(1), points->tree().leafCount()); + EXPECT_EQ(Index64(1), points->tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES), points->activeVoxelCount()); EXPECT_EQ(Index64(NUM_VALUES), pointCount(points->tree())); @@ -262,7 +262,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) BoolGrid grid; grid.sparseFill(boxBounds, false, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -270,7 +270,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) DoubleGrid grid; grid.sparseFill(boxBounds, 0.0, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -278,7 +278,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) FloatGrid grid; grid.sparseFill(boxBounds, 0.0f, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -286,7 +286,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) Int32Grid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -294,7 +294,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) Int64Grid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -302,7 +302,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) MaskGrid grid; grid.sparseFill(boxBounds, /*maskBuffer*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -310,7 +310,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) Vec3DGrid grid; grid.sparseFill(boxBounds, Vec3d(), /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -318,7 +318,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) Vec3IGrid grid; grid.sparseFill(boxBounds, Vec3i(), /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -326,7 +326,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) Vec3SGrid grid; grid.sparseFill(boxBounds, Vec3f(), /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -334,7 +334,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) PointDataGrid grid; grid.sparseFill(boxBounds, 0, /*active*/true); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -354,7 +354,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) BoolGrid grid; grid.sparseFill(boxBounds, false, /*active*/true); auto points = points::denseUniformPointScatter(grid, 0.8f); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); // Note that a value of 22 is precomputed as the number of active // voxels/points produced by a value of 0.8 EXPECT_EQ(Index64(22), points->activeVoxelCount()); @@ -373,7 +373,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) const Index32 NUM_VALUES = BoolGrid::TreeType::LeafNodeType::NUM_VALUES; - EXPECT_EQ(Index32(1), grid.tree().leafCount()); + EXPECT_EQ(Index64(1), grid.tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), grid.activeVoxelCount()); auto points = points::denseUniformPointScatter(grid, pointsPerVoxel); @@ -381,7 +381,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) const Index64 expectedCount = Index64(pointsPerVoxel * (NUM_VALUES + 1)); EXPECT_EQ(Index64(0), points->tree().activeTileCount()); - EXPECT_EQ(Index32(2), points->tree().leafCount()); + EXPECT_EQ(Index64(2), points->tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), points->activeVoxelCount()); EXPECT_EQ(expectedCount, pointCount(points->tree())); @@ -462,7 +462,7 @@ TEST_F(TestPointScatter, testDenseUniformPointScatter) points = points::denseUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(2), points->tree().leafCount()); + EXPECT_EQ(Index64(2), points->tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), points->activeVoxelCount()); EXPECT_EQ(expectedCount, pointCount(points->tree())); } @@ -480,7 +480,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, false, /*active*/true); grid.sparseFill(activeBoxBounds, true, /*active*/true); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -489,7 +489,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, 0.0, /*active*/true); grid.sparseFill(activeBoxBounds, 1.0, /*active*/true); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -498,7 +498,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, 0.0f, /*active*/true); grid.sparseFill(activeBoxBounds, 1.0f, /*active*/true); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -507,7 +507,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, 0, /*active*/true); grid.sparseFill(activeBoxBounds, 1, /*active*/true); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -516,7 +516,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, 0, /*active*/true); grid.sparseFill(activeBoxBounds, 1, /*active*/true); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -525,7 +525,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) grid.sparseFill(totalBoxBounds, /*maskBuffer*/0); grid.sparseFill(activeBoxBounds, /*maskBuffer*/1); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(8), points->tree().leafCount()); + EXPECT_EQ(Index64(8), points->tree().leafCount()); EXPECT_EQ(Index64(27), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 27), pointCount(points->tree())); } @@ -543,7 +543,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) const Index32 NUM_VALUES = BoolGrid::TreeType::LeafNodeType::NUM_VALUES; - EXPECT_EQ(Index32(1), grid.tree().leafCount()); + EXPECT_EQ(Index64(1), grid.tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), grid.activeVoxelCount()); auto points = points::nonUniformPointScatter(grid, pointsPerVoxel); @@ -551,7 +551,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) const Index64 expectedCount = Index64(pointsPerVoxel * (NUM_VALUES + 1)); EXPECT_EQ(Index64(0), points->tree().activeTileCount()); - EXPECT_EQ(Index32(2), points->tree().leafCount()); + EXPECT_EQ(Index64(2), points->tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), points->activeVoxelCount()); EXPECT_EQ(expectedCount, pointCount(points->tree())); @@ -637,7 +637,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) points = points::nonUniformPointScatter(countGrid, pointsPerVoxel); - EXPECT_EQ(Index32(1), points->tree().leafCount()); + EXPECT_EQ(Index64(1), points->tree().leafCount()); EXPECT_EQ(Index64(7), points->activeVoxelCount()); EXPECT_EQ(Index64(pointsPerVoxel * 28), pointCount(points->tree())); @@ -656,7 +656,7 @@ TEST_F(TestPointScatter, testNonUniformPointScatter) points = points::nonUniformPointScatter(grid, pointsPerVoxel); - EXPECT_EQ(Index32(2), points->tree().leafCount()); + EXPECT_EQ(Index64(2), points->tree().leafCount()); EXPECT_EQ(Index64(NUM_VALUES + 1), points->activeVoxelCount()); EXPECT_EQ(expectedCount, pointCount(points->tree())); } diff --git a/openvdb/openvdb/unittest/TestTools.cc b/openvdb/openvdb/unittest/TestTools.cc index 931f879614..bc5e1d8f70 100644 --- a/openvdb/openvdb/unittest/TestTools.cc +++ b/openvdb/openvdb/unittest/TestTools.cc @@ -1707,7 +1707,7 @@ TEST_F(TestTools, testPrune) const float value = 5.345f; FloatTree tree(value); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index32(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); @@ -1716,7 +1716,7 @@ TEST_F(TestTools, testPrune) tools::prune(tree); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index32(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); } @@ -1739,17 +1739,17 @@ TEST_F(TestTools, testPrune) FloatTree tree(val); tree.addLeaf(leaf); - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal tools::prune(tree);// tolerance is zero - EXPECT_EQ(Index32(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal tools::prune(tree, tol); - EXPECT_EQ(Index32(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal std::sort(data.begin(), data.end()); @@ -1765,7 +1765,7 @@ TEST_F(TestTools, testPrune) io::File sourceFile("/usr/pic1/Data/OpenVDB/LevelSetModels/crawler.vdb"); sourceFile.open(false);//disable delayed loading FloatGrid::Ptr grid = gridPtrCast(sourceFile.getGrids()->at(0)); - const Index32 leafCount = grid->tree().leafCount(); + const Index64 leafCount = grid->tree().leafCount(); timer.start("\nSerial tolerance prune"); grid->tree().prune(); @@ -1778,7 +1778,7 @@ TEST_F(TestTools, testPrune) io::File sourceFile("/usr/pic1/Data/OpenVDB/LevelSetModels/crawler.vdb"); sourceFile.open(false);//disable delayed loading FloatGrid::Ptr grid = gridPtrCast(sourceFile.getGrids()->at(0)); - const Index32 leafCount = grid->tree().leafCount(); + const Index64 leafCount = grid->tree().leafCount(); timer.start("\nParallel tolerance prune"); tools::prune(grid->tree()); diff --git a/openvdb/openvdb/unittest/TestTree.cc b/openvdb/openvdb/unittest/TestTree.cc index 92ab90a5a1..bb515d0263 100644 --- a/openvdb/openvdb/unittest/TestTree.cc +++ b/openvdb/openvdb/unittest/TestTree.cc @@ -1343,14 +1343,14 @@ TEST_F(TestTree, testTopologyUnion) tree0.addTile(1, xyz, true, true); // leaf level tile tree1.touchLeaf(xyz)->setValueOn(0); // single leaf tree0.topologyUnion(tree1, true); // single tile - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(LeafT::NUM_VOXELS), tree0.activeVoxelCount()); tree1.addTile(1, xyz + openvdb::Coord(8), true, true); // leaf + tile tree0.topologyUnion(tree1, true); // two tiles - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(2), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(LeafT::NUM_VOXELS*2), tree0.activeVoxelCount()); @@ -1359,7 +1359,7 @@ TEST_F(TestTree, testTopologyUnion) tree0.clear(); tree0.addTile(2, xyz, true, true); tree0.topologyUnion(tree1, true); // all topology in tree1 is already active. no change - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); EXPECT_EQ(openvdb::Index32(2), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(InternalT1::NUM_VOXELS), tree0.activeVoxelCount()); @@ -1368,7 +1368,7 @@ TEST_F(TestTree, testTopologyUnion) tree0.clear(); tree0.addTile(3, xyz, true, true); tree0.topologyUnion(tree1, true); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(InternalT2::NUM_VOXELS), tree0.activeVoxelCount()); @@ -1379,7 +1379,7 @@ TEST_F(TestTree, testTopologyUnion) tree0.addTile(1, xyz, true, true); tree1.addTile(2, xyz, true, true); tree0.topologyUnion(tree1, true); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); openvdb::Index64 tiles = openvdb::Index64(InternalT1::DIM) / InternalT1::getChildDim(); tiles = tiles * tiles * tiles; @@ -1429,22 +1429,22 @@ TEST_F(TestTree, testTopologyIntersection) tree0.setValue(openvdb::Coord( 400, 30, 20), 2.0f); tree0.setValue(openvdb::Coord( 8, 11, 11), 3.0f); EXPECT_EQ(openvdb::Index64(3), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree0.leafCount() ); tree1.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree1.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree1.setValue(openvdb::Coord( 8, 11, 11), 6.0f); EXPECT_EQ(openvdb::Index64(3), tree1.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree1.leafCount() ); tree1.topologyIntersection(tree0); - EXPECT_EQ( openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(3), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(2), tree1.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); openvdb::tools::pruneInactive(tree1); EXPECT_TRUE(!tree1.empty()); - EXPECT_EQ( openvdb::Index32(2), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(2), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(2), tree1.activeVoxelCount() ); } {//passive tile @@ -1453,17 +1453,17 @@ TEST_F(TestTree, testTopologyIntersection) openvdb::FloatTree tree0(background), tree1(background); tree0.fill(openvdb::CoordBBox(openvdb::Coord(0),openvdb::Coord(dim-1)),2.0f, false); EXPECT_EQ(openvdb::Index64(0), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount() ); tree1.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree1.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree1.setValue(openvdb::Coord( dim, 11, 11), 6.0f); - EXPECT_EQ(openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree1.leafCount() ); EXPECT_EQ(openvdb::Index64(3), tree1.activeVoxelCount()); tree1.topologyIntersection(tree0); - EXPECT_EQ( openvdb::Index32(0), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(0), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(0), tree1.activeVoxelCount() ); EXPECT_TRUE(tree1.empty()); } @@ -1473,17 +1473,17 @@ TEST_F(TestTree, testTopologyIntersection) openvdb::FloatTree tree0(background), tree1(background); tree1.fill(openvdb::CoordBBox(openvdb::Coord(0),openvdb::Coord(dim-1)),2.0f, true); EXPECT_EQ(dim*dim*dim, tree1.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(0), tree1.leafCount() ); + EXPECT_EQ(openvdb::Index64(0), tree1.leafCount() ); tree0.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree0.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree0.setValue(openvdb::Coord( dim, 11, 11), 6.0f); EXPECT_EQ(openvdb::Index64(3), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree0.leafCount() ); tree1.topologyIntersection(tree0); - EXPECT_EQ( openvdb::Index32(2), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(2), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(2), tree1.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); openvdb::tools::pruneInactive(tree1); @@ -1522,10 +1522,10 @@ TEST_F(TestTree, testTopologyIntersection) tree3.setValue(iter.getCoord(), vec_val); } - EXPECT_EQ(openvdb::Index32(4), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(4), tree1.leafCount()); - EXPECT_EQ(openvdb::Index32(7), tree2.leafCount()); - EXPECT_EQ(openvdb::Index32(7), tree3.leafCount()); + EXPECT_EQ(openvdb::Index64(4), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(4), tree1.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree2.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree3.leafCount()); //tree1.topologyInterection(tree2);//should make tree1 = tree0 @@ -1673,22 +1673,22 @@ TEST_F(TestTree, testTopologyDifference) tree0.setValue(openvdb::Coord( 400, 30, 20), 2.0f); tree0.setValue(openvdb::Coord( 8, 11, 11), 3.0f); EXPECT_EQ(openvdb::Index64(3), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree0.leafCount() ); tree1.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree1.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree1.setValue(openvdb::Coord( 8, 11, 11), 6.0f); EXPECT_EQ(openvdb::Index64(3), tree1.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree1.leafCount() ); tree1.topologyDifference(tree0); - EXPECT_EQ( openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(3), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(1), tree1.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); openvdb::tools::pruneInactive(tree1); EXPECT_TRUE(!tree1.empty()); - EXPECT_EQ( openvdb::Index32(1), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(1), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(1), tree1.activeVoxelCount() ); } {//passive tile @@ -1699,22 +1699,22 @@ TEST_F(TestTree, testTopologyDifference) EXPECT_EQ(openvdb::Index64(0), tree0.activeVoxelCount()); EXPECT_TRUE(!tree0.hasActiveTiles()); EXPECT_EQ(openvdb::Index64(0), tree0.root().onTileCount()); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount() ); tree1.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree1.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree1.setValue(openvdb::Coord( dim, 11, 11), 6.0f); EXPECT_EQ(openvdb::Index64(3), tree1.activeVoxelCount()); EXPECT_TRUE(!tree1.hasActiveTiles()); - EXPECT_EQ(openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree1.leafCount() ); tree1.topologyDifference(tree0); - EXPECT_EQ( openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(3), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(3), tree1.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); openvdb::tools::pruneInactive(tree1); - EXPECT_EQ( openvdb::Index32(3), tree1.leafCount() ); + EXPECT_EQ( openvdb::Index64(3), tree1.leafCount() ); EXPECT_EQ( openvdb::Index64(3), tree1.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); } @@ -1726,14 +1726,14 @@ TEST_F(TestTree, testTopologyDifference) EXPECT_EQ(dim*dim*dim, tree1.activeVoxelCount()); EXPECT_TRUE(tree1.hasActiveTiles()); EXPECT_EQ(openvdb::Index64(1), tree1.root().onTileCount()); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount() ); tree0.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree0.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree0.setValue(openvdb::Coord( int(dim), 11, 11), 6.0f); EXPECT_TRUE(!tree0.hasActiveTiles()); EXPECT_EQ(openvdb::Index64(3), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree0.leafCount() ); EXPECT_TRUE( tree0.isValueOn(openvdb::Coord( int(dim), 11, 11))); EXPECT_TRUE(!tree1.isValueOn(openvdb::Coord( int(dim), 11, 11))); @@ -1754,22 +1754,22 @@ TEST_F(TestTree, testTopologyDifference) EXPECT_EQ(dim*dim*dim, tree1.activeVoxelCount()); EXPECT_TRUE(tree1.hasActiveTiles()); EXPECT_EQ(openvdb::Index64(1), tree1.root().onTileCount()); - EXPECT_EQ(openvdb::Index32(0), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(0), tree0.leafCount() ); tree0.setValue(openvdb::Coord( 500, 301, 200), 4.0f); tree0.setValue(openvdb::Coord( 400, 30, 20), 5.0f); tree0.setValue(openvdb::Coord( dim, 11, 11), 6.0f); EXPECT_TRUE(!tree0.hasActiveTiles()); EXPECT_EQ(openvdb::Index64(3), tree0.activeVoxelCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.leafCount() ); + EXPECT_EQ(openvdb::Index64(3), tree0.leafCount() ); tree0.topologyDifference(tree1); - EXPECT_EQ( openvdb::Index32(1), tree0.leafCount() ); + EXPECT_EQ( openvdb::Index64(1), tree0.leafCount() ); EXPECT_EQ( openvdb::Index64(1), tree0.activeVoxelCount() ); EXPECT_TRUE(!tree0.empty()); openvdb::tools::pruneInactive(tree0); - EXPECT_EQ( openvdb::Index32(1), tree0.leafCount() ); + EXPECT_EQ( openvdb::Index64(1), tree0.leafCount() ); EXPECT_EQ( openvdb::Index64(1), tree0.activeVoxelCount() ); EXPECT_TRUE(!tree1.empty()); } @@ -1806,10 +1806,10 @@ TEST_F(TestTree, testTopologyDifference) tree3.setValue(iter.getCoord(), vec_val); } - EXPECT_EQ(openvdb::Index32(4), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(4), tree1.leafCount()); - EXPECT_EQ(openvdb::Index32(7), tree2.leafCount()); - EXPECT_EQ(openvdb::Index32(7), tree3.leafCount()); + EXPECT_EQ(openvdb::Index64(4), tree0.leafCount()); + EXPECT_EQ(openvdb::Index64(4), tree1.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree2.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree3.leafCount()); //tree1.topologyInterection(tree2);//should make tree1 = tree0 @@ -2094,16 +2094,16 @@ TEST_F(TestTree, testPruneInactive) tree.setValue(Coord( 5, 10,-20), 0.3f); // Verify that the tree has the expected numbers of active voxels and leaf nodes. EXPECT_EQ(Index64(8), tree.activeVoxelCount()); - EXPECT_EQ(Index32(8), tree.leafCount()); + EXPECT_EQ(Index64(8), tree.leafCount()); // Verify that prune() has no effect, since the values are all different. openvdb::tools::prune(tree); EXPECT_EQ(Index64(8), tree.activeVoxelCount()); - EXPECT_EQ(Index32(8), tree.leafCount()); + EXPECT_EQ(Index64(8), tree.leafCount()); // Verify that pruneInactive() has no effect, since the values are active. openvdb::tools::pruneInactive(tree); EXPECT_EQ(Index64(8), tree.activeVoxelCount()); - EXPECT_EQ(Index32(8), tree.leafCount()); + EXPECT_EQ(Index64(8), tree.leafCount()); // Make some of the active values inactive, without changing their values. tree.setValueOff(Coord(-5, 10, 20)); @@ -2111,15 +2111,15 @@ TEST_F(TestTree, testPruneInactive) tree.setValueOff(Coord(-5, 10,-20)); tree.setValueOff(Coord(-5,-10,-20)); EXPECT_EQ(Index64(4), tree.activeVoxelCount()); - EXPECT_EQ(Index32(8), tree.leafCount()); + EXPECT_EQ(Index64(8), tree.leafCount()); // Verify that prune() has no effect, since the values are still different. openvdb::tools::prune(tree); EXPECT_EQ(Index64(4), tree.activeVoxelCount()); - EXPECT_EQ(Index32(8), tree.leafCount()); + EXPECT_EQ(Index64(8), tree.leafCount()); // Verify that pruneInactive() prunes the nodes containing only inactive voxels. openvdb::tools::pruneInactive(tree); EXPECT_EQ(Index64(4), tree.activeVoxelCount()); - EXPECT_EQ(Index32(4), tree.leafCount()); + EXPECT_EQ(Index64(4), tree.leafCount()); // Make all of the active values inactive, without changing their values. tree.setValueOff(Coord( 5, 10, 20)); @@ -2127,11 +2127,11 @@ TEST_F(TestTree, testPruneInactive) tree.setValueOff(Coord( 5,-10,-20)); tree.setValueOff(Coord( 5, 10,-20)); EXPECT_EQ(Index64(0), tree.activeVoxelCount()); - EXPECT_EQ(Index32(4), tree.leafCount()); + EXPECT_EQ(Index64(4), tree.leafCount()); // Verify that prune() has no effect, since the values are still different. openvdb::tools::prune(tree); EXPECT_EQ(Index64(0), tree.activeVoxelCount()); - EXPECT_EQ(Index32(4), tree.leafCount()); + EXPECT_EQ(Index64(4), tree.leafCount()); // Verify that pruneInactive() prunes all of the remaining leaf nodes. openvdb::tools::pruneInactive(tree); EXPECT_TRUE(tree.empty()); @@ -2158,7 +2158,7 @@ TEST_F(TestTree, testPruneLevelSet) } } - const openvdb::Index32 leafCount = tree.leafCount(); + const openvdb::Index64 leafCount = tree.leafCount(); EXPECT_EQ(tree.activeVoxelCount(), count); EXPECT_EQ(tree.activeLeafVoxelCount(), count); @@ -2646,6 +2646,7 @@ TEST_F(TestTree, testStealNodes) TEST_F(TestTree, testStealNode) { using openvdb::Index; + using openvdb::Index64; using openvdb::FloatTree; const float background=0.0f, value = 5.6f, epsilon=0.000001f; @@ -2656,19 +2657,19 @@ TEST_F(TestTree, testStealNode) EXPECT_EQ(Index(0), NodeT::getLevel()); FloatTree tree(background); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); tree.setValue(xyz, value); - EXPECT_EQ(Index(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_TRUE(tree.isValueOn(xyz)); EXPECT_NEAR(value, tree.getValue(xyz), epsilon); NodeT* node = tree.root().stealNode(xyz, background, false); EXPECT_TRUE(node != nullptr); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); @@ -2681,19 +2682,19 @@ TEST_F(TestTree, testStealNode) EXPECT_EQ(Index(1), NodeT::getLevel()); FloatTree tree(background); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); tree.setValue(xyz, value); - EXPECT_EQ(Index(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_TRUE(tree.isValueOn(xyz)); EXPECT_NEAR(value, tree.getValue(xyz), epsilon); NodeT* node = tree.root().stealNode(xyz, background, false); EXPECT_TRUE(node != nullptr); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); @@ -2706,19 +2707,19 @@ TEST_F(TestTree, testStealNode) EXPECT_EQ(Index(2), NodeT::getLevel()); FloatTree tree(background); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); tree.setValue(xyz, value); - EXPECT_EQ(Index(1), tree.leafCount()); + EXPECT_EQ(Index64(1), tree.leafCount()); EXPECT_TRUE(tree.isValueOn(xyz)); EXPECT_NEAR(value, tree.getValue(xyz), epsilon); NodeT* node = tree.root().stealNode(xyz, background, false); EXPECT_TRUE(node != nullptr); - EXPECT_EQ(Index(0), tree.leafCount()); + EXPECT_EQ(Index64(0), tree.leafCount()); EXPECT_TRUE(!tree.isValueOn(xyz)); EXPECT_NEAR(background, tree.getValue(xyz), epsilon); EXPECT_TRUE(tree.root().stealNode(xyz, value, false) == nullptr); @@ -2743,7 +2744,7 @@ TEST_F(TestTree, testNodeCount) std::vector dims; tree.getNodeLog2Dims(dims); - std::vector nodeCount1(dims.size()); + std::vector nodeCount1(dims.size()); //timer.start("Old technique");// use for benchmark test for (auto it = tree.cbeginNode(); it; ++it) ++(nodeCount1[dims.size()-1-it.getDepth()]); //timer.restart("New technique");// use for benchmark test @@ -2868,7 +2869,7 @@ TEST_F(TestTree, testInternalNode) internalNode.touchLeaf(c2); internalNode.touchLeaf(c3); - EXPECT_EQ(openvdb::Index(2), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(2), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); EXPECT_TRUE(!internalNode.hasActiveTiles()); @@ -2885,14 +2886,14 @@ TEST_F(TestTree, testInternalNode) // steal the internal node children leaving it empty again std::vector children; internalNode.stealNodes(children, 0.0f, false); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); // insert the root node children directly for (ChildType* child : children) { internalNode.addChild(child); } - EXPECT_EQ(openvdb::Index(2), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(2), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); { // verify the coordinates of the root node children @@ -2906,19 +2907,19 @@ TEST_F(TestTree, testInternalNode) { // test inserting a tile and replacing with a child node InternalNodeType internalNode(c1, 0.0f); EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); // add a tile internalNode.addTile(openvdb::Index(0), /*value=*/1.0f, /*state=*/true); EXPECT_TRUE(internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(0), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); // replace the tile with a child node EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 2.0f))); EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index(1), internalNode.leafCount()); + EXPECT_EQ(openvdb::Index64(1), internalNode.leafCount()); EXPECT_EQ(openvdb::Index32(1), internalNode.childCount()); EXPECT_EQ(c1, internalNode.cbeginChildOn().getCoord()); ASSERT_DOUBLES_EXACTLY_EQUAL(2.0f, internalNode.cbeginChildOn()->getValue(0)); diff --git a/openvdb/openvdb/unittest/TestTreeGetSetValues.cc b/openvdb/openvdb/unittest/TestTreeGetSetValues.cc index 27dcf9e89d..834b594510 100644 --- a/openvdb/openvdb/unittest/TestTreeGetSetValues.cc +++ b/openvdb/openvdb/unittest/TestTreeGetSetValues.cc @@ -224,17 +224,17 @@ TEST_F(TestTreeGetSetValues, testFill) // The following tests assume a [3,2,3] tree configuration. tree.clear(); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node // Partially fill a single leaf node. tree.fill(CoordBBox(Coord(8), Coord(14)), 0.0); - EXPECT_EQ(openvdb::Index32(1), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); // Completely fill the leaf node, replacing it with a tile. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); { @@ -242,81 +242,81 @@ TEST_F(TestTreeGetSetValues, testFill) // Fill a single voxel of the tile with a different (active) value. tree.fill(CoordBBox(Coord(10), Coord(10)), 1.0); - EXPECT_EQ(openvdb::Index32(1), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); EXPECT_EQ(activeVoxelCount, int(tree.activeVoxelCount())); // Fill the voxel with an inactive value. tree.fill(CoordBBox(Coord(10), Coord(10)), 1.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(1), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); EXPECT_EQ(activeVoxelCount - 1, int(tree.activeVoxelCount())); // Completely fill the leaf node, replacing it with a tile again. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); } // Expand by one voxel, creating seven neighboring leaf nodes. tree.fill(CoordBBox(Coord(8), Coord(16)), 0.0); - EXPECT_EQ(openvdb::Index32(7), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); // Completely fill the internal node containing the tile, replacing it with // a tile at the next level of the tree. tree.fill(CoordBBox(Coord(0), Coord(31)), 0.0); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(2), tree.nonLeafCount()); // Expand by one voxel, creating a layer of leaf nodes on three faces. tree.fill(CoordBBox(Coord(0), Coord(32)), 0.0); - EXPECT_EQ(openvdb::Index32(5*5 + 4*5 + 4*4), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(5*5 + 4*5 + 4*4), tree.leafCount()); EXPECT_EQ(openvdb::Index32(2 + 7), tree.nonLeafCount()); // +7 internal nodes // Completely fill the second-level internal node, replacing it with a root-level tile. tree.fill(CoordBBox(Coord(0), Coord(255)), 0.0); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // Repeat, filling with an inactive value. tree.clear(); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node // Partially fill a single leaf node. tree.fill(CoordBBox(Coord(8), Coord(14)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(1), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); // Completely fill the leaf node, replacing it with a tile. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); // Expand by one voxel, creating seven neighboring leaf nodes. tree.fill(CoordBBox(Coord(8), Coord(16)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(7), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(7), tree.leafCount()); EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); // Completely fill the internal node containing the tile, replacing it with // a tile at the next level of the tree. tree.fill(CoordBBox(Coord(0), Coord(31)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(2), tree.nonLeafCount()); // Expand by one voxel, creating a layer of leaf nodes on three faces. tree.fill(CoordBBox(Coord(0), Coord(32)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(5*5 + 4*5 + 4*4), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(5*5 + 4*5 + 4*4), tree.leafCount()); EXPECT_EQ(openvdb::Index32(2 + 7), tree.nonLeafCount()); // +7 internal nodes // Completely fill the second-level internal node, replacing it with a root-level tile. tree.fill(CoordBBox(Coord(0), Coord(255)), 0.0, /*active=*/false); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); tree.clear(); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); @@ -324,7 +324,7 @@ TEST_F(TestTreeGetSetValues, testFill) tree.fill(CoordBBox(Coord(27), Coord(254)), background, /*active=*/false); // Confirm that after pruning, the tree is empty. openvdb::tools::prune(tree); - EXPECT_EQ(openvdb::Index32(0), tree.leafCount()); + EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); } diff --git a/openvdb/openvdb/unittest/TestValueAccessor.cc b/openvdb/openvdb/unittest/TestValueAccessor.cc index 24d33afda5..8afa873c04 100644 --- a/openvdb/openvdb/unittest/TestValueAccessor.cc +++ b/openvdb/openvdb/unittest/TestValueAccessor.cc @@ -587,6 +587,7 @@ TEST_F(TestValueAccessor, testMultiThreadedRWAccessors) TEST_F(TestValueAccessor, testAccessorRegistration) { using openvdb::Index; + using openvdb::Index64; const float background = 5.0f, value = -9.345f; const openvdb::Coord c0(5, 10, 20); @@ -597,14 +598,14 @@ TEST_F(TestValueAccessor, testAccessorRegistration) // Set a single leaf voxel via the accessor and verify that // the cache is populated. acc.setValue(c0, value); - EXPECT_EQ(Index(1), tree->leafCount()); + EXPECT_EQ(Index64(1), tree->leafCount()); EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); // Reset the voxel to the background value and verify that no nodes // have been deleted and that the cache is still populated. tree->setValueOff(c0, background); - EXPECT_EQ(Index(1), tree->leafCount()); + EXPECT_EQ(Index64(1), tree->leafCount()); EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); @@ -612,13 +613,13 @@ TEST_F(TestValueAccessor, testAccessorRegistration) // the cache has been cleared. openvdb::tools::prune(*tree); //tree->prune(); - EXPECT_EQ(Index(0), tree->leafCount()); + EXPECT_EQ(Index64(0), tree->leafCount()); EXPECT_EQ(Index(1), tree->nonLeafCount()); // root node only EXPECT_TRUE(acc.getNode() == nullptr); // Set the leaf voxel again and verify that the cache is repopulated. acc.setValue(c0, value); - EXPECT_EQ(Index(1), tree->leafCount()); + EXPECT_EQ(Index64(1), tree->leafCount()); EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); From a24c8631bc118a7ae382f63d132fd0379d6261cc Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:20:12 -0400 Subject: [PATCH 23/98] Update Tree.h Correct type for variable. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/Tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index 22799f3cf1..d7110c1f42 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -2036,7 +2036,7 @@ Tree::print(std::ostream& os, int verboseLevel) const } const auto nodeCount = this->nodeCount();//fast - const Index32 leafCount = nodeCount.front();// leaf is the first element + const Index64 leafCount = nodeCount.front();// leaf is the first element OPENVDB_ASSERT(dims.size() == nodeCount.size()); Index64 totalNodeCount = 0; From 1f7798d6c6d0504a808faf4f8995b4572cbf3a33 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:21:16 -0400 Subject: [PATCH 24/98] Update CMakeLists.txt Turns off OPENVDB_BUILD_UNITTESTS. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75d895f39d..230539d88d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ include(GNUInstallDirs) 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" ON) +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) From f13a0a8524aa2706a993eed0609837196e15f154 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:08:33 -0400 Subject: [PATCH 25/98] Index64 leafCount in AX tests Use Index64 for tree's leafCount. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- .../test/compiler/TestPointExecutable.cc | 6 +++--- .../test/compiler/TestVolumeExecutable.cc | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc b/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc index 2e5ad4fdcc..14da8b3828 100644 --- a/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc +++ b/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc @@ -545,7 +545,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index32(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); // collapsed uniform 0 attributes points::appendAttribute(points->tree(), "f"); @@ -641,7 +641,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index32(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); // collapsed uniform 0 attributes points::appendAttribute>(points->tree(), "fpu8"); @@ -728,7 +728,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid , points::PointDataGrid> (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index32(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); points::appendAttribute(points->tree(), "t"); points::appendAttribute>(points->tree(), "f"); diff --git a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc index 2a00ae6703..e84ec2c1c3 100644 --- a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc +++ b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc @@ -155,7 +155,7 @@ TestVolumeExecutable::testTreeExecutionLevel() const openvdb::FloatTree copy = tree; // check config auto CHECK_CONFIG = [&]() { - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(3), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-4), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); @@ -357,7 +357,7 @@ TestVolumeExecutable::testActiveTileStreaming() CPPUNIT_ASSERT_EQUAL(openvdb::Index(openvdb::FloatTree::DEPTH-1), max); executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(3), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-4), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); @@ -404,7 +404,7 @@ TestVolumeExecutable::testActiveTileStreaming() openvdb::Index64(NodeT1::NUM_VOXELS) + openvdb::Index64(NodeT0::NUM_VOXELS); - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-1), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-1), tree.getValueDepth(openvdb::Coord(NodeT1::DIM))); @@ -463,7 +463,7 @@ TestVolumeExecutable::testActiveTileStreaming() ((n1ChildCount * (n2ChildAxisCount * n2ChildAxisCount)) - leafs) // NodeT1 face tiles (NodeT0) - leafs + 1 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-2), tree.getValueDepth(openvdb::Coord(NodeT2::DIM+NodeT1::DIM))); @@ -512,7 +512,7 @@ TestVolumeExecutable::testActiveTileStreaming() executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(0), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(5), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*0, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); @@ -567,7 +567,7 @@ TestVolumeExecutable::testActiveTileStreaming() (n1ChildCount - leafs) // NodeT1 face tiles (NodeT0) - leafs + 3 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::BoolTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::BoolTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*2, 0, 0))); @@ -624,7 +624,7 @@ TestVolumeExecutable::testActiveTileStreaming() (n1ChildCount - leafs) // NodeT1 face tiles (NodeT0) - leafs + 3 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(StringTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(StringTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*2, 0, 0))); @@ -668,7 +668,7 @@ TestVolumeExecutable::testActiveTileStreaming() executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(2), tree.activeTileCount()); CPPUNIT_ASSERT(tree.hasSameTopology(copy)); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(0))); @@ -715,7 +715,7 @@ TestVolumeExecutable::testActiveTileStreaming() openvdb::Index64(NodeT1::NUM_VOXELS) + openvdb::Index64(NodeT0::NUM_VOXELS); - CPPUNIT_ASSERT_EQUAL(openvdb::Index32(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS) + 1, tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(openvdb::Index64(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS) + 1, tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(voxels, tree.activeVoxelCount()); CPPUNIT_ASSERT_EQUAL(leaf, tree.probeLeaf(openvdb::Coord(NodeT1::DIM + NodeT0::DIM))); From fcff36445a4f7696aabf92f2aeffb9163bb2050c Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:23:29 -0400 Subject: [PATCH 26/98] Update TestNodeVisitor.cc Correct type for nodeCount members. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/unittest/TestNodeVisitor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/unittest/TestNodeVisitor.cc b/openvdb/openvdb/unittest/TestNodeVisitor.cc index 8ab14d4cfd..e4154544a8 100644 --- a/openvdb/openvdb/unittest/TestNodeVisitor.cc +++ b/openvdb/openvdb/unittest/TestNodeVisitor.cc @@ -144,7 +144,7 @@ TEST_F(TestNodeVisitor, testOriginArray) std::vector nodeCount = grid->tree().nodeCount(); Index64 totalNodeCount(0); - for (Index32 count : nodeCount) totalNodeCount += count; + for (Index64 count : nodeCount) totalNodeCount += count; // use an offset size_t offset = 10; From 30e24e132998f02912cb1b008b1f8bac4ec77c66 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 8 Oct 2024 21:35:42 -0700 Subject: [PATCH 27/98] Delete some unused private methods on RootNode Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 5eb7794115..af47cd6646 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -898,15 +898,6 @@ class RootNode template friend struct RootNodeCopyHelper; template friend struct RootNodeCombineHelper; - /// Currently no-op, but can be used to define empty and delete keys for mTable - void initTable() {} - //@{ - /// @internal Used by doVisit2(). - void resetTable(MapType& table) { mTable.swap(table); table.clear(); } - void resetTable(const MapType&) const {} - //@} - - Index getChildCount() const; Index getTileCount() const; Index getActiveTileCount() const; Index getInactiveTileCount() const; @@ -1025,7 +1016,6 @@ RootNode::RootNode() : mBackground(zeroVal()) , mOrigin(0, 0, 0) { - this->initTable(); } @@ -1035,7 +1025,6 @@ RootNode::RootNode(const ValueType& background) : mBackground(background) , mOrigin(0, 0, 0) { - this->initTable(); } @@ -1057,7 +1046,6 @@ RootNode::RootNode(const RootNode& other, enforceSameConfiguration(other); const Tile bgTile(backgd, /*active=*/false), fgTile(foregd, true); - this->initTable(); for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) { mTable[i->first] = OtherRootT::isTile(i) @@ -1085,7 +1073,7 @@ RootNode::RootNode(const RootNode& other, enforceSameConfiguration(other); const Tile bgTile(backgd, /*active=*/false), fgTile(backgd, true); - this->initTable(); + for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) { mTable[i->first] = OtherRootT::isTile(i) ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile) @@ -1144,7 +1132,6 @@ struct RootNodeCopyHelper self.mTransientData = other.mTransientData; self.clear(); - self.initTable(); for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) { if (other.isTile(i)) { @@ -1175,7 +1162,6 @@ RootNode::operator=(const RootNode& other) mTransientData = other.mTransientData; this->clear(); - this->initTable(); for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) { mTable[i->first] = @@ -1498,13 +1484,6 @@ RootNode::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const } -template -inline Index -RootNode::getChildCount() const { - return this->childCount(); -} - - template inline Index RootNode::getTileCount() const @@ -2336,7 +2315,6 @@ RootNode::readTopology(std::istream& is, bool fromHalf) is.read(reinterpret_cast(rangeMin.asPointer()), 3 * sizeof(Int32)); is.read(reinterpret_cast(rangeMax.asPointer()), 3 * sizeof(Int32)); - this->initTable(); Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 }; Int32 offset[3]; for (int i = 0; i < 3; ++i) { From eee04931e26c0518fc626f892420d9dd28df2229 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 8 Oct 2024 21:43:50 -0700 Subject: [PATCH 28/98] Make tileCount(), activeTileCount(), inactiveTileCount() public Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 55 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index af47cd6646..7b6e9d8ca9 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -486,6 +486,9 @@ class RootNode Index32 leafCount() const; Index32 nonLeafCount() const; Index32 childCount() const; + Index32 tileCount() const; + Index32 activeTileCount() const; + Index32 inactiveTileCount() const; Index64 onVoxelCount() const; Index64 offVoxelCount() const; Index64 onLeafVoxelCount() const; @@ -898,10 +901,6 @@ class RootNode template friend struct RootNodeCopyHelper; template friend struct RootNodeCombineHelper; - Index getTileCount() const; - Index getActiveTileCount() const; - Index getInactiveTileCount() const; - /// Return a MapType key for the given coordinates, offset by the mOrigin. Coord coordToKey(const Coord& xyz) const { return (xyz - mOrigin) & ~(ChildType::DIM - 1); } @@ -1485,36 +1484,38 @@ RootNode::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const template -inline Index -RootNode::getTileCount() const +inline Index32 +RootNode::leafCount() const { - Index sum = 0; + Index32 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTile(i)) ++sum; + if (isChild(i)) sum += getChild(i).leafCount(); } return sum; } template -inline Index -RootNode::getActiveTileCount() const +inline Index32 +RootNode::nonLeafCount() const { - Index sum = 0; - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTileOn(i)) ++sum; + Index32 sum = 1; + if (ChildT::LEVEL != 0) { + for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { + if (isChild(i)) sum += getChild(i).nonLeafCount(); + } } return sum; } template -inline Index -RootNode::getInactiveTileCount() const +inline Index32 +RootNode::childCount() const { Index sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTileOff(i)) ++sum; + if (isChild(i)) ++sum; } return sum; } @@ -1522,11 +1523,11 @@ RootNode::getInactiveTileCount() const template inline Index32 -RootNode::leafCount() const +RootNode::tileCount() const { Index32 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) sum += getChild(i).leafCount(); + if (isTile(i)) ++sum; } return sum; } @@ -1534,13 +1535,11 @@ RootNode::leafCount() const template inline Index32 -RootNode::nonLeafCount() const +RootNode::activeTileCount() const { - Index32 sum = 1; - if (ChildT::LEVEL != 0) { - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) sum += getChild(i).nonLeafCount(); - } + Index32 sum = 0; + for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { + if (isTileOn(i)) ++sum; } return sum; } @@ -1548,11 +1547,11 @@ RootNode::nonLeafCount() const template inline Index32 -RootNode::childCount() const +RootNode::inactiveTileCount() const { - Index sum = 0; + Index32 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) ++sum; + if (isTileOff(i)) ++sum; } return sum; } @@ -2268,7 +2267,7 @@ RootNode::writeTopology(std::ostream& os, bool toHalf) const } io::setGridBackgroundValuePtr(os, &mBackground); - const Index numTiles = this->getTileCount(), numChildren = this->childCount(); + const Index numTiles = this->tileCount(), numChildren = this->childCount(); os.write(reinterpret_cast(&numTiles), sizeof(Index)); os.write(reinterpret_cast(&numChildren), sizeof(Index)); From bee795bc93ba0a7ffef19a969b607c414a9de166 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 8 Oct 2024 21:44:16 -0700 Subject: [PATCH 29/98] Make hasKey() and coordToKey() public Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 7b6e9d8ca9..a963c43439 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -893,6 +893,12 @@ class RootNode /// other tools do not yet support variable offsets. void setOrigin(const Coord &origin); + /// Return a MapType key for the given coordinates, offset by the mOrigin. + Coord coordToKey(const Coord& xyz) const { return (xyz - mOrigin) & ~(ChildType::DIM - 1); } + + /// Return @c true if this node's mTable contains the given key. + bool hasKey(const Coord& key) const { return mTable.find(key) != mTable.end(); } + private: /// During topology-only construction, access is needed /// to protected/private members of other template instances. @@ -901,14 +907,9 @@ class RootNode template friend struct RootNodeCopyHelper; template friend struct RootNodeCombineHelper; - /// Return a MapType key for the given coordinates, offset by the mOrigin. - Coord coordToKey(const Coord& xyz) const { return (xyz - mOrigin) & ~(ChildType::DIM - 1); } - /// Insert this node's mTable keys into the given set. void insertKeys(CoordSet&) const; - /// Return @c true if this node's mTable contains the given key. - bool hasKey(const Coord& key) const { return mTable.find(key) != mTable.end(); } //@{ /// @brief Look up the given key in this node's mTable. /// @return an iterator pointing to the matching mTable entry or to mTable.end(). From 937e5fa77746540b1c76af95db805edb5a910df4 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 14:50:59 -0700 Subject: [PATCH 30/98] Fix a bug in the setOrigin() call Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index a963c43439..cf6e17c526 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -2609,10 +2609,10 @@ template inline void RootNode::setOrigin(const Coord &origin) { - mOrigin = origin; - if (mOrigin != Coord(0,0,0)) { + if (origin != Coord(0,0,0)) { OPENVDB_THROW(ValueError, "RootNode::setOrigin: non-zero offsets are currently not supported"); } + mOrigin = origin; } template From a984443642418ffbe20cd1e7ad68aea321d63a75 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 8 Oct 2024 23:10:58 -0700 Subject: [PATCH 31/98] Add RootNode::deleteChildOrTile() Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index cf6e17c526..8b54f4413b 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -709,6 +709,11 @@ class RootNode template void addTileAndCache(Index level, const Coord& xyz, const ValueType&, bool state, AccessorT&); + /// @brief Delete any child or tile containing voxel (x, y, z) at the root level. + /// Do nothing if no child or tile was found. + /// @return @c true if child or tile was deleted + bool deleteChildOrTile(const Coord& xyz); + /// @brief Return a pointer to the leaf node that contains voxel (x, y, z). /// If no such node exists, create one that preserves the values and /// active states of all voxels. @@ -2700,6 +2705,15 @@ RootNode::addTileAndCache(Index level, const Coord& xyz, const ValueType } +template +inline bool +RootNode::deleteChildOrTile(const Coord& xyz) +{ + Coord key = this->coordToKey(xyz); + return mTable.erase(key) == size_t(1); +} + + //////////////////////////////////////// From 0cda152ee62c38e5d05cf3d4687f985945d6f482 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 11:59:49 -0700 Subject: [PATCH 32/98] Extend RootNode unit test to support map and delete test cases Signed-off-by: Dan Bailey --- openvdb/openvdb/unittest/TestRootNode.cc | 353 +++++++++++++++++++++++ 1 file changed, 353 insertions(+) diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index 16be294068..ef9302dda4 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -110,3 +110,356 @@ TEST_F(TestRoot, test) EXPECT_EQ(Index32(5), rootNode3.transientData()); } } + +TEST_F(TestRoot, testMap) +{ + using RootNode = FloatTree::RootNodeType; + + { // empty root node + RootNode root(1.0f); + + // background checks + + EXPECT_EQ(root.background(), 1.0f); + root.setBackground(2.0f, false); + EXPECT_EQ(root.background(), 2.0f); + EXPECT_EQ(root.numBackgroundTiles(), 0); + + // count checks + + EXPECT_TRUE(root.empty()); + EXPECT_FALSE(root.hasActiveTiles()); + EXPECT_EQ(root.getTableSize(), 0); + EXPECT_EQ(root.leafCount(), 0); + EXPECT_EQ(root.nonLeafCount(), 1); // root counts as a node + EXPECT_EQ(root.childCount(), 0); + EXPECT_EQ(root.tileCount(), 0); + EXPECT_EQ(root.activeTileCount(), 0); + EXPECT_EQ(root.inactiveTileCount(), 0); + + EXPECT_EQ(root.onVoxelCount(), 0); + EXPECT_EQ(root.offVoxelCount(), 0); + EXPECT_EQ(root.onLeafVoxelCount(), 0); + EXPECT_EQ(root.offLeafVoxelCount(), 0); + EXPECT_EQ(root.onTileCount(), 0); + + // bounding box checks + + EXPECT_EQ(root.getMinIndex(), Coord()); + EXPECT_EQ(root.getMaxIndex(), Coord()); + EXPECT_EQ(root.getWidth(), 0); + EXPECT_EQ(root.getHeight(), 0); + EXPECT_EQ(root.getDepth(), 0); + EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite + + CoordBBox bbox; + root.evalActiveBoundingBox(bbox); + EXPECT_EQ(bbox, CoordBBox()); // empty bbox + + root.getIndexRange(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(0))); // zero bbox + + // origin checks + + root.setOrigin(Coord(0, 0, 0)); + EXPECT_THROW(root.setOrigin(Coord(1, 2, 3)), ValueError); // non-zero origins not supported + + // key checks + + EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), -1); + + EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096)); + + EXPECT_FALSE(root.hasKey(Coord(0, 0, 0))); + } + + { // one active, non-background root node tile + RootNode root(1.0f); + root.addTile(Coord(1, 2, 3), 2.0f, true); + + // background checks + + EXPECT_EQ(root.background(), 1.0f); + EXPECT_EQ(root.numBackgroundTiles(), 0); + + // count checks + + EXPECT_FALSE(root.empty()); + EXPECT_TRUE(root.hasActiveTiles()); + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_EQ(root.leafCount(), 0); + EXPECT_EQ(root.nonLeafCount(), 1); + EXPECT_EQ(root.childCount(), 0); + EXPECT_EQ(root.tileCount(), 1); + EXPECT_EQ(root.activeTileCount(), 1); + EXPECT_EQ(root.inactiveTileCount(), 0); + + Index64 voxels = Index64(4096) * 4096 * 4096; + EXPECT_EQ(root.onVoxelCount(), voxels); + EXPECT_EQ(root.offVoxelCount(), 0); + EXPECT_EQ(root.onLeafVoxelCount(), 0); + EXPECT_EQ(root.offLeafVoxelCount(), 0); + EXPECT_EQ(root.onTileCount(), 1); + + // bounding box checks + + EXPECT_EQ(root.getMinIndex(), Coord(0)); + EXPECT_EQ(root.getMaxIndex(), Coord(4095)); + EXPECT_EQ(root.getWidth(), 4095); + EXPECT_EQ(root.getHeight(), 4095); + EXPECT_EQ(root.getDepth(), 4095); + EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite + + CoordBBox bbox; + root.evalActiveBoundingBox(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + root.getIndexRange(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + // key checks + + EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0); + + EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096)); + + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(1, 2, 3))); + + // erase background tiles + + root.eraseBackgroundTiles(); + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + + // clear root + + root.clear(); + EXPECT_EQ(root.getTableSize(), 0); + EXPECT_FALSE(root.hasKey(Coord(0, 0, 0))); + } + + { // one inactive, background root node tile + RootNode root(1.0f); + root.addTile(Coord(1, 2, 3), 1.0f, false); + + // background checks + + EXPECT_EQ(root.background(), 1.0f); + EXPECT_EQ(root.numBackgroundTiles(), 1); + + // count checks + + EXPECT_TRUE(root.empty()); // root is empty if it only has inactive background tiles + EXPECT_FALSE(root.hasActiveTiles()); + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_EQ(root.leafCount(), 0); + EXPECT_EQ(root.nonLeafCount(), 1); + EXPECT_EQ(root.childCount(), 0); + EXPECT_EQ(root.tileCount(), 1); + EXPECT_EQ(root.activeTileCount(), 0); + EXPECT_EQ(root.inactiveTileCount(), 1); + + EXPECT_EQ(root.onVoxelCount(), 0); + EXPECT_EQ(root.offVoxelCount(), 0); + EXPECT_EQ(root.onLeafVoxelCount(), 0); + EXPECT_EQ(root.offLeafVoxelCount(), 0); + EXPECT_EQ(root.onTileCount(), 0); + + // bounding box checks + + EXPECT_EQ(root.getMinIndex(), Coord(0)); + EXPECT_EQ(root.getMaxIndex(), Coord(4095)); + EXPECT_EQ(root.getWidth(), 4095); + EXPECT_EQ(root.getHeight(), 4095); + EXPECT_EQ(root.getDepth(), 4095); + EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite + + CoordBBox bbox; + root.evalActiveBoundingBox(bbox); + EXPECT_EQ(bbox, CoordBBox()); // empty bbox + + root.getIndexRange(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + // key checks + + EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0); + + EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096)); + + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(1, 2, 3))); + + // erase background tiles + + root.eraseBackgroundTiles(); + EXPECT_EQ(root.getTableSize(), 0); + EXPECT_FALSE(root.hasKey(Coord(0, 0, 0))); + } + + { // one active, background root node tile + RootNode root(1.0f); + root.addTile(Coord(1, 2, 3), 1.0f, true); + + // background checks + + EXPECT_EQ(root.background(), 1.0f); + EXPECT_EQ(root.numBackgroundTiles(), 0); + + // count checks + + EXPECT_FALSE(root.empty()); + EXPECT_TRUE(root.hasActiveTiles()); + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_EQ(root.leafCount(), 0); + EXPECT_EQ(root.nonLeafCount(), 1); + EXPECT_EQ(root.childCount(), 0); + EXPECT_EQ(root.tileCount(), 1); + EXPECT_EQ(root.activeTileCount(), 1); + EXPECT_EQ(root.inactiveTileCount(), 0); + + Index64 voxels = Index64(4096) * 4096 * 4096; + EXPECT_EQ(root.onVoxelCount(), voxels); + EXPECT_EQ(root.offVoxelCount(), 0); + EXPECT_EQ(root.onLeafVoxelCount(), 0); + EXPECT_EQ(root.offLeafVoxelCount(), 0); + EXPECT_EQ(root.onTileCount(), 1); + + // bounding box checks + + EXPECT_EQ(root.getMinIndex(), Coord(0)); + EXPECT_EQ(root.getMaxIndex(), Coord(4095)); + EXPECT_EQ(root.getWidth(), 4095); + EXPECT_EQ(root.getHeight(), 4095); + EXPECT_EQ(root.getDepth(), 4095); + EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite + + CoordBBox bbox; + root.evalActiveBoundingBox(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + root.getIndexRange(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + // key checks + + EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0); + + EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096)); + + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(1, 2, 3))); + } + + { // one internal node tile (which implicitly adds a root node child) + RootNode root(1.0f); + root.addTile(2, Coord(1, 2, 3), 2.0f, true); + + // count checks + + EXPECT_FALSE(root.empty()); + EXPECT_TRUE(root.hasActiveTiles()); // this method recurses down the tree + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_EQ(root.leafCount(), 0); + EXPECT_EQ(root.nonLeafCount(), 2); + EXPECT_EQ(root.childCount(), 1); + EXPECT_EQ(root.tileCount(), 0); + EXPECT_EQ(root.activeTileCount(), 0); + EXPECT_EQ(root.inactiveTileCount(), 0); + + Index64 totalVoxels = Index64(4096) * 4096 * 4096; + Index64 onVoxels = Index64(128) * 128 * 128; + EXPECT_EQ(root.onVoxelCount(), onVoxels); + EXPECT_EQ(root.offVoxelCount(), totalVoxels - onVoxels); + EXPECT_EQ(root.onLeafVoxelCount(), 0); + EXPECT_EQ(root.offLeafVoxelCount(), 0); + EXPECT_EQ(root.onTileCount(), 1); + + // bounding box checks + + EXPECT_EQ(root.getMinIndex(), Coord(0)); + EXPECT_EQ(root.getMaxIndex(), Coord(4095)); + EXPECT_EQ(root.getWidth(), 4095); + EXPECT_EQ(root.getHeight(), 4095); + EXPECT_EQ(root.getDepth(), 4095); + EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite + + CoordBBox bbox; + root.evalActiveBoundingBox(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(127))); + + root.getIndexRange(bbox); + EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095))); + + // key checks + + EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 1); // InternalNode 1 + + EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0)); + EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096)); + + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(1, 2, 3))); + } +} + +TEST_F(TestRoot, testDelete) +{ + using RootNode = FloatTree::RootNodeType; + + RootNode root(1.0f); + + root.addTile(Coord(1, 2, 3), 2.0f, true); + root.addTile(Coord(4096, 2, 3), 3.0f, true); + + auto* child = new RootNode::ChildNodeType(Coord(0, 0, 4096), 5.0f, true); + EXPECT_TRUE(root.addChild(child)); // always returns true + + EXPECT_EQ(root.getTableSize(), 3); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_TRUE(root.hasKey(Coord(4096, 0, 0))); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096))); + EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0))); + + EXPECT_FALSE(root.deleteChildOrTile(Coord(4096, 4096, 0))); + + EXPECT_EQ(root.getTableSize(), 3); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_TRUE(root.hasKey(Coord(4096, 0, 0))); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096))); + EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0))); + + EXPECT_TRUE(root.deleteChildOrTile(Coord(4096, 5, 6))); + + EXPECT_EQ(root.getTableSize(), 2); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0))); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096))); + EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0))); + + EXPECT_TRUE(root.deleteChildOrTile(Coord(1, 5, 4097))); + + EXPECT_EQ(root.getTableSize(), 1); + EXPECT_TRUE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(0, 0, 4096))); + EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0))); + + EXPECT_TRUE(root.deleteChildOrTile(Coord(1, 5, 7))); + + EXPECT_EQ(root.getTableSize(), 0); + EXPECT_FALSE(root.hasKey(Coord(0, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0))); + EXPECT_FALSE(root.hasKey(Coord(0, 0, 4096))); + EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0))); +} From 02abba79631a29d970d771a070a30c6d37350656 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 9 Oct 2024 15:37:15 -0700 Subject: [PATCH 33/98] Add changes file Signed-off-by: Dan Bailey --- pendingchanges/root_node.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 pendingchanges/root_node.txt diff --git a/pendingchanges/root_node.txt b/pendingchanges/root_node.txt new file mode 100644 index 0000000000..21fd020bda --- /dev/null +++ b/pendingchanges/root_node.txt @@ -0,0 +1,9 @@ +API Changes: + - RootNode::tileCount(), RootNode::activeTileCount() and RootNode::inactiveTileCount() are now public. + - RootNode::hasKey() and RootNode::coordToKey() are now public. + +Improvements: + - Add RootNode::deleteChildOrTile() to delete a child or tile of the root node. + +Bug Fixes: + - Fix a bug in RootNode::setOrigin() where the origin was updated before the error was thrown potentially leaving the root in an invalid state. \ No newline at end of file From 682aaf1b93a11fc8cbb43d913dc695b914027302 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Sat, 26 Oct 2024 16:57:14 -0700 Subject: [PATCH 34/98] Address feedback Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 40 ++++++++++++++-------------- pendingchanges/root_node_emplace.txt | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 31e2053750..78130e9700 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -1791,7 +1791,7 @@ inline void RootNode::setActiveState(const Coord& xyz, bool on) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (on) { @@ -1815,7 +1815,7 @@ inline void RootNode::setActiveStateAndCache(const Coord& xyz, bool on, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (on) { @@ -1842,7 +1842,7 @@ inline void RootNode::setValueOff(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (!math::isExactlyEqual(mBackground, value)) { @@ -1864,7 +1864,7 @@ inline void RootNode::setValueOffAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (!math::isExactlyEqual(mBackground, value)) { @@ -1889,7 +1889,7 @@ inline void RootNode::setValueOn(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -1909,7 +1909,7 @@ inline void RootNode::setValueAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -1932,7 +1932,7 @@ inline void RootNode::setValueOnly(const Coord& xyz, const ValueType& value) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -1952,7 +1952,7 @@ inline void RootNode::setValueOnlyAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -1976,7 +1976,7 @@ inline void RootNode::modifyValue(const Coord& xyz, const ModifyOp& op) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -2009,7 +2009,7 @@ inline void RootNode::modifyValueAndCache(const Coord& xyz, const ModifyOp& op, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -2046,7 +2046,7 @@ inline void RootNode::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -2075,7 +2075,7 @@ RootNode::modifyValueAndActiveStateAndCache( const Coord& xyz, const ModifyOp& op, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground); @@ -2588,7 +2588,7 @@ RootNode::addLeaf(LeafNodeType* leaf) if (leaf == nullptr) return; ChildT* child = nullptr; const Coord& xyz = leaf->origin(); - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (ChildT::LEVEL>0) { @@ -2624,7 +2624,7 @@ RootNode::addLeafAndCache(LeafNodeType* leaf, AccessorT& acc) if (leaf == nullptr) return; ChildT* child = nullptr; const Coord& xyz = leaf->origin(); - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { if (ChildT::LEVEL>0) { @@ -2658,7 +2658,7 @@ RootNode::addChild(ChildT* child) { if (!child) return false; const Coord& xyz = child->origin(); - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background mTable.emplace(key, *child); @@ -2684,7 +2684,7 @@ template inline void RootNode::addTile(const Coord& xyz, const ValueType& value, bool state) { - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background mTable.emplace(key, Tile(value, state)); @@ -2699,7 +2699,7 @@ RootNode::addTile(Index level, const Coord& xyz, const ValueType& value, bool state) { if (LEVEL >= level) { - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background if (LEVEL > level) { @@ -2735,7 +2735,7 @@ RootNode::addTileAndCache(Index level, const Coord& xyz, const ValueType bool state, AccessorT& acc) { if (LEVEL >= level) { - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) {//background if (LEVEL > level) { @@ -2776,7 +2776,7 @@ inline typename ChildT::LeafNodeType* RootNode::touchLeaf(const Coord& xyz) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground, false); @@ -2797,7 +2797,7 @@ inline typename ChildT::LeafNodeType* RootNode::touchLeafAndCache(const Coord& xyz, AccessorT& acc) { ChildT* child = nullptr; - Coord key = this->coordToKey(xyz); + const Coord key = this->coordToKey(xyz); MapIter iter = this->findKey(key); if (iter == mTable.end()) { child = new ChildT(xyz, mBackground, false); diff --git a/pendingchanges/root_node_emplace.txt b/pendingchanges/root_node_emplace.txt index ebe67c570d..5c1d0d739c 100644 --- a/pendingchanges/root_node_emplace.txt +++ b/pendingchanges/root_node_emplace.txt @@ -1,2 +1,2 @@ Improvements: - - Small optimizations to RootNode to eliminate redundant key conversion and to create map values in-place. \ No newline at end of file + - RootNode code cleanup to eliminate redundant key conversion and to create map values in-place. \ No newline at end of file From 18d4cc3c2ce5dbe273937f700e062051adac56ae Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Sat, 26 Oct 2024 17:14:33 -0700 Subject: [PATCH 35/98] Address feedback Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 45 +++++++++++------------- openvdb/openvdb/tree/LeafNode.h | 4 +-- openvdb/openvdb/tree/RootNode.h | 8 ++--- openvdb/openvdb/unittest/TestRootNode.cc | 8 ++--- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 4c1149a862..832e3bff36 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -472,66 +472,66 @@ class InternalNode // Enabling OpenVDB asserts will catch where assumptions are incorrectly invalidated. /// @brief Return the tile value at offset. - /// @note Use getValue() for a safer alternative. + /// @note Use getValue(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. const ValueType& getValueUnsafe(Index offset) const; /// @brief Return the tile value and active state at offset. - /// @note Use getValue() for a safer alternative. + /// @note Use probeValue(const Coord&, ValueType&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. bool getValueUnsafe(Index offset, ValueType& value) const; /// @brief Return the child node at offset. - /// @note Use probeChild() for a safer alternative. + /// @note Use probeChild(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. ChildNodeType* getChildUnsafe(Index offset); /// @brief Return the child node at offset. - /// @note Use probeConstChild() for a safer alternative. + /// @note Use probeConstChild(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. const ChildNodeType* getConstChildUnsafe(Index offset) const; /// @brief Return the child node at offset. - /// @note Use probeChild() for a safer alternative. + /// @note Use probeChild(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. const ChildNodeType* getChildUnsafe(Index offset) const; /// @brief Set the tile active state at offset but don't change its value. - /// @note Use setActiveState() for a safer alternative. + /// @note Use setActiveState(const Coord&, bool) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setActiveStateUnsafe(Index offset, bool on); /// @brief Set the tile value at offset but don't change its value. - /// @note Use setValueOnly() for a safer alternative. + /// @note Use setValueOnly(const Coord&, const ValueType&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setValueOnlyUnsafe(Index offset, const ValueType& value); /// @brief Mark the tile active at offset but don't change its value. - /// @note Use setValueOn() for a safer alternative. + /// @note Use setValueOn(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setValueOnUnsafe(Index offset); /// @brief Set the tile value at offset and mark the voxel as active. - /// @note Use setValueOn() for a safer alternative. + /// @note Use setValueOn(const Coord&, const ValueType&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setValueOnUnsafe(Index offset, const ValueType& value); /// @brief Mark the tile inactive at offset but don't change its value. - /// @note Use setValueOff() for a safer alternative. + /// @note Use setValueOff(const Coord&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setValueOffUnsafe(Index offset); /// @brief Set the tile value at offset and mark the voxel as inactive. - /// @note Use setValueOff() for a safer alternative. + /// @note Use setValueOff(const Coord&, const ValueType&) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setValueOffUnsafe(Index offset, const ValueType& value); /// @brief Replace a tile at offset with the given child node. - /// @note Use addChild() for a safer alternative. + /// @note Use addChild(ChildNodeType*) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void setChildUnsafe(Index offset, ChildNodeType* child); /// @brief Replace a child node at offset with the given child node. - /// @note Use addChild() for a safer alternative. + /// @note Use addChild(ChildNodeType*) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void resetChildUnsafe(Index offset, ChildNodeType* child); /// @brief Replace a child node at offset with the given value and active state. - /// @note Use addChild() for a safer alternative. + /// @note Use addChild(ChildNodeType*) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. ChildNodeType* stealChildUnsafe(Index offset, const ValueType& value, bool active); /// @brief Delete a child node at offset and replace with the given value and active state. - /// @note Use addTile() for a safer alternative. + /// @note Use addTile(Index, const ValueType&, bool) for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. void deleteChildUnsafe(Index offset, const ValueType& value, bool active); @@ -1627,8 +1627,8 @@ inline bool InternalNode::isValueOn(const Coord& xyz) const { const Index n = this->coordToOffset(xyz); - if (this->isChildMaskOff(n)) return this->isValueMaskOn(n); - return mNodes[n].getChild()->isValueOn(xyz); + return this->isChildMaskOff(n) ? this->isValueMaskOn(n) + : mNodes[n].getChild()->isValueOn(xyz); } template @@ -1636,8 +1636,8 @@ inline bool InternalNode::isValueOff(const Coord& xyz) const { const Index n = this->coordToOffset(xyz); - if (this->isChildMaskOff(n)) return this->isValueMaskOn(n); - return mNodes[n].getChild()->isValueOff(xyz); + return this->isChildMaskOff(n) ? this->isValueMaskOn(n) + : mNodes[n].getChild()->isValueOff(xyz); } template @@ -2501,12 +2501,7 @@ inline void InternalNode::deleteChildUnsafe(Index n, const ValueType& value, bool active) { // replace child with tile (and delete child) - OPENVDB_ASSERT(n < NUM_VALUES); - OPENVDB_ASSERT(mChildMask.isOn(n)); - delete mNodes[n].getChild(); - mChildMask.setOff(n); - mValueMask.set(n, active); - mNodes[n].setValue(value); + delete this->stealChildUnsafe(n, value, active); } diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 27dab9d33d..7ebde8acd6 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -473,11 +473,11 @@ class LeafNode void setValuesOff() { mValueMask.setOff(); } /// Return @c true if the voxel at the given coordinates is active. - bool isValueOn(const Coord& xyz) const {return this->isValueOn(LeafNode::coordToOffset(xyz));} + bool isValueOn(const Coord& xyz) const { return this->isValueOn(LeafNode::coordToOffset(xyz)); } /// Return @c true if the voxel at the given offset is active. bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } /// Return @c true if the voxel at the given coordinates is inactive. - bool isValueOff(const Coord& xyz) const {return this->isValueOff(LeafNode::coordToOffset(xyz));} + bool isValueOff(const Coord& xyz) const { OPENVDB_ASSERT(offset < SIZE); return this->isValueOff(LeafNode::coordToOffset(xyz)); } /// Return @c true if the voxel at the given offset is inactive. bool isValueOff(Index offset) const { return mValueMask.isOff(offset); } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 9c9fff1b17..d9bb2de2e3 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -766,11 +766,11 @@ class RootNode /// @brief Return the tile value at the given coordinate. /// @note Use cbeginValueAll() for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. - const ValueType& getValueUnsafe(const Coord& xyz) const; + const ValueType& getTileValueUnsafe(const Coord& xyz) const; /// @brief Return the tile value and active state at the given coordinate. /// @note Use cbeginValueAll() for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. - bool getValueUnsafe(const Coord& xyz, ValueType& value) const; + bool getTileValueUnsafe(const Coord& xyz, ValueType& value) const; /// @brief Return the child node at the given coordinate. /// @note Use beginChildAll() for a safer alternative. /// @warning This method should only be used by experts seeking low-level optimizations. @@ -2919,7 +2919,7 @@ RootNode::probeConstNodeAndCache(const Coord& xyz, AccessorT& acc) const template inline const typename ChildT::ValueType& -RootNode::getValueUnsafe(const Coord& xyz) const +RootNode::getTileValueUnsafe(const Coord& xyz) const { MapCIter iter = this->findCoord(xyz); OPENVDB_ASSERT(iter != mTable.end()); @@ -2930,7 +2930,7 @@ RootNode::getValueUnsafe(const Coord& xyz) const template inline bool -RootNode::getValueUnsafe(const Coord& xyz, ValueType& value) const +RootNode::getTileValueUnsafe(const Coord& xyz, ValueType& value) const { MapCIter iter = this->findCoord(xyz); OPENVDB_ASSERT(iter != mTable.end()); diff --git a/openvdb/openvdb/unittest/TestRootNode.cc b/openvdb/openvdb/unittest/TestRootNode.cc index 8b361009b1..e100ec9b75 100644 --- a/openvdb/openvdb/unittest/TestRootNode.cc +++ b/openvdb/openvdb/unittest/TestRootNode.cc @@ -124,12 +124,12 @@ TEST_F(TestRoot, testUnsafe) EXPECT_TRUE(root.addChild(child)); // always returns true { // get value - EXPECT_EQ(root.getValueUnsafe(Coord(1, 2, 3)), 2.0f); - EXPECT_EQ(root.getValueUnsafe(Coord(4096, 2, 3)), 3.0f); + EXPECT_EQ(root.getTileValueUnsafe(Coord(1, 2, 3)), 2.0f); + EXPECT_EQ(root.getTileValueUnsafe(Coord(4096, 2, 3)), 3.0f); float value = -1.0f; - EXPECT_TRUE(root.getValueUnsafe(Coord(1, 2, 3), value)); + EXPECT_TRUE(root.getTileValueUnsafe(Coord(1, 2, 3), value)); EXPECT_EQ(value, 2.0f); value = -1.0f; - EXPECT_FALSE(root.getValueUnsafe(Coord(4096, 2, 3), value)); + EXPECT_FALSE(root.getTileValueUnsafe(Coord(4096, 2, 3), value)); EXPECT_EQ(value, 3.0f); value = -1.0f; } From 485ff9884ffc1eb83aa87e05314cf2e6a1c16dd9 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Sat, 26 Oct 2024 17:33:14 -0700 Subject: [PATCH 36/98] Address feedback Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 76 +++++--------------- openvdb/openvdb/tree/RootNode.h | 22 +----- openvdb/openvdb/unittest/TestInternalNode.cc | 48 +++++-------- 3 files changed, 38 insertions(+), 108 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 356a3a9e8d..4cbafff1d0 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -620,7 +620,7 @@ class InternalNode /// If no such node exists, return nullptr. template NodeType* probeNode(const Coord& xyz); template const NodeType* probeConstNode(const Coord& xyz) const; - template const NodeType* probeNode(const Coord& xyz) const; + template const NodeType* probeNode(const Coord& xyz) const { return this->probeConstNode(xyz); } //@} //@{ @@ -628,7 +628,7 @@ class InternalNode /// If no such node exists, return nullptr. ChildNodeType* probeChild(const Coord& xyz); const ChildNodeType* probeConstChild(const Coord& xyz) const; - const ChildNodeType* probeChild(const Coord& xyz) const; + const ChildNodeType* probeChild(const Coord& xyz) const { return this->probeConstChild(xyz); } //@} //@{ @@ -636,25 +636,27 @@ class InternalNode /// If no such node exists, return nullptr. ChildNodeType* probeChild(const Coord& xyz, ValueType& value, bool& active); const ChildNodeType* probeConstChild(const Coord& xyz, ValueType& value, bool& active) const; - const ChildNodeType* probeChild(const Coord& xyz, ValueType& value, bool& active) const; + const ChildNodeType* probeChild(const Coord& xyz, ValueType& value, bool& active) const { return this->probeConstChild(xyz, value, active); } //@} //@{ /// @brief Return a pointer to the child node for a specific offset. /// If no such node exists, return nullptr. + /// @warning This method should only be used by experts seeking low-level optimizations. /// @note Out-of-bounds memory access attempts will wrap around using modulo indexing. - ChildNodeType* probeChild(Index offset); - const ChildNodeType* probeConstChild(Index offset) const; - const ChildNodeType* probeChild(Index offset) const; + ChildNodeType* probeChildUnsafe(Index offset); + const ChildNodeType* probeConstChildUnsafe(Index offset) const; + const ChildNodeType* probeChildUnsafe(Index offset) const { return this->probeConstChildUnsafe(offset); } //@} //@{ /// @brief Return a pointer to the child node for a specific offset. /// If no such node exists, return nullptr. + /// @warning This method should only be used by experts seeking low-level optimizations. /// @note Out-of-bounds memory access attempts will wrap around using modulo indexing. - ChildNodeType* probeChild(Index offset, ValueType& value, bool& active); - const ChildNodeType* probeConstChild(Index offset, ValueType& value, bool& active) const; - const ChildNodeType* probeChild(Index offset, ValueType& value, bool& active) const; + ChildNodeType* probeChildUnsafe(Index offset, ValueType& value, bool& active); + const ChildNodeType* probeConstChildUnsafe(Index offset, ValueType& value, bool& active) const; + const ChildNodeType* probeChildUnsafe(Index offset, ValueType& value, bool& active) const { return this->probeConstChildUnsafe(offset, value, active); } //@} //@{ @@ -1261,15 +1263,6 @@ InternalNode::probeConstNode(const Coord& xyz) const } -template -template -inline const NodeT* -InternalNode::probeNode(const Coord& xyz) const -{ - return this->probeConstNode(xyz); -} - - template template inline const NodeT* @@ -1297,7 +1290,7 @@ inline ChildT* InternalNode::probeChild(const Coord& xyz) { const Index n = this->coordToOffset(xyz); - return this->probeChild(n); + return this->probeChildUnsafe(n); } template @@ -1305,14 +1298,7 @@ inline const ChildT* InternalNode::probeConstChild(const Coord& xyz) const { const Index n = this->coordToOffset(xyz); - return this->probeConstChild(n); -} - -template -inline const ChildT* -InternalNode::probeChild(const Coord& xyz) const -{ - return this->probeConstChild(xyz); + return this->probeConstChildUnsafe(n); } template @@ -1320,7 +1306,7 @@ inline ChildT* InternalNode::probeChild(const Coord& xyz, ValueType& value, bool& active) { const Index n = this->coordToOffset(xyz); - return this->probeChild(n, value, active); + return this->probeChildUnsafe(n, value, active); } template @@ -1328,49 +1314,32 @@ inline const ChildT* InternalNode::probeConstChild(const Coord& xyz, ValueType& value, bool& active) const { const Index n = this->coordToOffset(xyz); - return this->probeConstChild(n, value, active); -} - -template -inline const ChildT* -InternalNode::probeChild(const Coord& xyz, ValueType& value, bool& active) const -{ - return this->probeConstChild(xyz, value, active); + return this->probeConstChildUnsafe(n, value, active); } template inline ChildT* -InternalNode::probeChild(Index offset) +InternalNode::probeChildUnsafe(Index offset) { OPENVDB_ASSERT(offset < NUM_VALUES); - offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); return nullptr; } template inline const ChildT* -InternalNode::probeConstChild(Index offset) const +InternalNode::probeConstChildUnsafe(Index offset) const { OPENVDB_ASSERT(offset < NUM_VALUES); - offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); return nullptr; } -template -inline const ChildT* -InternalNode::probeChild(Index offset) const -{ - return this->probeConstChild(offset); -} - template inline ChildT* -InternalNode::probeChild(Index offset, ValueType& value, bool& active) +InternalNode::probeChildUnsafe(Index offset, ValueType& value, bool& active) { OPENVDB_ASSERT(offset < NUM_VALUES); - offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); value = mNodes[offset].getValue(); active = mValueMask.isOn(offset); @@ -1379,22 +1348,15 @@ InternalNode::probeChild(Index offset, ValueType& value, bool& template inline const ChildT* -InternalNode::probeConstChild(Index offset, ValueType& value, bool& active) const +InternalNode::probeConstChildUnsafe(Index offset, ValueType& value, bool& active) const { OPENVDB_ASSERT(offset < NUM_VALUES); - offset &= (NUM_VALUES - 1); // prevent use of an out-of-bounds index if (mChildMask.isOn(offset)) return mNodes[offset].getChild(); value = mNodes[offset].getValue(); active = mValueMask.isOn(offset); return nullptr; } -template -inline const ChildT* -InternalNode::probeChild(Index offset, ValueType& value, bool& active) const -{ - return this->probeConstChild(offset, value, active); -} //////////////////////////////////////// diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 7376f80eb9..63231a777b 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -735,7 +735,7 @@ class RootNode /// return @c nullptr. bool probe(const Coord& xyz, ChildNodeType*& child, ValueType& value, bool& active); bool probeConst(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const; - bool probe(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const; + bool probe(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const { return this->probeConst(xyz, child, value, active); } //} //@{ @@ -752,7 +752,7 @@ class RootNode /// If no such node exists, return @c nullptr. ChildNodeType* probeChild(const Coord& xyz); const ChildNodeType* probeConstChild(const Coord& xyz) const; - const ChildNodeType* probeChild(const Coord& xyz) const; + const ChildNodeType* probeChild(const Coord& xyz) const { return this->probeConstChild(xyz); } //@} //@{ @@ -760,7 +760,7 @@ class RootNode /// If no such node exists, return @c nullptr. LeafNodeType* probeLeaf(const Coord& xyz); const LeafNodeType* probeConstLeaf(const Coord& xyz) const; - const LeafNodeType* probeLeaf(const Coord& xyz) const; + const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); } //@} //@{ @@ -2872,14 +2872,6 @@ RootNode::probeConst(const Coord& xyz, const ChildNodeType*& child, Valu } -template -inline bool -RootNode::probe(const Coord& xyz, const ChildNodeType*& child, ValueType& value, bool& active) const -{ - return this->probeConst(xyz, child, value, active); -} - - template inline ChildT* RootNode::probeChild(const Coord& xyz) @@ -2888,14 +2880,6 @@ RootNode::probeChild(const Coord& xyz) } -template -inline const ChildT* -RootNode::probeChild(const Coord& xyz) const -{ - return this->template probeConstNode(xyz); -} - - template inline const ChildT* RootNode::probeConstChild(const Coord& xyz) const diff --git a/openvdb/openvdb/unittest/TestInternalNode.cc b/openvdb/openvdb/unittest/TestInternalNode.cc index 2a8c5728ed..a9396cbeb0 100644 --- a/openvdb/openvdb/unittest/TestInternalNode.cc +++ b/openvdb/openvdb/unittest/TestInternalNode.cc @@ -151,7 +151,7 @@ TEST_F(TestInternalNode, testProbe) EXPECT_FALSE(bool(node6)); } - { // probeChild, probeConstChild - coord access + { // probeChild, probeConstChild auto* node1 = internalNode.probeChild(Coord(0, 256, 4096)); EXPECT_TRUE(bool(node1)); auto* node2 = internalNode.probeChild(Coord(0, 128, 4096)); @@ -167,32 +167,26 @@ TEST_F(TestInternalNode, testProbe) EXPECT_FALSE(bool(node6)); } - { // probeChild, probeConstChild - index access - auto* node1 = internalNode.probeChild(64); + { // probeChildUnsafe, probeConstChildUnsafe + auto* node1 = internalNode.probeChildUnsafe(64); EXPECT_TRUE(bool(node1)); - auto* node2 = internalNode.probeChild(33); + auto* node2 = internalNode.probeChildUnsafe(33); EXPECT_FALSE(bool(node2)); const InternalNode& constInternalNode = internalNode; - auto* node3 = constInternalNode.probeChild(64); + auto* node3 = constInternalNode.probeChildUnsafe(64); EXPECT_TRUE(bool(node3)); - auto* node4 = constInternalNode.probeChild(33); + auto* node4 = constInternalNode.probeChildUnsafe(33); EXPECT_FALSE(bool(node4)); - auto* node5 = internalNode.probeConstChild(64); + auto* node5 = internalNode.probeConstChildUnsafe(64); EXPECT_TRUE(bool(node5)); - auto* node6 = internalNode.probeConstChild(33); + auto* node6 = internalNode.probeConstChildUnsafe(33); EXPECT_FALSE(bool(node6)); - - // wrap-around modulo indexing - auto* node7 = internalNode.probeConstChild(64 + 32*32*32); - EXPECT_TRUE(bool(node7)); - auto* node8 = internalNode.probeConstChild(33 + 32*32*32); - EXPECT_FALSE(bool(node8)); } float value = -1.0f; bool active = false; - { // probeChild, probeConstChild - coord access with value and active status + { // probeChild, probeConstChild with value and active status auto* node1 = internalNode.probeChild(Coord(0, 256, 4096), value, active); EXPECT_TRUE(bool(node1)); EXPECT_EQ(value, -1.0f); @@ -220,41 +214,31 @@ TEST_F(TestInternalNode, testProbe) EXPECT_TRUE(active); active = false; } - { // probeChild, probeConstChild - index access with value and active status - auto* node1 = internalNode.probeChild(64, value, active); + { // probeChildUnsafe, probeConstChildUnsafe with value and active status + auto* node1 = internalNode.probeChildUnsafe(64, value, active); EXPECT_TRUE(bool(node1)); EXPECT_EQ(value, -1.0f); EXPECT_FALSE(active); - auto* node2 = internalNode.probeChild(33, value, active); + auto* node2 = internalNode.probeChildUnsafe(33, value, active); EXPECT_FALSE(bool(node2)); EXPECT_EQ(value, 4.0f); value = -1.0f; EXPECT_TRUE(active); active = false; const InternalNode& constInternalNode = internalNode; - auto* node3 = constInternalNode.probeChild(64, value, active); + auto* node3 = constInternalNode.probeChildUnsafe(64, value, active); EXPECT_TRUE(bool(node3)); EXPECT_EQ(value, -1.0f); EXPECT_FALSE(active); - auto* node4 = constInternalNode.probeChild(33, value, active); + auto* node4 = constInternalNode.probeChildUnsafe(33, value, active); EXPECT_FALSE(bool(node4)); EXPECT_EQ(value, 4.0f); value = -1.0f; EXPECT_TRUE(active); active = false; - auto* node5 = internalNode.probeConstChild(64, value, active); + auto* node5 = internalNode.probeConstChildUnsafe(64, value, active); EXPECT_TRUE(bool(node5)); EXPECT_EQ(value, -1.0f); EXPECT_FALSE(active); - auto* node6 = internalNode.probeConstChild(33, value, active); + auto* node6 = internalNode.probeConstChildUnsafe(33, value, active); EXPECT_FALSE(bool(node6)); EXPECT_EQ(value, 4.0f); value = -1.0f; EXPECT_TRUE(active); active = false; - - // wrap-around modulo indexing - auto* node7 = internalNode.probeConstChild(64 + 32*32*32, value, active); - EXPECT_TRUE(bool(node7)); - EXPECT_EQ(value, -1.0f); - EXPECT_FALSE(active); - auto* node8 = internalNode.probeConstChild(33 + 32*32*32, value, active); - EXPECT_FALSE(bool(node8)); - EXPECT_EQ(value, 4.0f); value = -1.0f; - EXPECT_TRUE(active); active = false; } } From 0c8caf63e103817a4dce2ca847b06480fadfd448 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Sat, 26 Oct 2024 17:35:47 -0700 Subject: [PATCH 37/98] Fix some asserts Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/InternalNode.h | 4 ++-- openvdb/openvdb/tree/LeafNode.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 832e3bff36..fd5468c160 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -331,11 +331,11 @@ class InternalNode /// Return @c true if the voxel at the given coordinates is active. bool isValueOn(const Coord& xyz) const; /// Return @c true if the voxel at the given offset is active. - bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } + bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < NUM_VALUES); return mValueMask.isOn(offset); } /// Return @c true if the voxel at the given coordinates is inactive. bool isValueOff(const Coord& xyz) const; /// Return @c true if the voxel at the given offset is inactive. - bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOff(offset); } + bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < NUM_VALUES); return mValueMask.isOff(offset); } /// Return @c true if this node or any of its child nodes have any active tiles. bool hasActiveTiles() const; diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 7ebde8acd6..62dd53f486 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -477,9 +477,9 @@ class LeafNode /// Return @c true if the voxel at the given offset is active. bool isValueOn(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOn(offset); } /// Return @c true if the voxel at the given coordinates is inactive. - bool isValueOff(const Coord& xyz) const { OPENVDB_ASSERT(offset < SIZE); return this->isValueOff(LeafNode::coordToOffset(xyz)); } + bool isValueOff(const Coord& xyz) const { return this->isValueOff(LeafNode::coordToOffset(xyz)); } /// Return @c true if the voxel at the given offset is inactive. - bool isValueOff(Index offset) const { return mValueMask.isOff(offset); } + bool isValueOff(Index offset) const { OPENVDB_ASSERT(offset < SIZE); return mValueMask.isOff(offset); } /// Return @c false since leaf nodes never contain tiles. static bool hasActiveTiles() { return false; } From d855b3f12d9610175d71db906808d035d18c5675 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Mon, 28 Oct 2024 21:54:00 -0700 Subject: [PATCH 38/98] Eliminate Python version check now that the minimum version is Python3 and other clean up Signed-off-by: Dan Bailey --- CMakeLists.txt | 61 ++++++----------------------------------- cmake/FindOpenVDB.cmake | 2 -- 2 files changed, 8 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3cb513d11..37ca1722c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -453,62 +453,17 @@ endif() # Locate Python and nanobind if necessary if(OPENVDB_BUILD_PYTHON_MODULE OR (OPENVDB_BUILD_NANOVDB AND NANOVDB_BUILD_PYTHON_MODULE)) - # Small function which mimics basic output (bar components) of - # FindPackageHandleStandardArgs. This is required as we want to ensure - # the minimum python version is MINIMUM_PYTHON_VERSION - however this cannot - # be provided to find_package(Python) with differing major versions. e.g. - # calls to find_package(Python 2.7) fails if python3 is found on the system. - function(OPENVDB_CHECK_PYTHON_VERSION) - set(PY_TARGET ${ARGV0}) - set(PY_TARGET_VERSION ${ARGV1}) - set(PY_TARGET_INCLUDES ${ARGV2}) - set(MIN_VERSION ${ARGV3}) - set(FUTURE_MIN_VERSION ${ARGV4}) - - if(NOT TARGET ${PY_TARGET}) - message(FATAL_ERROR "Could NOT find ${PY_TARGET} (Required is at least version " - "\"${MIN_VERSION}\")" - ) - endif() - - if(PY_TARGET_VERSION AND MIN_VERSION) - if(PY_TARGET_VERSION VERSION_LESS MIN_VERSION) - message(FATAL_ERROR "Could NOT find ${PY_TARGET}: Found unsuitable version " - "\"${PY_TARGET_VERSION}\" but required is at least \"${MIN_VERSION}\" (found ${PY_TARGET_INCLUDES})" - ) - endif() - endif() - message(STATUS "Found ${PY_TARGET}: ${PY_TARGET_INCLUDES}) (found suitable " - "version \"${PY_TARGET_VERSION}\", minimum required is \"${MIN_VERSION}\")" - ) - - if(OPENVDB_FUTURE_DEPRECATION AND PY_TARGET_VERSION AND FUTURE_MIN_VERSION) - if(PY_TARGET_VERSION VERSION_LESS FUTURE_MIN_VERSION) - message(DEPRECATION "Support for ${PY_TARGET} versions < ${FUTURE_MIN_VERSION} " - "is deprecated and will be removed.") - endif() - endif() - endfunction() - - # Configure Python and Numpy. - # To ensure consistent versions between components Interpreter, Compiler, - # Development and NumPy, specify all components at the same time when using - # FindPython. - - # @note explicitly only search for Development.Module from 3.18 as searching - # Development.Embed can cause issues on linux systems where it doesn't exist - set(OPENVDB_PYTHON_REQUIRED_COMPONENTS Development Interpreter) - - # Make sure find_package(Python) is only ever invoked once with all required components - find_package(Python 3.8 REQUIRED COMPONENTS ${OPENVDB_PYTHON_REQUIRED_COMPONENTS}) + # Call find_package(Python ...) + find_package(Python 3.8 REQUIRED COMPONENTS Development Interpreter) find_package(nanobind REQUIRED) - openvdb_check_python_version(Python::Module - "${Python_VERSION}" - "${Python_INCLUDE_DIRS}" - "${MINIMUM_PYTHON_VERSION}" - "${FUTURE_MINIMUM_PYTHON_VERSION}") + 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) get_filename_component(Python_PACKAGES_DIR ${Python_SITELIB} NAME) diff --git a/cmake/FindOpenVDB.cmake b/cmake/FindOpenVDB.cmake index e35b5f5a0d..30e8e352f0 100644 --- a/cmake/FindOpenVDB.cmake +++ b/cmake/FindOpenVDB.cmake @@ -334,10 +334,8 @@ set(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(OPENVDB_PYTHON_PATH_SUFFIXES lib64/python - lib64/python2.7 lib64/python3 lib/python - lib/python2.7 lib/python3 ) From 59f86855ff6c151e1aef3bce027470f7424202ee Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 29 Oct 2024 00:12:37 -0700 Subject: [PATCH 39/98] Use sudo to make install nanobind Signed-off-by: Dan Bailey --- ci/install_nanobind.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/install_nanobind.sh b/ci/install_nanobind.sh index 8103a4fabe..50b6766b81 100755 --- a/ci/install_nanobind.sh +++ b/ci/install_nanobind.sh @@ -25,4 +25,4 @@ cmake \ .. make -j8 -make install +sudo make install From 4296ab35088580e7af8c48ebcc06a0a7792cf2dc Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 29 Oct 2024 00:13:03 -0700 Subject: [PATCH 40/98] Where Python_SITELIB is not defined, fall back to "site-packages" Signed-off-by: Dan Bailey --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 37ca1722c7..257cce8c4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -466,7 +466,11 @@ if(OPENVDB_BUILD_PYTHON_MODULE OR (OPENVDB_BUILD_NANOVDB AND NANOVDB_BUILD_PYTHO endif() if(NOT DEFINED VDB_PYTHON_INSTALL_DIRECTORY) - get_filename_component(Python_PACKAGES_DIR ${Python_SITELIB} NAME) + 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." From 8c57afe1d51041559e58f09d44408e39ab835461 Mon Sep 17 00:00:00 2001 From: apradhana Date: Tue, 22 Oct 2024 12:58:58 -0700 Subject: [PATCH 41/98] Add meeting notes October 8th and 22nd, 2024. Signed-off-by: apradhana --- tsc/meetings/2024-09-24.md | 2 +- tsc/meetings/2024-10-08.md | 82 ++++++++++++++++++++ tsc/meetings/2024-10-22.md | 151 +++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 tsc/meetings/2024-10-08.md create mode 100644 tsc/meetings/2024-10-22.md diff --git a/tsc/meetings/2024-09-24.md b/tsc/meetings/2024-09-24.md index bbb86694a3..02a4e06d4b 100644 --- a/tsc/meetings/2024-09-24.md +++ b/tsc/meetings/2024-09-24.md @@ -1,4 +1,4 @@ -Minutes from OpenVDB TSC meeting, March 12th, 2024 +Minutes from OpenVDB TSC meeting, September 9th, 2024 Attendees: *Ken* M., *Jeff* L., *Andre* P, *Dan* B., *Greg* H. diff --git a/tsc/meetings/2024-10-08.md b/tsc/meetings/2024-10-08.md new file mode 100644 index 0000000000..19a2582a38 --- /dev/null +++ b/tsc/meetings/2024-10-08.md @@ -0,0 +1,82 @@ +Minutes from OpenVDB TSC meeting, Octtober 8th, 2024 + +Attendees: *Ken* M., *Nick* A., *Jeff* L., *Andre* P, *Dan* B., *Greg* H. + +Regrets: *Rich* J. + +Additional Attendees: +John Mertic (Linux Foundation), Dhruv Govil (Apple), Mathew Cong (NVIDIA), +Jonathan Swartz (NVIDIA), JT Nelson (Blender), Victor Lu + +Agenda: + +1) Confirm quorum +2) Secretary +3) Re-licensing Progress +4) CI +5) Changing cpp test to gtest in AX +6) Deprecation Policy +7) PR-1916 - Nanobind PR +8) ABI and API Changes +9) Tube complex and thicken mesh +10) Next meeting + +------------ + +1) Confirm quorum + +Quorum is present. + +2) Secretary + +Secretary is Andre Pradhana. + +3) Re-licensing Progress + +NVIDIA has signed the CLA, but has not added their name to the list. ILM and +United Therapeutics have signed. + +The next step is to merge PR-1858 (which needs a second approval). Noted that +the PR probably needs to be updated to be more aligned with the master branch. +There was a suggestion to change the target of the PR to a feature branch to +bring everything up to date before merging to master. + +4) CI + +There are a few CI issues, e.g. with Houdini 20.5 and AX unit tests failing due +to LLVM version issues. + +5) Changing cpp test to gtest in AX + +Tim is looking at changing cpp test to unit test in +[PR-1919](https://github.com/AcademySoftwareFoundation/openvdb/pull/1919). + +6) Deprecation Policy + +Currently, we do not change the ABI until after the major release, i.e. we used +to add an extra minor release. + +We took a vote (six people agreed, one abstains) and agreed to drop ABI support +at the same time as a major release. Our deprecation policy is to support the +current and last two versions of the VFX reference platform. + +7) PR-1916 - Nanobind PR + +This PR is to switch from pybind11 to NanoBind. Andre agreed to take a look at +the PR. + +8) ABI and API Changes + +Dan went through a few suggestions: + - Root Node and Internal Nodes API changes: adding public methods to check if a + key exists in map and adding index-based iteration on internal nodes. + - Adding unsafe methods to bypass checks. It was suggested to add new methods + without unsafe labels. + +9) Tube complex and thicken mesh + +Greg will have a PR ready for creating tube complexes and thicken mesh. + +10) Next meeting + +Next meeting is on October 22nd, 2024. 2pm-3pm EDT (GMT-4). diff --git a/tsc/meetings/2024-10-22.md b/tsc/meetings/2024-10-22.md new file mode 100644 index 0000000000..c405ee6982 --- /dev/null +++ b/tsc/meetings/2024-10-22.md @@ -0,0 +1,151 @@ +Minutes from OpenVDB TSC meeting, October 22nd, 2024 + +Attendees: *Jeff* L., *Ken* M., *Andre* P., *Dan* B., *Nick* A., *Greg* H. + +Regrets: *Rich* J. + +Additional Attendees: +John Mertic (Linux Foundation), J. T. Nelson (Blender), Dhruv Govil (Apple), +Jonathan Swartz (NVIDIA), Matthew Cong (NVIDIA), Francis Williams (NVIDIA) + +Agenda: + +1) Confirm quorum +2) Secretary +3) Re-licensing to Apache and CLA/CCLA +4) CI +5) Drop ABI-9 support +6) PR-1916 +7) PR-1931 +8) PR-1936 +9) PR-1938 +10) PR-1939 +11) Half Grid Support PR +12) PR-1793 - Fillet in LevelSetFilter +13) PR-1794 +14) Pip Install OpenVDB +15) PR-1935 - Create Tubes and Thickened Mesh +16) Next Meeting + +------------ + +1) Confirm quorum + +Quorum is present. + +2) Secretary + +Secretary is Andre Pradhana. + +3) Re-licensing to Apache and CLA/CCLA + +The relicensing PR is merged. New contributions need to be licensed under +Apache, not SPDX. + +Today the following companies have signed for the new CLA: United Therapeutics, +Lucas Film, SideFX, and NVIDIA. Weta is in the process. Apple does individual +CLA. + +The process is that the old CLA will be taken out, documented for historic +purposes, and insert the new CLAs. New contributors need to sign the new CLA. +John Mertic needed approval from TSC members. + +We had concern regarding TSC members who cannot contribute code because they are +blocked by CLA approval. We voted if we needed to delay CLA update. Five people +agree to go through with updating the CLA and relicensing for VDB 12. John got +the approval. + +4) CI + +Dan fixed Windows CI. + +Weekly extra build has been upgraded to 2024 images now which uses LLVM 17. AX +was removed from this CI because of incompatibility. + +NanoVDB CI is updated to use 2024 OS Image. Andre looked at it and approved. + +5) Drop ABI-9 support + +We are dropping ABI-9 support for VDB-12. This means we are now dropping C++11 +and Python 3.7. + +Most notably, this also changes the old deprecation policy so that we do not +need to maintain an older version of the ABI for an extra minor release. + +6) [PR-1916](https://github.com/AcademySoftwareFoundation/openvdb/pull/1916) + +Nanobind support for OpenVDB and NanoVDB has the correct approvals. Dan merged +it. + +7) [PR-1931](https://github.com/AcademySoftwareFoundation/openvdb/pull/1931) + +A few methods were made to be public (e.g. haskey()). It’s suggested to make +some of the APIs to be aligned with what’s in the Tree API. + +Gave a motivation on the reason to add an API called deleteChildOrChild, which +gives one the ability to delete a child or coordinate that has a given +coordinate. A potential problem with the implementation detail of deleting an +element of a map is a case where one iterates through a map and deletes an entry +of the map, which invalidates the iterator itself. Needs good documentation, +e.g. calling this can invalidate child iterators. + +There is a bug in RooNode setOrigin. + +Ken will take a look. + +8) [PR-1936](https://github.com/AcademySoftwareFoundation/openvdb/pull/1936) + +Added const version of probeNode (for internal and root nodes) that didn’t exist +before. The API allows one to give the node type you want to probe and probe the +level below. + +The internal node can probe based on a child, but also overloads to probe with a +child, a value, and an activate state. + +The APIs have assert. + +Ken will take a look. + +9) [PR-1938](https://github.com/AcademySoftwareFoundation/openvdb/pull/1938) + +Discussion about adding unsafe methods, e.g. getValueUnsafe, getChildUnsafe. + +There was a concern: if a user deletes the word unsafe from the API call, will +the code still work? The answer is it depends on the implementation. + +Assert are added into these methods, so debug build should help with debugging +with a debug build. + +10) [PR-1939](https://github.com/AcademySoftwareFoundation/openvdb/pull/1939) + +Added a more efficient implementation in RootNode constructor by calling emplace +method in the table. + +Ken will take a look. + +11) Half Grid Support PR + +Andre and Greg will meet. We will create a feature/half_grid_branch and work +from there. + +12) [PR-1793](https://github.com/AcademySoftwareFoundation/openvdb/pull/1793) - Fillet in LevelSetFilter + +This PR is for VDB-12. + +13) [PR-1794](https://github.com/AcademySoftwareFoundation/openvdb/pull/1794) + +This PR is for VDB-12. + +14) Pip Install OpenVDB + +Matthew will try to get pip install for Python for VDB-12. + +15) [PR-1935](https://github.com/AcademySoftwareFoundation/openvdb/pull/1935) - Create Tubes and Thickened Mesh + +Discussed replacing the word thickened to dilate. Another suggestion along the +line of the term “alpha shape”. + +16) Next Meeting + +Next meeting is on October 29th, 2024. 2pm-3pm EDT (GMT-4). + From fe71e9da2a8020048d6c8741cbc6bd295cebfeea Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 29 Oct 2024 10:20:00 -0700 Subject: [PATCH 42/98] Disable undefined sanitization in transformValues() Signed-off-by: Dan Bailey --- openvdb/openvdb/tools/ValueTransformer.h | 14 ++++++++------ openvdb/openvdb/unittest/TestTools.cc | 1 - 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openvdb/openvdb/tools/ValueTransformer.h b/openvdb/openvdb/tools/ValueTransformer.h index 0022e49db5..a3ff7dc006 100644 --- a/openvdb/openvdb/tools/ValueTransformer.h +++ b/openvdb/openvdb/tools/ValueTransformer.h @@ -135,12 +135,14 @@ inline void foreach(const IterT& iter, const XformOp& op, /// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction /// with a tree::IteratorRange that wraps a grid or tree iterator. template -inline void transformValues(const InIterT& inIter, OutGridT& outGrid, +inline __attribute__((no_sanitize("undefined"))) +void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, bool threaded = true, bool shareOp = true, MergePolicy merge = MERGE_ACTIVE_STATES); template -inline void transformValues(const InIterT& inIter, OutGridT& outGrid, +inline __attribute__((no_sanitize("undefined"))) +void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op, bool threaded = true, bool shareOp = true, MergePolicy merge = MERGE_ACTIVE_STATES); @@ -585,8 +587,8 @@ class CopyableOpTransformer template -inline void -transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, +inline __attribute__((no_sanitize("undefined"))) +void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, bool threaded, bool shared, MergePolicy merge) { using Adapter = TreeAdapter; @@ -603,8 +605,8 @@ transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, } template -inline void -transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op, +inline __attribute__((no_sanitize("undefined"))) +void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op, bool threaded, bool /*share*/, MergePolicy merge) { using Adapter = TreeAdapter; diff --git a/openvdb/openvdb/unittest/TestTools.cc b/openvdb/openvdb/unittest/TestTools.cc index 931f879614..d8780dba1c 100644 --- a/openvdb/openvdb/unittest/TestTools.cc +++ b/openvdb/openvdb/unittest/TestTools.cc @@ -1498,7 +1498,6 @@ struct FloatToVec } - TEST_F(TestTools, testTransformValues) { using openvdb::CoordBBox; From 49cc7de94a44b7d14b8e748977be910fb2415779 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 29 Oct 2024 12:33:19 -0700 Subject: [PATCH 43/98] Switch to ubsan suppress macro Signed-off-by: Dan Bailey --- openvdb/openvdb/tools/ValueTransformer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openvdb/openvdb/tools/ValueTransformer.h b/openvdb/openvdb/tools/ValueTransformer.h index a3ff7dc006..0d9af45858 100644 --- a/openvdb/openvdb/tools/ValueTransformer.h +++ b/openvdb/openvdb/tools/ValueTransformer.h @@ -135,13 +135,13 @@ inline void foreach(const IterT& iter, const XformOp& op, /// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction /// with a tree::IteratorRange that wraps a grid or tree iterator. template -inline __attribute__((no_sanitize("undefined"))) +inline OPENVDB_UBSAN_SUPPRESS("undefined") void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, bool threaded = true, bool shareOp = true, MergePolicy merge = MERGE_ACTIVE_STATES); template -inline __attribute__((no_sanitize("undefined"))) +inline OPENVDB_UBSAN_SUPPRESS("undefined") void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op, bool threaded = true, bool shareOp = true, MergePolicy merge = MERGE_ACTIVE_STATES); @@ -587,7 +587,7 @@ class CopyableOpTransformer template -inline __attribute__((no_sanitize("undefined"))) +inline OPENVDB_UBSAN_SUPPRESS("undefined") void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, bool threaded, bool shared, MergePolicy merge) { @@ -605,7 +605,7 @@ void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op, } template -inline __attribute__((no_sanitize("undefined"))) +inline OPENVDB_UBSAN_SUPPRESS("undefined") void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op, bool threaded, bool /*share*/, MergePolicy merge) { From 2e580072bb032c2d0148fa68db88458860b11a45 Mon Sep 17 00:00:00 2001 From: Jeff Lait Date: Tue, 29 Oct 2024 15:38:54 -0400 Subject: [PATCH 44/98] TSC Meeting notes for Oct 29th 2024. Merge in pending changes. Signed-off-by: Jeff Lait --- CHANGES | 152 +++++++++++++++++++++- doc/changes.txt | 160 ++++++++++++++++++++++++ pendingchanges/assert.txt | 6 - pendingchanges/ax_windows_cmake_fix.txt | 3 - pendingchanges/boost_promote.txt | 4 - pendingchanges/explicit_inst_win.txt | 3 - pendingchanges/houdinirpath.txt | 3 - pendingchanges/iofix.txt | 3 - pendingchanges/jemalloc.txt | 3 - pendingchanges/nanobind.txt | 4 - pendingchanges/nanovdb_32.7.txt | 85 ------------- pendingchanges/root_node.txt | 9 -- pendingchanges/root_node_emplace.txt | 2 - pendingchanges/tsan_spheres.txt | 5 - pendingchanges/ubsan.txt | 3 - pendingchanges/value_accessors_tree.txt | 3 - pendingchanges/windows_static_blosc.txt | 2 - tsc/meetings/2024-10-29.md | 140 +++++++++++++++++++++ 18 files changed, 451 insertions(+), 139 deletions(-) delete mode 100644 pendingchanges/assert.txt delete mode 100644 pendingchanges/ax_windows_cmake_fix.txt delete mode 100644 pendingchanges/boost_promote.txt delete mode 100644 pendingchanges/explicit_inst_win.txt delete mode 100644 pendingchanges/houdinirpath.txt delete mode 100644 pendingchanges/iofix.txt delete mode 100644 pendingchanges/jemalloc.txt delete mode 100644 pendingchanges/nanobind.txt delete mode 100644 pendingchanges/nanovdb_32.7.txt delete mode 100644 pendingchanges/root_node.txt delete mode 100644 pendingchanges/root_node_emplace.txt delete mode 100644 pendingchanges/tsan_spheres.txt delete mode 100644 pendingchanges/ubsan.txt delete mode 100644 pendingchanges/value_accessors_tree.txt delete mode 100644 pendingchanges/windows_static_blosc.txt create mode 100644 tsc/meetings/2024-10-29.md diff --git a/CHANGES b/CHANGES index c0d27a1ce9..46582faa71 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,157 @@ OpenVDB Version History ======================= -Version 11.0.1 - In development +Version 12.0.0 - In development + + OpenVDB: + Improvements: + - Added openvdb::assertAbort to replace cassert and a + OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle + assertions in OpenVDB code, independantly of NDEBUG. Asserts are + no longer enabled by default in when NDEBUG is absent (e.g. + Debug builds). + - Removed last traces of Boost when OPENVDB_USE_DELAYED_LOADING is OFF + [Reported by Brian McKinnon] + - RootNode code cleanup to eliminate redundant key conversion and + to create map values in-place. + - Add RootNode::deleteChildOrTile() to delete a child or tile of + the root node. + - ValueAccessors are now defined and created in the Tree class + instead of in the Grid class so that custom Tree implementations + may define and create their own ValueAccessors if desired. + + API Changes: + - RootNode::tileCount(), RootNode::activeTileCount() and + RootNode::inactiveTileCount() are now public. + - RootNode::hasKey() and RootNode::coordToKey() are now public. + + Bug Fixes: + - Fix potential crash reading corrupt .vdb files with invalid + blosc or zip chunks. + [Fix thanks to Matthias Ueberheide] + - Fix a bug in RootNode::setOrigin() where the origin was updated + before the error was thrown potentially leaving the root in an + invalid state. + - Fixed a thread sanitizer issue which could cause undefined + behaviour in VolumeToSpheres::fillWithSpheres + [Reported by Jérémie Dumas] + - Fixed an occurance of undefined behaviour in tools::activate + (though this would typically not have manifested with any + unintended behaviour) + + NanoVDB: + Bug fix: + - nanovdb::readGrids works with raw grid buffer. + + Improvements: + - Restructure files location and namespace to be more align with + OpenVDB. The namespaces touched by the restructuring are: io, + cuda, util, tools, and math. + - Add two scripts updateFiles.sh and updateFiles.py to update the + files using NanoVDB. The script updateFiles.py works on both + Windows and Linux. For a more complete list of changes, see API + Changes (details). + + - cuda::PointsToGrid supports target density. + - Add support for NanoVDB Grid of type UInt8. + - Add ability to use externally managed CUDA buffer. + - Add create methods for CudaDeviceBuffer and exceptions. + - Improve GridValidator logic, e.g. include check for grid count. + - Add operator > and >= for class Coord according to lexicographical order. + - Add toCodec to convert string to Codec enumeration type. + - Add nanovdb::strlen(). + - Add strncpy util. + - Add NANOVDB_DISABLE_SYNC_CUDA_MALLOC that maps cudaMallocAsync + and cudaFreeAsync to cudaMalloc and cudaFree respectively. + - Add guard to UINT64_C. + - Remove use of cudaMallocAsync in PointsToGrid.cuh. + - Align PNanoVDB blind metadata to NanoVDB. + + API Changes: + - Change mapToGridType to toGridType. + - Change mapToMagic to toMagic. + - Change CpuTimer.h to Timer.h. + + API Changes (details): + - These APIs are now under the math namespace: 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. + + - These APIs are now under the tools namespace: createNanoGrid, + StatsMode, createLevelSetSphere, createFogVolumeSphere, + createFogVolumeSphere, createFogVolumeSphere, + createFogVolumeTorus, createLevelSetBox, CreateNanoGrid, + updateGridStats, evalChecksum, validateChecksum, checkGrid, + Extrema. + - These APIs are now under the util namespace: is_floating_point, + findLowestOn, findHighestOn, Range, streq, strcpy, strcat, + empty, Split, invoke, forEach, reduce, prefixSum, is_same, + is_specialization, PtrAdd, PtrDiff. + + - Move nanovdb::build to nanovdb::tools::build. + - Rename nanovdb::BBoxR to nanovdb::Vec3dBBox. + - Rename nanovdb::BBox to nanovdb::Vec3dBbox. + - Move nanovdb::cudaCreateNodeManager to nanovdb::cuda::createNodeManager. + - Move and rename nanovdb::cudaVoxelsToGrid to nanovdb::cuda::voxelsToGrid. + - Move and rename nanovdb::cudaPointsToGrid to nanovdb::cuda::pointsToGrid. + - Move nanovdb::DitherLUT to nanovdb::math::DitherLUT. + - Move and rename nanovdb::PackedRGBA8 to nanovdb::math::Rgba8. + - Move nanovdb::Rgba8 to nanovdb::math::Rgba8. + - Move and rename nanovdb::CpuTimer to nanovdb::util::Timer. + - Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. + - Move and rename nanovdb::CountOn to nanovdb::util::countOn. + + - Move util/GridHandle.h to GridHandle.h. + - Move util/BuildGrid.h to tools/GridBuilder.h. + - Move util/GridBuilder.h to tools/GridBuilder.h. + - Move util/IO.h to io/IO.h. + - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. + - Move util/DitherLUT.h to math/DitherLUT.h. + - Move util/HDDA.h to math/HDDA.h. + - Move util/Ray.h to math/Ray.h. + - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. + - Move util/Stencils.h to nanovdb/math/Stencils.h. + - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. + - Move and rename util/Primitives.h to tools/CreatePrimitives.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridStats.h to tools/GridStats.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridValidator.h to tools/GridValidator.h. + - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. + - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. + - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. + - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. + - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. + - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. + - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. + - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. + - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. + - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. + - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. + + Houdini: + - When OPENVDB_ENABLE_RPATH is ON, the location of + libopenvdb_houdini is now added to the rpath of all Houdini + dsos. + + Python: + - OpenVDB Python bindings are now implemented using nanobind + instead of pybind11 + - The OpenVDB Python module has been changed from pyopenvdb to openvdb + - Added Python bindings for NanoVDB + + Build: + - Fixed an issue with OpenVDB AX's CMake on Windows where the + static and shared library targets would have the same name + [Reported by Nicholas Yue] + - USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default + due to OOM linker issues. + - Jemalloc is now the preferred allocator of choice on all + platforms when CONCURRENT_MALLOC is set to Auto. + - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB + Windows static library. Version 11.0.0 - November 1, 2023 diff --git a/doc/changes.txt b/doc/changes.txt index b7435d86d2..4fb6330b79 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -2,6 +2,166 @@ @page changes Release Notes +@htmlonly @endhtmlonly +@par +Version 12.0.0 - In Development + +@par +OpenVDB: +- Improvements: + - Added openvdb::assertAbort to replace cassert and a + OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle + assertions in OpenVDB code, independantly of NDEBUG. Asserts are + no longer enabled by default in when NDEBUG is absent (e.g. + Debug builds). + - Removed last traces of Boost when OPENVDB_USE_DELAYED_LOADING is OFF + [Reported by Brian McKinnon] + - RootNode code cleanup to eliminate redundant key conversion and + to create map values in-place. + - Add RootNode::deleteChildOrTile() to delete a child or tile of + the root node. + - ValueAccessors are now defined and created in the Tree class + instead of in the Grid class so that custom Tree implementations + may define and create their own ValueAccessors if desired. + +- API Changes: + - RootNode::tileCount(), RootNode::activeTileCount() and + RootNode::inactiveTileCount() are now public. + - RootNode::hasKey() and RootNode::coordToKey() are now public. + +- Bug Fixes: + - Fix potential crash reading corrupt .vdb files with invalid + blosc or zip chunks. + [Fix thanks to Matthias Ueberheide] + - Fix a bug in RootNode::setOrigin() where the origin was updated + before the error was thrown potentially leaving the root in an + invalid state. + - Fixed a thread sanitizer issue which could cause undefined + behaviour in VolumeToSpheres::fillWithSpheres + [Reported by Jérémie Dumas] + - Fixed an occurance of undefined behaviour in tools::activate + (though this would typically not have manifested with any + unintended behaviour) + +@par +NanoVDB: +- Bug fix: + - nanovdb::readGrids works with raw grid buffer. + +- Improvements: + - Restructure files location and namespace to be more align with + OpenVDB. The namespaces touched by the restructuring are: io, + cuda, util, tools, and math. + - Add two scripts updateFiles.sh and updateFiles.py to update the + files using NanoVDB. The script updateFiles.py works on both + Windows and Linux. For a more complete list of changes, see API + Changes (details). + + - cuda::PointsToGrid supports target density. + - Add support for NanoVDB Grid of type UInt8. + - Add ability to use externally managed CUDA buffer. + - Add create methods for CudaDeviceBuffer and exceptions. + - Improve GridValidator logic, e.g. include check for grid count. + - Add operator > and >= for class Coord according to lexicographical order. + - Add toCodec to convert string to Codec enumeration type. + - Add nanovdb::strlen(). + - Add strncpy util. + - Add NANOVDB_DISABLE_SYNC_CUDA_MALLOC that maps cudaMallocAsync + and cudaFreeAsync to cudaMalloc and cudaFree respectively. + - Add guard to UINT64_C. + - Remove use of cudaMallocAsync in PointsToGrid.cuh. + - Align PNanoVDB blind metadata to NanoVDB. + +- API Changes: + - Change mapToGridType to toGridType. + - Change mapToMagic to toMagic. + - Change CpuTimer.h to Timer.h. + +- API Changes (details): + - These APIs are now under the math namespace: 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. + + - These APIs are now under the tools namespace: createNanoGrid, + StatsMode, createLevelSetSphere, createFogVolumeSphere, + createFogVolumeSphere, createFogVolumeSphere, + createFogVolumeTorus, createLevelSetBox, CreateNanoGrid, + updateGridStats, evalChecksum, validateChecksum, checkGrid, + Extrema. + - These APIs are now under the util namespace: is_floating_point, + findLowestOn, findHighestOn, Range, streq, strcpy, strcat, + empty, Split, invoke, forEach, reduce, prefixSum, is_same, + is_specialization, PtrAdd, PtrDiff. + + - Move nanovdb::build to nanovdb::tools::build. + - Rename nanovdb::BBoxR to nanovdb::Vec3dBBox. + - Rename nanovdb::BBox to nanovdb::Vec3dBbox. + - Move nanovdb::cudaCreateNodeManager to nanovdb::cuda::createNodeManager. + - Move and rename nanovdb::cudaVoxelsToGrid to nanovdb::cuda::voxelsToGrid. + - Move and rename nanovdb::cudaPointsToGrid to nanovdb::cuda::pointsToGrid. + - Move nanovdb::DitherLUT to nanovdb::math::DitherLUT. + - Move and rename nanovdb::PackedRGBA8 to nanovdb::math::Rgba8. + - Move nanovdb::Rgba8 to nanovdb::math::Rgba8. + - Move and rename nanovdb::CpuTimer to nanovdb::util::Timer. + - Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. + - Move and rename nanovdb::CountOn to nanovdb::util::countOn. + + - Move util/GridHandle.h to GridHandle.h. + - Move util/BuildGrid.h to tools/GridBuilder.h. + - Move util/GridBuilder.h to tools/GridBuilder.h. + - Move util/IO.h to io/IO.h. + - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. + - Move util/DitherLUT.h to math/DitherLUT.h. + - Move util/HDDA.h to math/HDDA.h. + - Move util/Ray.h to math/Ray.h. + - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. + - Move util/Stencils.h to nanovdb/math/Stencils.h. + - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. + - Move and rename util/Primitives.h to tools/CreatePrimitives.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridStats.h to tools/GridStats.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridValidator.h to tools/GridValidator.h. + - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. + - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. + - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. + - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. + - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. + - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. + - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. + - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. + - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. + - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. + - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. + +@par +Python: + - OpenVDB Python bindings are now implemented using nanobind + instead of pybind11 + - The OpenVDB Python module has been changed from pyopenvdb to openvdb + - Added Python bindings for NanoVDB + +@par +Houdini: + - When OPENVDB_ENABLE_RPATH is ON, the location of + libopenvdb_houdini is now added to the rpath of all Houdini + dsos. + +@par +Build: + - Fixed an issue with OpenVDB AX's CMake on Windows where the + static and shared library targets would have the same name + [Reported by Nicholas Yue] + - USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default + due to OOM linker issues. + - Jemalloc is now the preferred allocator of choice on all + platforms when CONCURRENT_MALLOC is set to Auto. + - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB + Windows static library. + + @htmlonly @endhtmlonly @par Version 11.0.0 - November 1, 2023 diff --git a/pendingchanges/assert.txt b/pendingchanges/assert.txt deleted file mode 100644 index 76502ccd00..0000000000 --- a/pendingchanges/assert.txt +++ /dev/null @@ -1,6 +0,0 @@ -OpenVDB: - Improvements: - - Added openvdb::assertAbort to replace cassert and a OPENVDB_ENABLE_ASSERTS - cmake argument/compile define to toggle assertions in OpenVDB code, - independantly of NDEBUG. Asserts are no longer enabled by default in - when NDEBUG is absent (e.g. Debug builds). diff --git a/pendingchanges/ax_windows_cmake_fix.txt b/pendingchanges/ax_windows_cmake_fix.txt deleted file mode 100644 index d022feaa4e..0000000000 --- a/pendingchanges/ax_windows_cmake_fix.txt +++ /dev/null @@ -1,3 +0,0 @@ -Build: - - Fixed an issue with OpenVDB AX's CMake on Windows where the static and shared library targets would have the same name - [Reported by Nicholas Yue] diff --git a/pendingchanges/boost_promote.txt b/pendingchanges/boost_promote.txt deleted file mode 100644 index 97ebdddb0d..0000000000 --- a/pendingchanges/boost_promote.txt +++ /dev/null @@ -1,4 +0,0 @@ -OpenVDB: - Improvements: - - Removed last traces of Boost when OPENVDB_USE_DELAYED_LOADING is OFF - [Reported by Brian McKinnon] diff --git a/pendingchanges/explicit_inst_win.txt b/pendingchanges/explicit_inst_win.txt deleted file mode 100644 index f86db01b8d..0000000000 --- a/pendingchanges/explicit_inst_win.txt +++ /dev/null @@ -1,3 +0,0 @@ -Build: - - USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default due to - OOM linker issues. diff --git a/pendingchanges/houdinirpath.txt b/pendingchanges/houdinirpath.txt deleted file mode 100644 index 2165afe686..0000000000 --- a/pendingchanges/houdinirpath.txt +++ /dev/null @@ -1,3 +0,0 @@ -Houdini: - - When OPENVDB_ENABLE_RPATH is ON, the location of libopenvdb_houdini is now - added to the rpath of all Houdini dsos. diff --git a/pendingchanges/iofix.txt b/pendingchanges/iofix.txt deleted file mode 100644 index 6d095d7a02..0000000000 --- a/pendingchanges/iofix.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bug Fixes: - - Fix potential crash reading corrupt .vdb files with invalid - blosc or zip chunks. [Fix thanks to Matthias Ueberheide] diff --git a/pendingchanges/jemalloc.txt b/pendingchanges/jemalloc.txt deleted file mode 100644 index 4db76f91b2..0000000000 --- a/pendingchanges/jemalloc.txt +++ /dev/null @@ -1,3 +0,0 @@ -Build: - - Jemalloc is now the preferred allocator of choice on all platforms when - CONCURRENT_MALLOC is set to Auto. diff --git a/pendingchanges/nanobind.txt b/pendingchanges/nanobind.txt deleted file mode 100644 index 19e3ff839c..0000000000 --- a/pendingchanges/nanobind.txt +++ /dev/null @@ -1,4 +0,0 @@ -Python: - - OpenVDB Python bindings are now implemented using nanobind instead of pybind11 - - The OpenVDB Python module has been changed from pyopenvdb to openvdb - - Added Python bindings for NanoVDB diff --git a/pendingchanges/nanovdb_32.7.txt b/pendingchanges/nanovdb_32.7.txt deleted file mode 100644 index 78e2f71d01..0000000000 --- a/pendingchanges/nanovdb_32.7.txt +++ /dev/null @@ -1,85 +0,0 @@ -Bug fix: -nanovdb::readGrids works with raw grid buffer. - -Improvements: -Restructure files location and namespace to be more align with OpenVDB. The -namespaces touched by the restructuring are: io, cuda, util, tools, and math. -Add two scripts updateFiles.sh and updateFiles.py to update the files using -NanoVDB. The script updateFiles.py works on both Windows and Linux. -For a more complete list of changes, see API Changes (details). - -cuda::PointsToGrid supports target density. -Add support for NanoVDB Grid of type UInt8. -Add ability to use externally managed CUDA buffer. -Add create methods for CudaDeviceBuffer and exceptions. -Improve GridValidator logic, e.g. include check for grid count. -Add operator > and >= for class Coord according to lexicographical order. -Add toCodec to convert string to Codec enumeration type. -Add nanovdb::strlen(). -Add strncpy util. -Add NANOVDB_DISABLE_SYNC_CUDA_MALLOC that maps cudaMallocAsync and -cudaFreeAsync to cudaMalloc and cudaFree respectively. -Add guard to UINT64_C. -Remove use of cudaMallocAsync in PointsToGrid.cuh. -Align PNanoVDB blind metadata to NanoVDB. - -API Changes: -Change mapToGridType to toGridType. -Change mapToMagic to toMagic. -Change CpuTimer.h to Timer.h. - -API Changes (details): -These APIs are now under the math namespace: 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. - -These APIs are now under the tools namespace: createNanoGrid, StatsMode, -createLevelSetSphere, createFogVolumeSphere, createFogVolumeSphere, -createFogVolumeSphere, createFogVolumeTorus, createLevelSetBox, CreateNanoGrid, -updateGridStats, evalChecksum, validateChecksum, checkGrid, Extrema. - -These APIs are now under the util namespace: is_floating_point, findLowestOn, -findHighestOn, Range, streq, strcpy, strcat, empty, Split, invoke, forEach, -reduce, prefixSum, is_same, is_specialization, PtrAdd, PtrDiff. - -Move nanovdb::build to nanovdb::tools::build. -Rename nanovdb::BBoxR to nanovdb::Vec3dBBox. -Rename nanovdb::BBox to nanovdb::Vec3dBbox. -Move nanovdb::cudaCreateNodeManager to nanovdb::cuda::createNodeManager. -Move and rename nanovdb::cudaVoxelsToGrid to nanovdb::cuda::voxelsToGrid. -Move and rename nanovdb::cudaPointsToGrid to nanovdb::cuda::pointsToGrid. -Move nanovdb::DitherLUT to nanovdb::math::DitherLUT. -Move and rename nanovdb::PackedRGBA8 to nanovdb::math::Rgba8. -Move nanovdb::Rgba8 to nanovdb::math::Rgba8. -Move and rename nanovdb::CpuTimer to nanovdb::util::Timer. -Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. -Move and rename nanovdb::CountOn to nanovdb::util::countOn. - -Move util/GridHandle.h to GridHandle.h. -Move util/BuildGrid.h to tools/GridBuilder.h. -Move util/GridBuilder.h to tools/GridBuilder.h. -Move util/IO.h to io/IO.h. -Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. -Move util/DitherLUT.h to math/DitherLUT.h. -Move util/HDDA.h to math/HDDA.h. -Move util/Ray.h to math/Ray.h. -Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. -Move util/Stencils.h to nanovdb/math/Stencils.h. -Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. -Move and rename util/Primitives.h to tools/CreatePrimitives.h. -Move util/GridChecksum.h to tools/GridChecksum.h. -Move util/GridStats.h to tools/GridStats.h. -Move util/GridChecksum.h to tools/GridChecksum.h. -Move util/GridValidator.h to tools/GridValidator.h. -Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. -Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. -Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. -Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. -Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. -Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. -Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. -Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. -Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. -Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. -Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. diff --git a/pendingchanges/root_node.txt b/pendingchanges/root_node.txt deleted file mode 100644 index 21fd020bda..0000000000 --- a/pendingchanges/root_node.txt +++ /dev/null @@ -1,9 +0,0 @@ -API Changes: - - RootNode::tileCount(), RootNode::activeTileCount() and RootNode::inactiveTileCount() are now public. - - RootNode::hasKey() and RootNode::coordToKey() are now public. - -Improvements: - - Add RootNode::deleteChildOrTile() to delete a child or tile of the root node. - -Bug Fixes: - - Fix a bug in RootNode::setOrigin() where the origin was updated before the error was thrown potentially leaving the root in an invalid state. \ No newline at end of file diff --git a/pendingchanges/root_node_emplace.txt b/pendingchanges/root_node_emplace.txt deleted file mode 100644 index 5c1d0d739c..0000000000 --- a/pendingchanges/root_node_emplace.txt +++ /dev/null @@ -1,2 +0,0 @@ -Improvements: - - RootNode code cleanup to eliminate redundant key conversion and to create map values in-place. \ No newline at end of file diff --git a/pendingchanges/tsan_spheres.txt b/pendingchanges/tsan_spheres.txt deleted file mode 100644 index 150bdb7803..0000000000 --- a/pendingchanges/tsan_spheres.txt +++ /dev/null @@ -1,5 +0,0 @@ -OpenVDB: - Bug Fixes: - - Fixed a thread sanitizer issue which could cause undefined behaviour - in VolumeToSpheres::fillWithSpheres - [Reported by Jérémie Dumas] diff --git a/pendingchanges/ubsan.txt b/pendingchanges/ubsan.txt deleted file mode 100644 index f050fd29e0..0000000000 --- a/pendingchanges/ubsan.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenVDB: - - Bug Fixes:: - - Fixed an occurance of undefined behaviour in tools::activate (though this would typically not have manifested with any unintended behaviour) diff --git a/pendingchanges/value_accessors_tree.txt b/pendingchanges/value_accessors_tree.txt deleted file mode 100644 index 8076f7cd6c..0000000000 --- a/pendingchanges/value_accessors_tree.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenVDB: - Improvements: - - ValueAccessors are now defined and created in the Tree class instead of in the Grid class so that custom Tree implementations may define and create their own ValueAccessors if desired. diff --git a/pendingchanges/windows_static_blosc.txt b/pendingchanges/windows_static_blosc.txt deleted file mode 100644 index 882dc1f3fa..0000000000 --- a/pendingchanges/windows_static_blosc.txt +++ /dev/null @@ -1,2 +0,0 @@ -Build: - - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB Windows static library. diff --git a/tsc/meetings/2024-10-29.md b/tsc/meetings/2024-10-29.md new file mode 100644 index 0000000000..98a157f6f8 --- /dev/null +++ b/tsc/meetings/2024-10-29.md @@ -0,0 +1,140 @@ +Minutes from OpenVDB TSC meeting, October 29th, 2024 + +Attendees: *Ken* M., *Jeff* L., *Andre* P, *Dan* B., *Greg* H, *Nick* A. + +Additional Attendees: Dhruv Govil (Apple), Mathew Cong (NVIDIA), +Jonathan Swartz (NVIDIA) + +Regrets: *Richard* J. + +Agenda: + +1) Confirm quorum +2) Secretary +3) Meeting Times +4) OpenVDB 12 PRs +5) 12 Release +6) Next Meeting + +------------ + +1) Confirm quorum + +Quorum is present. + +2) Secretary + +Secretary is Jeff Lait. + +3) Meeting Times + +Do we alternate meeting times to get better universal times? + +We've lacked agenda so it is unclear if you need to show up or not. + +We need to be better at uploading meeting notes. + +In the winter, 8am works in NZ. We should figure out a better schedule for the summer. Either a new day or alternate days. + +We are able to sync and update the calendar now! + +We should start the call for agenda items again. + +Next weeks meeting we should each know what days don't work for this +time slot, so we can see if a non-Tuesday will work. + +4) OpenVDB 12 PRs + + +a) PR1936, 1938, 1939 + +Feedback addressed, ready to go. + +b) 1951 + +Awaiting on NVidia CLA. + +c) 1941 + +Awaiting on NVidia CLA. + +SKBuild is a bit of a mess. This is from the featurevdb vs nanovdb branches. Ideally only on SKBuild test? + +d) 1952 + +Need to sudo make install. Cleaned up old code. Now falls back +rather than uses complicated logic. + +Approved and ready. + +e) 1954 + +Newest container complains about undefined behaviour, we should fix +eventually, but turn off so it passes. We used to use a macro for +this, but it is believed __attribute__ is now supported by GCC. + +Nick will investigate, might be failing on Windows. + +f) 1794 + +Prevent integer overflow. + +This is an ABI change. Virtual functions now return different things. +Return type doesn't necessarily affect the mangle, but might affect the layout. + +We add a nodeCount(std::vector) rather than replace, and +deprecate the Index32 in new ABI. + +The version that returns std::vector needs both versions +switched according to the ABI type. + +We should also switch nonLeafCount at the same time rather than +waiting for next 2^32 overflow. + +g) 1935 + +Tube complex PR. + +Needs more unit tests. ConvexVoxelizer uses GridT, but things are +cast to float internally? Is this a float only setup? Should there be +static_asserts to early exit? This was originally float only and +tried to make generic. Passes shared pointer to grid, but holds +reference to a tree - should keep shared pointer to grid keep +lifetime guarantees. + +Should this all be put into one header? But these are separate functions. + +Should ConvexVoxelizer be a private namespace? Similar to Points api? +Ideally the user's entry ponit is a nicely documented header file. +Convex Voxelizer is meant to be a starting point for new types. An +example for a level set sphere test is provided. + +This should have its own unit test rather than adding to test tools. + +This can wait for VDB 12.1. + +h) Half grid feature branch + +Vec3h - Vec3h doesn't work.... Still failing unit tests. + +Not including means that .vdb files can't use this natively, as VDB12 +compliant DCC will not necessarily have this type registered. + +Requires too much for VDB12 release. + +We need a placeholder PR so we remember to finish this. + +i) 1821 + +PDAL support. Missing unit tests. Handles LIDAR style point formats. +Will be delayed until unit tests, can go in VDB12.1. + +5) Release + +Dan will do the release. PRs need to be merged by the 30th. + +6) Next Meeting + +Agenda: Dilation. New TSC meeting day + +Next Meeting 11-05-2024 at the same time. From 7f6945bd0089c85b266eea6bcaf32e953f95eb39 Mon Sep 17 00:00:00 2001 From: Jeff Lait Date: Tue, 29 Oct 2024 15:44:09 -0400 Subject: [PATCH 45/98] Fix trailing spaces. Signed-off-by: Jeff Lait --- CHANGES | 2 +- doc/changes.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 46582faa71..677d8794d7 100644 --- a/CHANGES +++ b/CHANGES @@ -27,7 +27,7 @@ Version 12.0.0 - In development Bug Fixes: - Fix potential crash reading corrupt .vdb files with invalid - blosc or zip chunks. + blosc or zip chunks. [Fix thanks to Matthias Ueberheide] - Fix a bug in RootNode::setOrigin() where the origin was updated before the error was thrown potentially leaving the root in an diff --git a/doc/changes.txt b/doc/changes.txt index 4fb6330b79..24f41674b8 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -31,7 +31,7 @@ OpenVDB: - Bug Fixes: - Fix potential crash reading corrupt .vdb files with invalid - blosc or zip chunks. + blosc or zip chunks. [Fix thanks to Matthias Ueberheide] - Fix a bug in RootNode::setOrigin() where the origin was updated before the error was thrown potentially leaving the root in an From 5e4bb9f3ea8e2ce563b6cd536764b4016fcb4eaa Mon Sep 17 00:00:00 2001 From: Matthew Cong Date: Mon, 30 Sep 2024 14:28:45 -0700 Subject: [PATCH 46/98] Add initial pip install implementation Signed-off-by: Matthew Cong --- CMakeLists.txt | 6 +- nanovdb/nanovdb/CMakeLists.txt | 6 +- nanovdb/nanovdb/cmd/CMakeLists.txt | 12 +++- nanovdb/nanovdb/examples/CMakeLists.txt | 6 +- nanovdb/nanovdb/python/CMakeLists.txt | 8 ++- nanovdb/nanovdb/python/__init__.py | 7 +++ openvdb/openvdb/CMakeLists.txt | 77 +++++++++++++++++-------- openvdb/openvdb/python/CMakeLists.txt | 9 ++- openvdb/openvdb/python/__init__.py | 1 + openvdb_ax/openvdb_ax/CMakeLists.txt | 57 ++++++++++++------ openvdb_cmd/CMakeLists.txt | 6 ++ openvdb_cmd/vdb_ax/CMakeLists.txt | 2 +- openvdb_cmd/vdb_lod/CMakeLists.txt | 2 +- openvdb_cmd/vdb_print/CMakeLists.txt | 2 +- openvdb_cmd/vdb_render/CMakeLists.txt | 2 +- openvdb_cmd/vdb_tool/CMakeLists.txt | 2 +- openvdb_cmd/vdb_view/CMakeLists.txt | 2 +- pyproject.toml | 46 +++++++++++++++ 18 files changed, 197 insertions(+), 56 deletions(-) create mode 100644 nanovdb/nanovdb/python/__init__.py create mode 100644 openvdb/openvdb/python/__init__.py create mode 100644 pyproject.toml diff --git a/CMakeLists.txt b/CMakeLists.txt index 257cce8c4e..8a17943004 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,7 +298,11 @@ if(OPENVDB_INSTALL_CMAKE_MODULES) cmake/OpenVDBMayaSetup.cmake cmake/OpenVDBUtils.cmake ) - install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenVDB) + if(SKBUILD) + install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR}/cmake/OpenVDB) + else() + install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenVDB) + endif() endif() # Configure component dependencies by loading the Houdini/Maya setup diff --git a/nanovdb/nanovdb/CMakeLists.txt b/nanovdb/nanovdb/CMakeLists.txt index 48d327d94e..7392fc7839 100644 --- a/nanovdb/nanovdb/CMakeLists.txt +++ b/nanovdb/nanovdb/CMakeLists.txt @@ -322,7 +322,11 @@ if(TARGET Threads::Threads) target_link_libraries(nanovdb INTERFACE Threads::Threads) endif() -set(NANOVDB_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/nanovdb) +if(SKBUILD) + set(NANOVDB_INSTALL_INCLUDE_DIR nanovdb/${CMAKE_INSTALL_INCLUDEDIR}/nanovdb) +else() + set(NANOVDB_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/nanovdb) +endif() set(NANOVDB_INSTALL_CUDA_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/cuda) set(NANOVDB_INSTALL_IO_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/io) set(NANOVDB_INSTALL_MATH_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/math) diff --git a/nanovdb/nanovdb/cmd/CMakeLists.txt b/nanovdb/nanovdb/cmd/CMakeLists.txt index f8162d8a7b..bad16c075a 100644 --- a/nanovdb/nanovdb/cmd/CMakeLists.txt +++ b/nanovdb/nanovdb/cmd/CMakeLists.txt @@ -27,22 +27,28 @@ endif() # ----------------------------------------------------------------------------- +if(SKBUILD) + set(NANOVDB_INSTALL_BINDIR nanovdb/${CMAKE_INSTALL_BINDIR}) +else() + set(NANOVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}) +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 ${CMAKE_INSTALL_BINDIR}) + 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 ${CMAKE_INSTALL_BINDIR}) +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 ${CMAKE_INSTALL_BINDIR}) +install(TARGETS nanovdb_validate RUNTIME DESTINATION ${NANOVDB_INSTALL_BINDIR}) diff --git a/nanovdb/nanovdb/examples/CMakeLists.txt b/nanovdb/nanovdb/examples/CMakeLists.txt index 4ccececa9e..da4cf64180 100644 --- a/nanovdb/nanovdb/examples/CMakeLists.txt +++ b/nanovdb/nanovdb/examples/CMakeLists.txt @@ -78,7 +78,11 @@ function(NANOVDB_EXAMPLE) target_include_directories(${EXAMPLE_NAME} PUBLIC ex_util) target_link_libraries(${EXAMPLE_NAME} PRIVATE nanovdb) - install(TARGETS ${EXAMPLE_NAME} DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples) + if(SKBUILD) + install(TARGETS ${EXAMPLE_NAME} DESTINATION nanovdb/${CMAKE_INSTALL_DOCDIR}/examples) + else() + install(TARGETS ${EXAMPLE_NAME} DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples) + endif() endfunction() # ----------------------------------------------------------------------- diff --git a/nanovdb/nanovdb/python/CMakeLists.txt b/nanovdb/nanovdb/python/CMakeLists.txt index 558c58a828..41e0e696c4 100644 --- a/nanovdb/nanovdb/python/CMakeLists.txt +++ b/nanovdb/nanovdb/python/CMakeLists.txt @@ -27,7 +27,13 @@ target_include_directories(nanovdb_python PRIVATE ${CUDA_INCLUDE_DIRECTORY}) target_link_libraries(nanovdb_python PRIVATE nanovdb ${CUDA_LIBRARIES} ${NANOVDB_BLOSC} ${NANOVDB_ZLIB} ${NANOVDB_OPENVDB} ${NANOVDB_TBB}) target_compile_definitions(nanovdb_python PRIVATE ${NANOVDB_USE_CUDA_FLAG} ${NANOVDB_USE_BLOSC_FLAG} ${NANOVDB_USE_ZLIB_FLAG} ${NANOVDB_USE_OPENVDB_FLAG} ${NANOVDB_USE_TBB_FLAG}) set_target_properties(nanovdb_python PROPERTIES OUTPUT_NAME "nanovdb") -install(TARGETS nanovdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) +if(SKBUILD) + set_target_properties(nanovdb_python PROPERTIES INSTALL_RPATH "$ORIGIN/../../openvdb/lib") + install(TARGETS nanovdb_python DESTINATION nanovdb/${CMAKE_INSTALL_LIBDIR}) + install(FILES __init__.py DESTINATION nanovdb) +else() + install(TARGETS nanovdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) +endif() # pytest if(NANOVDB_BUILD_PYTHON_UNITTESTS) diff --git a/nanovdb/nanovdb/python/__init__.py b/nanovdb/nanovdb/python/__init__.py new file mode 100644 index 0000000000..7bce6a9559 --- /dev/null +++ b/nanovdb/nanovdb/python/__init__.py @@ -0,0 +1,7 @@ +import sys +if sys.platform == "win32": + import os + openvdb_dll_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, 'openvdb', 'lib') + os.add_dll_directory(directory) + +from .lib.nanovdb import * diff --git a/openvdb/openvdb/CMakeLists.txt b/openvdb/openvdb/CMakeLists.txt index a0d7868192..2646ff8ed6 100644 --- a/openvdb/openvdb/CMakeLists.txt +++ b/openvdb/openvdb/CMakeLists.txt @@ -718,29 +718,58 @@ endif() # Installation -if(OPENVDB_CORE_STATIC) - install(TARGETS openvdb_static - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -endif() +if(SKBUILD) + if(OPENVDB_CORE_STATIC) + install(TARGETS openvdb_static + RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ) + endif() -if(OPENVDB_CORE_SHARED) - install(TARGETS openvdb_shared - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -endif() + if(OPENVDB_CORE_SHARED) + install(TARGETS openvdb_shared + RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ) + endif() + + install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb) + install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/io) + install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/math) + install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points) + install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points/impl) + install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tools) + install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tree) + install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/util) + install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/thread) +else() + if(OPENVDB_CORE_STATIC) + install(TARGETS openvdb_static + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() -install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) -install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/io) -install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/math) -install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points) -install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points/impl) -install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tools) -install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tree) -install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/util) -install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/thread) + if(OPENVDB_CORE_SHARED) + install(TARGETS openvdb_shared + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() + + install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) + install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/io) + install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/math) + install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points) + install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points/impl) + install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tools) + install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tree) + install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/util) + install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/thread) +endif() diff --git a/openvdb/openvdb/python/CMakeLists.txt b/openvdb/openvdb/python/CMakeLists.txt index f54ff3ac55..9424e9bdda 100644 --- a/openvdb/openvdb/python/CMakeLists.txt +++ b/openvdb/openvdb/python/CMakeLists.txt @@ -74,8 +74,13 @@ if(USE_AX) target_compile_definitions(openvdb_python PUBLIC "-DPY_OPENVDB_USE_AX") endif() set_target_properties(openvdb_python PROPERTIES OUTPUT_NAME "openvdb") - -install(TARGETS openvdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) +if(SKBUILD) + set_target_properties(openvdb_python PROPERTIES INSTALL_RPATH "$ORIGIN") + install(TARGETS openvdb_python DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR}) + install(FILES __init__.py DESTINATION openvdb) +else() + install(TARGETS openvdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) +endif() # pytest if(OPENVDB_BUILD_PYTHON_UNITTESTS) diff --git a/openvdb/openvdb/python/__init__.py b/openvdb/openvdb/python/__init__.py new file mode 100644 index 0000000000..1b25ddfcc5 --- /dev/null +++ b/openvdb/openvdb/python/__init__.py @@ -0,0 +1 @@ +from .lib.openvdb import * diff --git a/openvdb_ax/openvdb_ax/CMakeLists.txt b/openvdb_ax/openvdb_ax/CMakeLists.txt index 14c0f21ac0..5a745e6662 100644 --- a/openvdb_ax/openvdb_ax/CMakeLists.txt +++ b/openvdb_ax/openvdb_ax/CMakeLists.txt @@ -354,23 +354,46 @@ if(OPENVDB_AX_SHARED) endif() endif() -install(FILES ax.h Exceptions.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/) -install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/ast) -install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) -install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) +if(SKBUILD) + install(FILES ax.h Exceptions.h DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/) + install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/ast) + install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) + install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) + + if(OPENVDB_AX_STATIC) + install(TARGETS openvdb_ax_static + RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ) + endif() -if(OPENVDB_AX_STATIC) - install(TARGETS openvdb_ax_static - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -endif() + if(OPENVDB_AX_SHARED) + install(TARGETS openvdb_ax_shared + RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} + ) + endif() +else() + install(FILES ax.h Exceptions.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/) + install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/ast) + install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) + install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) + + if(OPENVDB_AX_STATIC) + install(TARGETS openvdb_ax_static + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() -if(OPENVDB_AX_SHARED) - install(TARGETS openvdb_ax_shared - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) + if(OPENVDB_AX_SHARED) + install(TARGETS openvdb_ax_shared + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() endif() diff --git a/openvdb_cmd/CMakeLists.txt b/openvdb_cmd/CMakeLists.txt index 02c02e2641..eb0e83fd66 100644 --- a/openvdb_cmd/CMakeLists.txt +++ b/openvdb_cmd/CMakeLists.txt @@ -59,6 +59,12 @@ endif() ########################################################################## +if(SKBUILD) + set(OPENVDB_INSTALL_BINDIR openvdb/${CMAKE_INSTALL_BINDIR}) +else() + set(OPENVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}) +endif() + if (OPENVDB_BUILD_VDB_PRINT) add_subdirectory(vdb_print) endif() diff --git a/openvdb_cmd/vdb_ax/CMakeLists.txt b/openvdb_cmd/vdb_ax/CMakeLists.txt index ee5875fe90..2370d9d902 100644 --- a/openvdb_cmd/vdb_ax/CMakeLists.txt +++ b/openvdb_cmd/vdb_ax/CMakeLists.txt @@ -34,4 +34,4 @@ set(SOURCE_FILES main.cc) add_executable(vdb_ax ${SOURCE_FILES}) target_link_libraries(vdb_ax ${OPENVDB_BINARIES_DEPENDENT_LIBS}) -install(TARGETS vdb_ax RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_ax RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) diff --git a/openvdb_cmd/vdb_lod/CMakeLists.txt b/openvdb_cmd/vdb_lod/CMakeLists.txt index 37cede195f..a4348603ad 100644 --- a/openvdb_cmd/vdb_lod/CMakeLists.txt +++ b/openvdb_cmd/vdb_lod/CMakeLists.txt @@ -16,4 +16,4 @@ set(SOURCE_FILES main.cc) add_executable(vdb_lod ${SOURCE_FILES}) target_link_libraries(vdb_lod ${OPENVDB_BINARIES_DEPENDENT_LIBS}) -install(TARGETS vdb_lod RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_lod RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) diff --git a/openvdb_cmd/vdb_print/CMakeLists.txt b/openvdb_cmd/vdb_print/CMakeLists.txt index 3a3c73629f..25f00390c5 100644 --- a/openvdb_cmd/vdb_print/CMakeLists.txt +++ b/openvdb_cmd/vdb_print/CMakeLists.txt @@ -16,4 +16,4 @@ set(SOURCE_FILES main.cc) add_executable(vdb_print ${SOURCE_FILES}) target_link_libraries(vdb_print ${OPENVDB_BINARIES_DEPENDENT_LIBS}) -install(TARGETS vdb_print RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_print RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) diff --git a/openvdb_cmd/vdb_render/CMakeLists.txt b/openvdb_cmd/vdb_render/CMakeLists.txt index fcb534c250..f19134b2f1 100644 --- a/openvdb_cmd/vdb_render/CMakeLists.txt +++ b/openvdb_cmd/vdb_render/CMakeLists.txt @@ -51,4 +51,4 @@ target_link_libraries(vdb_render $ ) -install(TARGETS vdb_render RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_render RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index f9b846b8aa..6d01701f87 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -166,7 +166,7 @@ target_include_directories(vdb_tool_common INTERFACE "${Boost_INCLUDE_DIRS}" "${ add_executable(vdb_tool src/main.cpp) target_include_directories(vdb_tool PRIVATE vdb_tool_common) target_link_libraries(vdb_tool PRIVATE vdb_tool_common) -install(TARGETS vdb_tool RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_tool RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) # unit test diff --git a/openvdb_cmd/vdb_view/CMakeLists.txt b/openvdb_cmd/vdb_view/CMakeLists.txt index d543112a9c..e7bf546c5e 100644 --- a/openvdb_cmd/vdb_view/CMakeLists.txt +++ b/openvdb_cmd/vdb_view/CMakeLists.txt @@ -45,4 +45,4 @@ endif() target_compile_definitions(vdb_view PRIVATE -DGL_GLEXT_PROTOTYPES=1) -install(TARGETS vdb_view RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS vdb_view RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..919b2a813c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,46 @@ +[build-system] +requires = ["scikit_build_core", "nanobind"] +build-backend = "scikit_build_core.build" + +[project] +name = "openvdb" +version = "11.0.1" +description= "Python bindings for OpenVDB: sparse volume data structure and tools." +dependencies = [ + "numpy", +] +authors = [ + { name = "OpenVDB Developer Team", email = "openvdb-dev@lists.aswf.io" }, +] +requires-python = ">=3.8" +classifiers = [ + "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] + +[project.urls] +homepage = "https://www.openvdb.org/" +documentation = "https://www.openvdb.org/documentation" +forum = "https://github.com/AcademySoftwareFoundation/openvdb/discussions" +repository = "https://github.com/AcademySoftwareFoundation/openvdb" +slack = "https://slack.aswf.io/" + +[tool.scikit-build] +wheel.packages = [] + +[tool.scikit-build.cmake.define] +OPENVDB_CORE_STATIC="OFF" +USE_EXPLICIT_INSTANTIATION="OFF" +DISABLE_DEPENDENCY_VERSION_CHECKS="ON" +OPENVDB_USE_DELAYED_LOADING="OFF" +OPENVDB_BUILD_PYTHON_MODULE="ON" +USE_NUMPY="ON" + +USE_NANOVDB="ON" +NANOVDB_USE_CUDA="ON" +NANOVDB_BUILD_PYTHON_MODULE="ON" +NANOVDB_USE_OPENVDB="ON" + From 40d1089000397468630d78996b19749dd2bca1d9 Mon Sep 17 00:00:00 2001 From: Matthew Cong Date: Wed, 23 Oct 2024 08:30:48 -0700 Subject: [PATCH 47/98] Update classifier Signed-off-by: Matthew Cong --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 919b2a813c..33f87d4a35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ authors = [ ] requires-python = ">=3.8" classifiers = [ - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", + "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", From 18ad2107582a344f8e95b5e21b58b2e561974f29 Mon Sep 17 00:00:00 2001 From: Matthew Cong Date: Tue, 29 Oct 2024 14:37:29 -0700 Subject: [PATCH 48/98] Consolidate SKBUILD logic Signed-off-by: Matthew Cong --- CMakeLists.txt | 30 ++++++++-- nanovdb/nanovdb/CMakeLists.txt | 18 +++--- nanovdb/nanovdb/cmd/CMakeLists.txt | 6 -- nanovdb/nanovdb/examples/CMakeLists.txt | 6 +- nanovdb/nanovdb/python/CMakeLists.txt | 2 +- openvdb/openvdb/CMakeLists.txt | 77 ++++++++----------------- openvdb/openvdb/python/CMakeLists.txt | 2 +- openvdb_ax/openvdb_ax/CMakeLists.txt | 57 ++++++------------ openvdb_cmd/CMakeLists.txt | 6 -- 9 files changed, 76 insertions(+), 128 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a17943004..c8d061bc73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,6 +285,30 @@ 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 @@ -298,11 +322,7 @@ if(OPENVDB_INSTALL_CMAKE_MODULES) cmake/OpenVDBMayaSetup.cmake cmake/OpenVDBUtils.cmake ) - if(SKBUILD) - install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR}/cmake/OpenVDB) - else() - install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenVDB) - endif() + install(FILES ${OPENVDB_CMAKE_MODULES} DESTINATION ${OPENVDB_INSTALL_LIBDIR}/cmake/OpenVDB) endif() # Configure component dependencies by loading the Houdini/Maya setup diff --git a/nanovdb/nanovdb/CMakeLists.txt b/nanovdb/nanovdb/CMakeLists.txt index 7392fc7839..1c50d2eade 100644 --- a/nanovdb/nanovdb/CMakeLists.txt +++ b/nanovdb/nanovdb/CMakeLists.txt @@ -322,20 +322,16 @@ if(TARGET Threads::Threads) target_link_libraries(nanovdb INTERFACE Threads::Threads) endif() -if(SKBUILD) - set(NANOVDB_INSTALL_INCLUDE_DIR nanovdb/${CMAKE_INSTALL_INCLUDEDIR}/nanovdb) -else() - set(NANOVDB_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/nanovdb) -endif() -set(NANOVDB_INSTALL_CUDA_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/cuda) -set(NANOVDB_INSTALL_IO_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/io) -set(NANOVDB_INSTALL_MATH_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/math) -set(NANOVDB_INSTALL_TOOLS_DIR ${NANOVDB_INSTALL_INCLUDE_DIR}/tools) +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_INCLUDE_DIR}/util) +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_INCLUDE_DIR}) +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}) diff --git a/nanovdb/nanovdb/cmd/CMakeLists.txt b/nanovdb/nanovdb/cmd/CMakeLists.txt index bad16c075a..6513b14d2a 100644 --- a/nanovdb/nanovdb/cmd/CMakeLists.txt +++ b/nanovdb/nanovdb/cmd/CMakeLists.txt @@ -27,12 +27,6 @@ endif() # ----------------------------------------------------------------------------- -if(SKBUILD) - set(NANOVDB_INSTALL_BINDIR nanovdb/${CMAKE_INSTALL_BINDIR}) -else() - set(NANOVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}) -endif() - if(NOT NANOVDB_USE_OPENVDB) message(WARNING " - OpenVDB required to build nanovdb_convert. Skipping.") else() diff --git a/nanovdb/nanovdb/examples/CMakeLists.txt b/nanovdb/nanovdb/examples/CMakeLists.txt index da4cf64180..cfbc33de0c 100644 --- a/nanovdb/nanovdb/examples/CMakeLists.txt +++ b/nanovdb/nanovdb/examples/CMakeLists.txt @@ -78,11 +78,7 @@ function(NANOVDB_EXAMPLE) target_include_directories(${EXAMPLE_NAME} PUBLIC ex_util) target_link_libraries(${EXAMPLE_NAME} PRIVATE nanovdb) - if(SKBUILD) - install(TARGETS ${EXAMPLE_NAME} DESTINATION nanovdb/${CMAKE_INSTALL_DOCDIR}/examples) - else() - install(TARGETS ${EXAMPLE_NAME} DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples) - endif() + install(TARGETS ${EXAMPLE_NAME} DESTINATION ${NANOVDB_INSTALL_DOCDIR}/examples) endfunction() # ----------------------------------------------------------------------- diff --git a/nanovdb/nanovdb/python/CMakeLists.txt b/nanovdb/nanovdb/python/CMakeLists.txt index 41e0e696c4..d5c50792ee 100644 --- a/nanovdb/nanovdb/python/CMakeLists.txt +++ b/nanovdb/nanovdb/python/CMakeLists.txt @@ -29,7 +29,7 @@ target_compile_definitions(nanovdb_python PRIVATE ${NANOVDB_USE_CUDA_FLAG} ${NAN set_target_properties(nanovdb_python PROPERTIES OUTPUT_NAME "nanovdb") if(SKBUILD) set_target_properties(nanovdb_python PROPERTIES INSTALL_RPATH "$ORIGIN/../../openvdb/lib") - install(TARGETS nanovdb_python DESTINATION nanovdb/${CMAKE_INSTALL_LIBDIR}) + install(TARGETS nanovdb_python DESTINATION ${NANOVDB_INSTALL_LIBDIR}) install(FILES __init__.py DESTINATION nanovdb) else() install(TARGETS nanovdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) diff --git a/openvdb/openvdb/CMakeLists.txt b/openvdb/openvdb/CMakeLists.txt index 2646ff8ed6..2ea9974698 100644 --- a/openvdb/openvdb/CMakeLists.txt +++ b/openvdb/openvdb/CMakeLists.txt @@ -718,58 +718,29 @@ endif() # Installation -if(SKBUILD) - if(OPENVDB_CORE_STATIC) - install(TARGETS openvdb_static - RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ) - endif() - - if(OPENVDB_CORE_SHARED) - install(TARGETS openvdb_shared - RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ) - endif() - - install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb) - install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/io) - install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/math) - install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points) - install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points/impl) - install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tools) - install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tree) - install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/util) - install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb/thread) -else() - if(OPENVDB_CORE_STATIC) - install(TARGETS openvdb_static - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - endif() - - if(OPENVDB_CORE_SHARED) - install(TARGETS openvdb_shared - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - endif() +if(OPENVDB_CORE_STATIC) + install(TARGETS openvdb_static + RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR} + LIBRARY DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ) +endif() - install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb) - install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/io) - install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/math) - install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points) - install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/points/impl) - install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tools) - install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/tree) - install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/util) - install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/thread) +if(OPENVDB_CORE_SHARED) + install(TARGETS openvdb_shared + RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR} + LIBRARY DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ) endif() + +install(FILES ${OPENVDB_LIBRARY_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openvdb/version.h DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb) +install(FILES ${OPENVDB_LIBRARY_IO_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/io) +install(FILES ${OPENVDB_LIBRARY_MATH_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/math) +install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/points) +install(FILES ${OPENVDB_LIBRARY_POINTS_IMPL_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/points/impl) +install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/tools) +install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/tree) +install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/util) +install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb/thread) diff --git a/openvdb/openvdb/python/CMakeLists.txt b/openvdb/openvdb/python/CMakeLists.txt index 9424e9bdda..cfdd4727bf 100644 --- a/openvdb/openvdb/python/CMakeLists.txt +++ b/openvdb/openvdb/python/CMakeLists.txt @@ -76,7 +76,7 @@ endif() set_target_properties(openvdb_python PROPERTIES OUTPUT_NAME "openvdb") if(SKBUILD) set_target_properties(openvdb_python PROPERTIES INSTALL_RPATH "$ORIGIN") - install(TARGETS openvdb_python DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR}) + install(TARGETS openvdb_python DESTINATION ${OPENVDB_INSTALL_LIBDIR}) install(FILES __init__.py DESTINATION openvdb) else() install(TARGETS openvdb_python DESTINATION ${VDB_PYTHON_INSTALL_DIRECTORY}) diff --git a/openvdb_ax/openvdb_ax/CMakeLists.txt b/openvdb_ax/openvdb_ax/CMakeLists.txt index 5a745e6662..9bde5bb921 100644 --- a/openvdb_ax/openvdb_ax/CMakeLists.txt +++ b/openvdb_ax/openvdb_ax/CMakeLists.txt @@ -354,46 +354,23 @@ if(OPENVDB_AX_SHARED) endif() endif() -if(SKBUILD) - install(FILES ax.h Exceptions.h DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/) - install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/ast) - install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) - install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION openvdb/${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) - - if(OPENVDB_AX_STATIC) - install(TARGETS openvdb_ax_static - RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ) - endif() +install(FILES ax.h Exceptions.h DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb_ax/) +install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb_ax/ast) +install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) +install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) - if(OPENVDB_AX_SHARED) - install(TARGETS openvdb_ax_shared - RUNTIME DESTINATION openvdb/${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION openvdb/${CMAKE_INSTALL_LIBDIR} - ) - endif() -else() - install(FILES ax.h Exceptions.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/) - install(FILES ${OPENVDB_AX_AST_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/ast) - install(FILES ${OPENVDB_AX_CODEGEN_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/codegen) - install(FILES ${OPENVDB_AX_COMPILER_INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb_ax/compiler) - - if(OPENVDB_AX_STATIC) - install(TARGETS openvdb_ax_static - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - endif() +if(OPENVDB_AX_STATIC) + install(TARGETS openvdb_ax_static + RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR} + LIBRARY DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ) +endif() - if(OPENVDB_AX_SHARED) - install(TARGETS openvdb_ax_shared - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - endif() +if(OPENVDB_AX_SHARED) + install(TARGETS openvdb_ax_shared + RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR} + LIBRARY DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${OPENVDB_INSTALL_LIBDIR} + ) endif() diff --git a/openvdb_cmd/CMakeLists.txt b/openvdb_cmd/CMakeLists.txt index eb0e83fd66..02c02e2641 100644 --- a/openvdb_cmd/CMakeLists.txt +++ b/openvdb_cmd/CMakeLists.txt @@ -59,12 +59,6 @@ endif() ########################################################################## -if(SKBUILD) - set(OPENVDB_INSTALL_BINDIR openvdb/${CMAKE_INSTALL_BINDIR}) -else() - set(OPENVDB_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}) -endif() - if (OPENVDB_BUILD_VDB_PRINT) add_subdirectory(vdb_print) endif() From da8b764aa92b647361491589bbaf06e21e1f4586 Mon Sep 17 00:00:00 2001 From: apradhana Date: Mon, 28 Oct 2024 09:18:24 -0700 Subject: [PATCH 49/98] Add a unit test for LevelSetFilter::fillet. Signed-off-by: apradhana --- openvdb/openvdb/tools/LevelSetFilter.h | 22 ++--- openvdb/openvdb/unittest/CMakeLists.txt | 1 + .../openvdb/unittest/TestLevelSetFilter.cc | 80 +++++++++++++++++++ pendingchanges/levelset_fillet.txt | 2 + 4 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 openvdb/openvdb/unittest/TestLevelSetFilter.cc create mode 100644 pendingchanges/levelset_fillet.txt diff --git a/openvdb/openvdb/tools/LevelSetFilter.h b/openvdb/openvdb/tools/LevelSetFilter.h index 0ce7dcd6f7..bc1a425815 100644 --- a/openvdb/openvdb/tools/LevelSetFilter.h +++ b/openvdb/openvdb/tools/LevelSetFilter.h @@ -98,11 +98,15 @@ class LevelSetFilter : public LevelSetTracker /// @brief One iteration of filleting on the level set. /// @param mask Optional alpha mask. /// - /// @note This filter rounds off concave edges to create a smoother transition between surfaces - /// Fillets a level set by - /// offsetting at locations with a negative principal curvature, proportional to its magnitude - /// leaves locations with non-negative principal curvatures untouched - /// This filter converges to the convex hull if iterated enough times + /// @note This filter rounds off concave edges to create a smoother + /// transition between surfaces. Fillets a level set by offsetting + /// at locations with a negative principal curvature, proportional + /// to its magnitude leaves locations with non-negative principal + /// curvatures untouched. This filter converges to the convex hull + /// if iterated enough times. + /// + /// @details See also Level Set Methods and Fast Marching Methods + /// by James Sethian, pp. 204. void fillet(const MaskType* mask = nullptr) { Filter f(this, mask); f.fillet(); @@ -409,10 +413,10 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa } } -/// Fillets a level set by -/// offsetting at locations with a negative principal curvature, proportional to its magnitude -/// leaves locations with non-negative principal curvatures untouched -/// This filter converges to the convex hull if iterated enough times +/// Fillets a level set by offsetting at locations with a negative principal +/// curvature, proportional to its magnitude. Leaves locations with non-negative +/// principal curvatures untouched. This filter converges to the convex hull if +/// iterated enough times. template inline void LevelSetFilter::Filter::filletImpl(const LeafRange& range) diff --git a/openvdb/openvdb/unittest/CMakeLists.txt b/openvdb/openvdb/unittest/CMakeLists.txt index f9665a0784..3339c97195 100644 --- a/openvdb/openvdb/unittest/CMakeLists.txt +++ b/openvdb/openvdb/unittest/CMakeLists.txt @@ -119,6 +119,7 @@ else() TestLeafManager.cc TestLeafMask.cc TestLeafOrigin.cc + TestLevelSetFilter.cc TestLevelSetRayIntersector.cc TestLevelSetUtil.cc TestLinearInterp.cc diff --git a/openvdb/openvdb/unittest/TestLevelSetFilter.cc b/openvdb/openvdb/unittest/TestLevelSetFilter.cc new file mode 100644 index 0000000000..12fc472f01 --- /dev/null +++ b/openvdb/openvdb/unittest/TestLevelSetFilter.cc @@ -0,0 +1,80 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include // for csgUnion() + +#include + +using namespace openvdb; + +class TestLevelSetFilter: public ::testing::Test +{ +public: + void SetUp() override { openvdb::initialize(); } + void TearDown() override { openvdb::uninitialize(); } + + void testLevelSetFillet(); +}; // class TestLevelSetFilter + + +//////////////////////////////////////// + + +TEST_F(TestLevelSetFilter, testLevelSetFillet) +{ + using GridT = FloatGrid; + using FilterT = tools::LevelSetFilter; + + const float radius = 5.0f; + const float voxelSize = 1.0f; + const float halfWidth = 3.0f; + typename GridT::Ptr sdfGrid = tools::createLevelSetSphere(/*radius=*/radius, + /*center=*/Vec3f(-radius, 0.0f, 0.0f), + /*dx=*/voxelSize, /*halfWidth*/ halfWidth); + typename GridT::Ptr sdfGridB = tools::createLevelSetSphere(/*radius=*/radius, + /*center=*/Vec3f(radius, 0.0f, 0.0f), + /*dx=*/voxelSize, /*halfWidth*/ halfWidth); + typename GridT::Accessor acc = sdfGrid->getAccessor(); + + EXPECT_TRUE(sdfGrid); + EXPECT_TRUE(sdfGridB); + + tools::csgUnion(*sdfGrid, *sdfGridB); + + { + EXPECT_TRUE(sdfGrid); + + Coord ijk(0, 3, 0); + + // We expect that the intersection between the two spheres are at (0, 0, 0) + // so the SDF value of the union in these offsets locations should be > 0 + EXPECT_TRUE(acc.getValue(ijk) > 0.f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0, 0, 1)) > 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0, 0,-1)) > 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1, 0)) > 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1, 1)) > 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1,-1)) > 0.0f); + } + + FilterT filter(*sdfGrid); + filter.fillet(); + + { + EXPECT_TRUE(sdfGrid); + + Coord ijk(0, 3, 0); + + // After the fillet operation, we expect that the zero-isocontour is + // pushed outward. + EXPECT_TRUE(acc.getValue(ijk) < 0.f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0, 0, 1)) < 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0, 0,-1)) < 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1, 0)) < 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1, 1)) < 0.0f); + EXPECT_TRUE(acc.getValue(ijk.offsetBy(0,-1,-1)) < 0.0f); + } +} diff --git a/pendingchanges/levelset_fillet.txt b/pendingchanges/levelset_fillet.txt new file mode 100644 index 0000000000..ca96a9f009 --- /dev/null +++ b/pendingchanges/levelset_fillet.txt @@ -0,0 +1,2 @@ +New Feature: +- Added fillet() method in tools::LevelSetFilter to round off concave edges to create smoother transition between surfaces. [Contributed by Greg Hurst] \ No newline at end of file From 844c79b38a931c121178bd7d38d0497b2276f2d9 Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Wed, 30 Oct 2024 12:29:42 +1300 Subject: [PATCH 50/98] Added PDAL read test to vdb_tool unittests Signed-off-by: Jonathan Swartz --- openvdb_cmd/vdb_tool/src/unittest.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openvdb_cmd/vdb_tool/src/unittest.cpp b/openvdb_cmd/vdb_tool/src/unittest.cpp index 16a6ef557c..738b4fd4ca 100644 --- a/openvdb_cmd/vdb_tool/src/unittest.cpp +++ b/openvdb_cmd/vdb_tool/src/unittest.cpp @@ -408,6 +408,30 @@ TEST_F(Test_vdb_tool, Geometry) EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo.quad()[0]); } + #ifdef VDB_TOOL_USE_PDAL + {// read from PDAL-supported ASCII format file + // (NOTE: PDAL also supports other formats e.g. LAS, LAZ, E57, Draco, FBX, NumPy, OBJ,…) + + // write a test file + std::ofstream os("data/test.txt"); + os << "X,Y,Z\n"; + for (size_t i=0; i Date: Wed, 30 Oct 2024 12:35:13 +1300 Subject: [PATCH 51/98] Fix whitespace issue Signed-off-by: Jonathan Swartz --- openvdb_cmd/vdb_tool/src/unittest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb_cmd/vdb_tool/src/unittest.cpp b/openvdb_cmd/vdb_tool/src/unittest.cpp index 738b4fd4ca..71fc4c9ade 100644 --- a/openvdb_cmd/vdb_tool/src/unittest.cpp +++ b/openvdb_cmd/vdb_tool/src/unittest.cpp @@ -409,7 +409,7 @@ TEST_F(Test_vdb_tool, Geometry) EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo.quad()[0]); } #ifdef VDB_TOOL_USE_PDAL - {// read from PDAL-supported ASCII format file + {// read from PDAL-supported ASCII format file // (NOTE: PDAL also supports other formats e.g. LAS, LAZ, E57, Draco, FBX, NumPy, OBJ,…) // write a test file From 986dfb959dc5525fac191406eb000b4f86f42736 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 29 Oct 2024 16:36:54 -0700 Subject: [PATCH 52/98] Fix a memory-leak in RootNode::deleteChildOrTile() and add an iterator warning Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index f135db1bb8..cf7892b883 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -712,6 +712,7 @@ class RootNode /// @brief Delete any child or tile containing voxel (x, y, z) at the root level. /// Do nothing if no child or tile was found. + /// @warning This method will invalidate any existing RootNode iterators. /// @return @c true if child or tile was deleted bool deleteChildOrTile(const Coord& xyz); @@ -2777,7 +2778,14 @@ inline bool RootNode::deleteChildOrTile(const Coord& xyz) { Coord key = this->coordToKey(xyz); - return mTable.erase(key) == size_t(1); + MapIter iter = this->findKey(key); + if (iter != mTable.end()) { + // the child must be deleted to prevent a memory leak + if (isChild(iter)) delete iter->second.child; + mTable.erase(iter); + return true; + } + return false; } From 3813556aa7f47ac25ef02c97ad5984c72e6616e1 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Tue, 29 Oct 2024 22:41:01 -0400 Subject: [PATCH 53/98] More 64 bit return for TreeBase * nonLeafCount and treeDepth return Index64 in TreeBase. * All ABI breakages safeguarded for versions < 12. * Deprecated implementations of nodeCount for vector arguments. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/python/pyGrid.h | 4 +- openvdb/openvdb/tree/InternalNode.h | 24 ++++++++++-- openvdb/openvdb/tree/LeafNode.h | 7 +++- openvdb/openvdb/tree/LeafNodeBool.h | 7 +++- openvdb/openvdb/tree/LeafNodeMask.h | 7 +++- openvdb/openvdb/tree/RootNode.h | 28 ++++++++++++-- openvdb/openvdb/tree/Tree.h | 26 +++++++++++-- openvdb/openvdb/unittest/TestGrid.cc | 4 +- openvdb/openvdb/unittest/TestLeaf.cc | 2 +- openvdb/openvdb/unittest/TestNodeIterator.cc | 8 ++-- openvdb/openvdb/unittest/TestNodeManager.cc | 2 +- openvdb/openvdb/unittest/TestNodeVisitor.cc | 2 +- openvdb/openvdb/unittest/TestTools.cc | 10 ++--- openvdb/openvdb/unittest/TestTree.cc | 10 ++--- .../openvdb/unittest/TestTreeGetSetValues.cc | 38 +++++++++---------- openvdb/openvdb/unittest/TestValueAccessor.cc | 8 ++-- 16 files changed, 131 insertions(+), 56 deletions(-) diff --git a/openvdb/openvdb/python/pyGrid.h b/openvdb/openvdb/python/pyGrid.h index c6fe8ab1d9..9778d364c2 100644 --- a/openvdb/openvdb/python/pyGrid.h +++ b/openvdb/openvdb/python/pyGrid.h @@ -205,7 +205,7 @@ getNodeLog2Dims(const GridType& grid) template -inline Index +inline Index64 treeDepth(const GridType& grid) { return grid.tree().treeDepth(); @@ -221,7 +221,7 @@ leafCount(const GridType& grid) template -inline Index32 +inline Index64 nonLeafCount(const GridType& grid) { return grid.tree().nonLeafCount(); diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 08ccc7cc68..bcf41449aa 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -276,7 +276,11 @@ class InternalNode Index64 leafCount() const; void nodeCount(std::vector &vec) const; - Index32 nonLeafCount() const; +#if OPENVDB_ABI_VERSION_NUMBER < 12 + OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") + void nodeCount(std::vector &vec) const; +#endif + Index64 nonLeafCount() const; Index32 childCount() const; Index64 onVoxelCount() const; Index64 offVoxelCount() const; @@ -1011,12 +1015,26 @@ InternalNode::nodeCount(std::vector &vec) const vec[ChildNodeType::LEVEL] += count; } +#if OPENVDB_ABI_VERSION_NUMBER < 12 +template +inline void +InternalNode::nodeCount(std::vector &vec) const +{ + OPENVDB_ASSERT(vec.size() > ChildNodeType::LEVEL); + const auto count = mChildMask.countOn(); + if (ChildNodeType::LEVEL > 0 && count > 0) { + for (auto iter = this->cbeginChildOn(); iter; ++iter) iter->nodeCount(vec); + } + vec[ChildNodeType::LEVEL] += count; +} +#endif + template -inline Index32 +inline Index64 InternalNode::nonLeafCount() const { - Index32 sum = 1; + Index64 sum = 1; if (ChildNodeType::getLevel() == 0) return sum; for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { sum += iter->nonLeafCount(); diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 89d04e9f23..6aee009f2a 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -132,8 +132,13 @@ class LeafNode static Index64 leafCount() { return 1; } /// no-op void nodeCount(std::vector &) const {} +#if OPENVDB_ABI_VERSION_NUMBER < 12 + /// no-op + OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") + void nodeCount(std::vector &) const {} +#endif /// Return the non-leaf count for this node, which is zero. - static Index32 nonLeafCount() { return 0; } + static Index64 nonLeafCount() { return 0; } /// Return the child count for this node, which is zero. static Index32 childCount() { return 0; } diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index cf990f846b..9c38b6f748 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -134,7 +134,12 @@ class LeafNode static Index64 leafCount() { return 1; } /// no-op void nodeCount(std::vector &) const {} - static Index32 nonLeafCount() { return 0; } +#if OPENVDB_ABI_VERSION_NUMBER < 12 + /// no-op + OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") + void nodeCount(std::vector &) const {} +#endif + static Index64 nonLeafCount() { return 0; } /// Return the number of active voxels. Index64 onVoxelCount() const { return mValueMask.countOn(); } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index df28099cc5..dd47f25b3f 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -115,8 +115,13 @@ class LeafNode static Index64 leafCount() { return 1; } /// no-op void nodeCount(std::vector &) const {} +#if OPENVDB_ABI_VERSION_NUMBER < 12 + /// no-op + OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") + void nodeCount(std::vector &) const {} +#endif /// Return the non-leaf count for this node, which is zero. - static Index32 nonLeafCount() { return 0; } + static Index64 nonLeafCount() { return 0; } /// Return the number of active voxels. Index64 onVoxelCount() const { return mBuffer.mData.countOn(); } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index c534ae0c90..f7c7f62cba 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -484,7 +484,7 @@ class RootNode static bool hasCompatibleValueType(const RootNode& other); Index64 leafCount() const; - Index32 nonLeafCount() const; + Index64 nonLeafCount() const; Index32 childCount() const; Index64 onVoxelCount() const; Index64 offVoxelCount() const; @@ -492,6 +492,10 @@ class RootNode Index64 offLeafVoxelCount() const; Index64 onTileCount() const; void nodeCount(std::vector &vec) const; +#if OPENVDB_ABI_VERSION_NUMBER < 12 + OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") + void nodeCount(std::vector &vec) const; +#endif bool isValueOn(const Coord& xyz) const; @@ -1579,10 +1583,10 @@ RootNode::leafCount() const template -inline Index32 +inline Index64 RootNode::nonLeafCount() const { - Index32 sum = 1; + Index64 sum = 1; if (ChildT::LEVEL != 0) { for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { if (isChild(i)) sum += getChild(i).nonLeafCount(); @@ -1690,6 +1694,24 @@ RootNode::nodeCount(std::vector &vec) const vec[ChildNodeType::LEVEL] = sum; } +#if OPENVDB_ABI_VERSION_NUMBER < 12 +template +inline void +RootNode::nodeCount(std::vector &vec) const +{ + OPENVDB_ASSERT(vec.size() > LEVEL); + Index32 sum = 0; + for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { + if (isChild(i)) { + ++sum; + getChild(i).nodeCount(vec); + } + } + vec[LEVEL] = 1;// one root node + vec[ChildNodeType::LEVEL] = sum; +} +#endif + //////////////////////////////////////// diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index d7110c1f42..b8cd93ca3f 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -102,7 +102,11 @@ class OPENVDB_API TreeBase /// @sa readNonresidentBuffers, io::File::open virtual void clipUnallocatedNodes() = 0; /// Return the total number of unallocated leaf nodes residing in this tree. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 virtual Index64 unallocatedLeafCount() const = 0; +#else + virtual Index32 unallocatedLeafCount() const = 0; +#endif // @@ -111,15 +115,31 @@ class OPENVDB_API TreeBase /// @brief Return the depth of this tree. /// /// A tree with only a root node and leaf nodes has depth 2, for example. - virtual Index treeDepth() const = 0; +#if OPENVDB_ABI_VERSION_NUMBER >= 12 + virtual Index64 treeDepth() const = 0; +#else + virtual Index32 treeDepth() const = 0; +#endif /// Return the number of leaf nodes. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 virtual Index64 leafCount() const = 0; +#else + virtual Index32 leafCount() const = 0; +#endif /// Return a vector with node counts. The number of nodes of type NodeType /// is given as element NodeType::LEVEL in the return vector. Thus, the size /// of this vector corresponds to the height (or depth) of this tree. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 virtual std::vector nodeCount() const = 0; +#else + virtual std::vector nodeCount() const = 0; +#endif /// Return the number of non-leaf nodes. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 + virtual Index64 nonLeafCount() const = 0; +#else virtual Index32 nonLeafCount() const = 0; +#endif /// Return the number of active voxels stored in leaf nodes. virtual Index64 activeLeafVoxelCount() const = 0; /// Return the number of inactive voxels stored in leaf nodes. @@ -341,7 +361,7 @@ class Tree: public TreeBase /// @brief Return the depth of this tree. /// /// A tree with only a root node and leaf nodes has depth 2, for example. - Index treeDepth() const override { return DEPTH; } + Index64 treeDepth() const override { return Index64(DEPTH); } /// Return the number of leaf nodes. Index64 leafCount() const override { return mRoot.leafCount(); } /// Return a vector with node counts. The number of nodes of type NodeType @@ -354,7 +374,7 @@ class Tree: public TreeBase return vec;// Named Return Value Optimization } /// Return the number of non-leaf nodes. - Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); } + Index64 nonLeafCount() const override { return mRoot.nonLeafCount(); } /// Return the number of active voxels stored in leaf nodes. Index64 activeLeafVoxelCount() const override { return tools::countActiveLeafVoxels(*this); } /// Return the number of inactive voxels stored in leaf nodes. diff --git a/openvdb/openvdb/unittest/TestGrid.cc b/openvdb/openvdb/unittest/TestGrid.cc index 66fa1082db..26e60199a2 100644 --- a/openvdb/openvdb/unittest/TestGrid.cc +++ b/openvdb/openvdb/unittest/TestGrid.cc @@ -87,11 +87,11 @@ class ProxyTree: public openvdb::TreeBase bool evalLeafDim(openvdb::Coord& dim) const override { dim = openvdb::Coord(0, 0, 0); return false; } - openvdb::Index treeDepth() const override { return 0; } + openvdb::Index64 treeDepth() const override { return 0; } openvdb::Index64 leafCount() const override { return 0; } std::vector nodeCount() const override { return std::vector(DEPTH, 0); } - openvdb::Index nonLeafCount() const override { return 0; } + openvdb::Index64 nonLeafCount() const override { return 0; } openvdb::Index64 activeVoxelCount() const override { return 0UL; } openvdb::Index64 inactiveVoxelCount() const override { return 0UL; } openvdb::Index64 activeLeafVoxelCount() const override { return 0UL; } diff --git a/openvdb/openvdb/unittest/TestLeaf.cc b/openvdb/openvdb/unittest/TestLeaf.cc index 3737386fe6..28ebb30e79 100644 --- a/openvdb/openvdb/unittest/TestLeaf.cc +++ b/openvdb/openvdb/unittest/TestLeaf.cc @@ -509,7 +509,7 @@ TEST_F(TestLeaf, testCount) EXPECT_EQ(Index(0), leaf.getLevel()); EXPECT_EQ(Index(1), leaf.getChildDim()); EXPECT_EQ(Index64(1), leaf.leafCount()); - EXPECT_EQ(Index(0), leaf.nonLeafCount()); + EXPECT_EQ(Index64(0), leaf.nonLeafCount()); EXPECT_EQ(Index(0), leaf.childCount()); std::vector dims; diff --git a/openvdb/openvdb/unittest/TestNodeIterator.cc b/openvdb/openvdb/unittest/TestNodeIterator.cc index a977e4200c..5f0562e388 100644 --- a/openvdb/openvdb/unittest/TestNodeIterator.cc +++ b/openvdb/openvdb/unittest/TestNodeIterator.cc @@ -58,7 +58,7 @@ TEST_F(TestNodeIterator, testSinglePositive) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); + EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -108,7 +108,7 @@ TEST_F(TestNodeIterator, testSinglePositive) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); + EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -163,7 +163,7 @@ TEST_F(TestNodeIterator, testSingleNegative) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); + EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -217,7 +217,7 @@ TEST_F(TestNodeIterator, testMultipleBlocks) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); + EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); // Descend to the depth-1 internal node with bounding box // (-256, -256, -256) -> (-1, -1, -1) containing voxel (-1, -1, -1). diff --git a/openvdb/openvdb/unittest/TestNodeManager.cc b/openvdb/openvdb/unittest/TestNodeManager.cc index 63073d6b18..6bd4759b3e 100644 --- a/openvdb/openvdb/unittest/TestNodeManager.cc +++ b/openvdb/openvdb/unittest/TestNodeManager.cc @@ -295,7 +295,7 @@ TEST_F(TestNodeManager, testDynamic) EXPECT_TRUE(sourceTree.root().addChild(child.release())); EXPECT_EQ(Index64(0), sourceTree.leafCount()); - EXPECT_EQ(Index32(2), sourceTree.nonLeafCount()); + EXPECT_EQ(Index64(2), sourceTree.nonLeafCount()); ExpandOp expandOp; diff --git a/openvdb/openvdb/unittest/TestNodeVisitor.cc b/openvdb/openvdb/unittest/TestNodeVisitor.cc index e4154544a8..5899b7c591 100644 --- a/openvdb/openvdb/unittest/TestNodeVisitor.cc +++ b/openvdb/openvdb/unittest/TestNodeVisitor.cc @@ -94,7 +94,7 @@ struct DescendOp } openvdb::Index32 previousLevel{0}; - openvdb::Index32 count{0}; + openvdb::Index64 count{0}; }; // struct DescendOp diff --git a/openvdb/openvdb/unittest/TestTools.cc b/openvdb/openvdb/unittest/TestTools.cc index bc5e1d8f70..a8e6247609 100644 --- a/openvdb/openvdb/unittest/TestTools.cc +++ b/openvdb/openvdb/unittest/TestTools.cc @@ -1708,7 +1708,7 @@ TEST_F(TestTools, testPrune) FloatTree tree(value); EXPECT_EQ(Index64(0), tree.leafCount()); - EXPECT_EQ(Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(Index64(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); tree.fill(CoordBBox(Coord(-10), Coord(10)), value, /*active=*/false); @@ -1717,7 +1717,7 @@ TEST_F(TestTools, testPrune) tools::prune(tree); EXPECT_EQ(Index64(0), tree.leafCount()); - EXPECT_EQ(Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(Index64(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); } @@ -1740,17 +1740,17 @@ TEST_F(TestTools, testPrune) tree.addLeaf(leaf); EXPECT_EQ(Index64(1), tree.leafCount()); - EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal + EXPECT_EQ(Index64(3), tree.nonLeafCount()); // root+2*internal tools::prune(tree);// tolerance is zero EXPECT_EQ(Index64(1), tree.leafCount()); - EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal + EXPECT_EQ(Index64(3), tree.nonLeafCount()); // root+2*internal tools::prune(tree, tol); EXPECT_EQ(Index64(0), tree.leafCount()); - EXPECT_EQ(Index32(3), tree.nonLeafCount()); // root+2*internal + EXPECT_EQ(Index64(3), tree.nonLeafCount()); // root+2*internal std::sort(data.begin(), data.end()); const float median = data[(LeafNodeT::NUM_VALUES-1)>>1]; diff --git a/openvdb/openvdb/unittest/TestTree.cc b/openvdb/openvdb/unittest/TestTree.cc index bb515d0263..aca4c5e93a 100644 --- a/openvdb/openvdb/unittest/TestTree.cc +++ b/openvdb/openvdb/unittest/TestTree.cc @@ -1344,14 +1344,14 @@ TEST_F(TestTree, testTopologyUnion) tree1.touchLeaf(xyz)->setValueOn(0); // single leaf tree0.topologyUnion(tree1, true); // single tile EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(LeafT::NUM_VOXELS), tree0.activeVoxelCount()); tree1.addTile(1, xyz + openvdb::Coord(8), true, true); // leaf + tile tree0.topologyUnion(tree1, true); // two tiles EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(2), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(LeafT::NUM_VOXELS*2), tree0.activeVoxelCount()); @@ -1360,7 +1360,7 @@ TEST_F(TestTree, testTopologyUnion) tree0.addTile(2, xyz, true, true); tree0.topologyUnion(tree1, true); // all topology in tree1 is already active. no change EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(2), tree0.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(2), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(InternalT1::NUM_VOXELS), tree0.activeVoxelCount()); @@ -1369,7 +1369,7 @@ TEST_F(TestTree, testTopologyUnion) tree0.addTile(3, xyz, true, true); tree0.topologyUnion(tree1, true); EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree0.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(1), tree0.nonLeafCount()); EXPECT_EQ(openvdb::Index64(1), tree0.activeTileCount()); EXPECT_EQ(openvdb::Index64(InternalT2::NUM_VOXELS), tree0.activeVoxelCount()); @@ -1380,7 +1380,7 @@ TEST_F(TestTree, testTopologyUnion) tree1.addTile(2, xyz, true, true); tree0.topologyUnion(tree1, true); EXPECT_EQ(openvdb::Index64(0), tree0.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree0.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree0.nonLeafCount()); openvdb::Index64 tiles = openvdb::Index64(InternalT1::DIM) / InternalT1::getChildDim(); tiles = tiles * tiles * tiles; EXPECT_EQ(tiles, tree0.activeTileCount()); diff --git a/openvdb/openvdb/unittest/TestTreeGetSetValues.cc b/openvdb/openvdb/unittest/TestTreeGetSetValues.cc index 834b594510..ea5ce6e9f8 100644 --- a/openvdb/openvdb/unittest/TestTreeGetSetValues.cc +++ b/openvdb/openvdb/unittest/TestTreeGetSetValues.cc @@ -225,17 +225,17 @@ TEST_F(TestTreeGetSetValues, testFill) tree.clear(); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); // root node // Partially fill a single leaf node. tree.fill(CoordBBox(Coord(8), Coord(14)), 0.0); EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); // Completely fill the leaf node, replacing it with a tile. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); { const int activeVoxelCount = int(tree.activeVoxelCount()); @@ -243,81 +243,81 @@ TEST_F(TestTreeGetSetValues, testFill) // Fill a single voxel of the tile with a different (active) value. tree.fill(CoordBBox(Coord(10), Coord(10)), 1.0); EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); EXPECT_EQ(activeVoxelCount, int(tree.activeVoxelCount())); // Fill the voxel with an inactive value. tree.fill(CoordBBox(Coord(10), Coord(10)), 1.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); EXPECT_EQ(activeVoxelCount - 1, int(tree.activeVoxelCount())); // Completely fill the leaf node, replacing it with a tile again. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); } // Expand by one voxel, creating seven neighboring leaf nodes. tree.fill(CoordBBox(Coord(8), Coord(16)), 0.0); EXPECT_EQ(openvdb::Index64(7), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); // Completely fill the internal node containing the tile, replacing it with // a tile at the next level of the tree. tree.fill(CoordBBox(Coord(0), Coord(31)), 0.0); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(2), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(2), tree.nonLeafCount()); // Expand by one voxel, creating a layer of leaf nodes on three faces. tree.fill(CoordBBox(Coord(0), Coord(32)), 0.0); EXPECT_EQ(openvdb::Index64(5*5 + 4*5 + 4*4), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(2 + 7), tree.nonLeafCount()); // +7 internal nodes + EXPECT_EQ(openvdb::Index64(2 + 7), tree.nonLeafCount()); // +7 internal nodes // Completely fill the second-level internal node, replacing it with a root-level tile. tree.fill(CoordBBox(Coord(0), Coord(255)), 0.0); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); // Repeat, filling with an inactive value. tree.clear(); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); // root node // Partially fill a single leaf node. tree.fill(CoordBBox(Coord(8), Coord(14)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(1), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); // Completely fill the leaf node, replacing it with a tile. tree.fill(CoordBBox(Coord(8), Coord(15)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); // Expand by one voxel, creating seven neighboring leaf nodes. tree.fill(CoordBBox(Coord(8), Coord(16)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(7), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(3), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(3), tree.nonLeafCount()); // Completely fill the internal node containing the tile, replacing it with // a tile at the next level of the tree. tree.fill(CoordBBox(Coord(0), Coord(31)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(2), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(2), tree.nonLeafCount()); // Expand by one voxel, creating a layer of leaf nodes on three faces. tree.fill(CoordBBox(Coord(0), Coord(32)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(5*5 + 4*5 + 4*4), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(2 + 7), tree.nonLeafCount()); // +7 internal nodes + EXPECT_EQ(openvdb::Index64(2 + 7), tree.nonLeafCount()); // +7 internal nodes // Completely fill the second-level internal node, replacing it with a root-level tile. tree.fill(CoordBBox(Coord(0), Coord(255)), 0.0, /*active=*/false); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); tree.clear(); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); // Partially fill a region with inactive background values. @@ -325,7 +325,7 @@ TEST_F(TestTreeGetSetValues, testFill) // Confirm that after pruning, the tree is empty. openvdb::tools::prune(tree); EXPECT_EQ(openvdb::Index64(0), tree.leafCount()); - EXPECT_EQ(openvdb::Index32(1), tree.nonLeafCount()); // root node + EXPECT_EQ(openvdb::Index64(1), tree.nonLeafCount()); // root node EXPECT_TRUE(tree.empty()); } diff --git a/openvdb/openvdb/unittest/TestValueAccessor.cc b/openvdb/openvdb/unittest/TestValueAccessor.cc index 8afa873c04..27cedd482a 100644 --- a/openvdb/openvdb/unittest/TestValueAccessor.cc +++ b/openvdb/openvdb/unittest/TestValueAccessor.cc @@ -599,14 +599,14 @@ TEST_F(TestValueAccessor, testAccessorRegistration) // the cache is populated. acc.setValue(c0, value); EXPECT_EQ(Index64(1), tree->leafCount()); - EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); + EXPECT_EQ(Index64(tree->root().getLevel()), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); // Reset the voxel to the background value and verify that no nodes // have been deleted and that the cache is still populated. tree->setValueOff(c0, background); EXPECT_EQ(Index64(1), tree->leafCount()); - EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); + EXPECT_EQ(Index64(tree->root().getLevel()), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); // Prune the tree and verify that only the root node remains and that @@ -614,13 +614,13 @@ TEST_F(TestValueAccessor, testAccessorRegistration) openvdb::tools::prune(*tree); //tree->prune(); EXPECT_EQ(Index64(0), tree->leafCount()); - EXPECT_EQ(Index(1), tree->nonLeafCount()); // root node only + EXPECT_EQ(Index64(1), tree->nonLeafCount()); // root node only EXPECT_TRUE(acc.getNode() == nullptr); // Set the leaf voxel again and verify that the cache is repopulated. acc.setValue(c0, value); EXPECT_EQ(Index64(1), tree->leafCount()); - EXPECT_EQ(tree->root().getLevel(), tree->nonLeafCount()); + EXPECT_EQ(Index64(tree->root().getLevel()), tree->nonLeafCount()); EXPECT_TRUE(acc.getNode() != nullptr); // Delete the tree and verify that the cache has been cleared. From d1264364a261f5bb3f490c50936766423bc3c105 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 08:59:49 -0400 Subject: [PATCH 54/98] compile for versions below 12 Restore 32 bit functionality for versions below 12. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/InternalNode.h | 35 +++++++++++++++- openvdb/openvdb/tree/LeafNode.h | 8 ++++ openvdb/openvdb/tree/LeafNodeBool.h | 9 ++++ openvdb/openvdb/tree/LeafNodeMask.h | 8 ++++ openvdb/openvdb/tree/RootNode.h | 64 ++++++++++++----------------- openvdb/openvdb/tree/Tree.h | 36 ++++++++++++++++ 6 files changed, 122 insertions(+), 38 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 023b72ef85..9f91514a61 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -274,13 +274,18 @@ class InternalNode /// Set the transient data value. void setTransientData(Index32 transientData) { mTransientData = transientData; } +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const; + Index64 nonLeafCount() const; +#else + Index32 leafCount() const; + Index32 nonLeafCount() const; +#endif void nodeCount(std::vector &vec) const; #if OPENVDB_ABI_VERSION_NUMBER < 12 OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &vec) const; #endif - Index64 nonLeafCount() const; Index32 childCount() const; Index64 onVoxelCount() const; Index64 offVoxelCount() const; @@ -1105,6 +1110,7 @@ InternalNode::~InternalNode() //////////////////////////////////////// +#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 InternalNode::leafCount() const @@ -1116,6 +1122,19 @@ InternalNode::leafCount() const } return sum; } +#else +template +inline Index32 +InternalNode::leafCount() const +{ + if (ChildNodeType::getLevel() == 0) return mChildMask.countOn(); + Index32 sum = 0; + for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { + sum += iter->leafCount(); + } + return sum; +} +#endif template inline void @@ -1144,6 +1163,7 @@ InternalNode::nodeCount(std::vector &vec) const #endif +#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 InternalNode::nonLeafCount() const @@ -1155,6 +1175,19 @@ InternalNode::nonLeafCount() const } return sum; } +#else +template +inline Index32 +InternalNode::nonLeafCount() const +{ + Index32 sum = 1; + if (ChildNodeType::getLevel() == 0) return sum; + for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { + sum += iter->nonLeafCount(); + } + return sum; +} +#endif template diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index acef463ef0..5e9857e4b6 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -129,7 +129,11 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } +#else + static Index32 leafCount() { return 1; } +#endif /// no-op void nodeCount(std::vector &) const {} #if OPENVDB_ABI_VERSION_NUMBER < 12 @@ -138,7 +142,11 @@ class LeafNode void nodeCount(std::vector &) const {} #endif /// Return the non-leaf count for this node, which is zero. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } +#else + static Index32 nonLeafCount() { return 0; } +#endif /// Return the child count for this node, which is zero. static Index32 childCount() { return 0; } diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index 690595171e..cce8d1205b 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -131,7 +131,11 @@ class LeafNode static void getNodeLog2Dims(std::vector& dims) { dims.push_back(Log2Dim); } static Index getChildDim() { return 1; } +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } +#else + static Index32 leafCount() { return 1; } +#endif /// no-op void nodeCount(std::vector &) const {} #if OPENVDB_ABI_VERSION_NUMBER < 12 @@ -139,7 +143,12 @@ class LeafNode OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} #endif + +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } +#else + static Index32 nonLeafCount() { return 0; } +#endif /// Return the number of active voxels. Index64 onVoxelCount() const { return mValueMask.countOn(); } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index 39ae76e9c1..b8f93701ec 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -112,7 +112,11 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } +#else + static Index32 leafCount() { return 1; } +#endif /// no-op void nodeCount(std::vector &) const {} #if OPENVDB_ABI_VERSION_NUMBER < 12 @@ -121,7 +125,11 @@ class LeafNode void nodeCount(std::vector &) const {} #endif /// Return the non-leaf count for this node, which is zero. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } +#else + static Index32 nonLeafCount() { return 0; } +#endif /// Return the number of active voxels. Index64 onVoxelCount() const { return mBuffer.mData.countOn(); } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 07c7c91eb5..47c8653015 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -484,8 +484,13 @@ class RootNode template static bool hasCompatibleValueType(const RootNode& other); +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const; Index64 nonLeafCount() const; +#else + Index32 leafCount() const; + Index32 nonLeafCount() const; +#endif Index32 childCount() const; Index32 tileCount() const; Index32 activeTileCount() const; @@ -1542,66 +1547,50 @@ RootNode::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const } +#if OPENVDB_ABI_VERSION_NUMBER >= 12 template -inline Index -RootNode::getChildCount() const { - return this->childCount(); -} - - -template -inline Index -RootNode::getTileCount() const -{ - Index sum = 0; - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTile(i)) ++sum; - } - return sum; -} - - -template -inline Index -RootNode::getActiveTileCount() const +inline Index64 +RootNode::leafCount() const { - Index sum = 0; + Index64 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTileOn(i)) ++sum; + if (isChild(i)) sum += getChild(i).leafCount(); } return sum; } - - +#else template -inline Index -RootNode::getInactiveTileCount() const +inline Index32 +RootNode::leafCount() const { - Index sum = 0; + Index32 sum = 0; for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isTileOff(i)) ++sum; + if (isChild(i)) sum += getChild(i).leafCount(); } return sum; } +#endif +#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 -RootNode::leafCount() const +RootNode::nonLeafCount() const { - Index64 sum = 0; - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) sum += getChild(i).leafCount(); + Index64 sum = 1; + if (ChildT::LEVEL != 0) { + for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { + if (isChild(i)) sum += getChild(i).nonLeafCount(); + } } return sum; } - - +#else template -inline Index64 +inline Index32 RootNode::nonLeafCount() const { - Index64 sum = 1; + Index32 sum = 1; if (ChildT::LEVEL != 0) { for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { if (isChild(i)) sum += getChild(i).nonLeafCount(); @@ -1609,6 +1598,7 @@ RootNode::nonLeafCount() const } return sum; } +#endif template diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index b8cd93ca3f..d1e9b9c6a9 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -361,20 +361,41 @@ class Tree: public TreeBase /// @brief Return the depth of this tree. /// /// A tree with only a root node and leaf nodes has depth 2, for example. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 treeDepth() const override { return Index64(DEPTH); } +#else + Index32 treeDepth() const override { return DEPTH; } +#endif /// Return the number of leaf nodes. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const override { return mRoot.leafCount(); } +#else + Index32 leafCount() const override { return mRoot.leafCount(); } +#endif /// Return a vector with node counts. The number of nodes of type NodeType /// is given as element NodeType::LEVEL in the return vector. Thus, the size /// of this vector corresponds to the height (or depth) of this tree. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 std::vector nodeCount() const override { std::vector vec(DEPTH, 0); mRoot.nodeCount( vec ); return vec;// Named Return Value Optimization } +#else + std::vector nodeCount() const override + { + std::vector vec(DEPTH, 0); + mRoot.nodeCount( vec ); + return vec;// Named Return Value Optimization + } +#endif /// Return the number of non-leaf nodes. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 nonLeafCount() const override { return mRoot.nonLeafCount(); } +#else + Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); } +#endif /// Return the number of active voxels stored in leaf nodes. Index64 activeLeafVoxelCount() const override { return tools::countActiveLeafVoxels(*this); } /// Return the number of inactive voxels stored in leaf nodes. @@ -489,7 +510,11 @@ class Tree: public TreeBase void clipUnallocatedNodes() override; /// Return the total number of unallocated leaf nodes residing in this tree. +#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 unallocatedLeafCount() const override; +#else + Index32 unallocatedLeafCount() const override; +#endif //@{ /// @brief Set all voxels within a given axis-aligned box to a constant value. @@ -1693,6 +1718,7 @@ Tree::clipUnallocatedNodes() } } +#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 Tree::unallocatedLeafCount() const @@ -1701,6 +1727,16 @@ Tree::unallocatedLeafCount() const for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum; return sum; } +#else +template +inline Index32 +Tree::unallocatedLeafCount() const +{ + Index32 sum = 0; + for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum; + return sum; +} +#endif template From 907afa0da60c707f8bab4e7ec61338f2c26fc7ed Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 09:46:41 -0400 Subject: [PATCH 55/98] Update Tree.h Prevent nodeCount deprecation warnings. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/Tree.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index d1e9b9c6a9..796f3756a7 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -386,7 +386,9 @@ class Tree: public TreeBase std::vector nodeCount() const override { std::vector vec(DEPTH, 0); + OPENVDB_NO_DEPRECATION_WARNING_BEGIN mRoot.nodeCount( vec ); + OPENVDB_NO_DEPRECATION_WARNING_END return vec;// Named Return Value Optimization } #endif From b1d114a2d29e100e8ab064e4fe1420b95d5a2b36 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:48:49 -0400 Subject: [PATCH 56/98] Backward compatibility for unit tests. Backward compatibility for unit tests. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/unittest/TestGrid.cc | 12 ++++++++++++ openvdb/openvdb/unittest/TestNodeVisitor.cc | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/openvdb/openvdb/unittest/TestGrid.cc b/openvdb/openvdb/unittest/TestGrid.cc index 26e60199a2..6247dbb982 100644 --- a/openvdb/openvdb/unittest/TestGrid.cc +++ b/openvdb/openvdb/unittest/TestGrid.cc @@ -75,7 +75,11 @@ class ProxyTree: public openvdb::TreeBase void prune(const ValueType& = 0) {} void clip(const openvdb::CoordBBox&) {} void clipUnallocatedNodes() override {} +#if OPENVDB_ABI_VERSION_NUMBER >= 12 openvdb::Index64 unallocatedLeafCount() const override { return 0; } +#else + openvdb::Index32 unallocatedLeafCount() const override { return 0; } +#endif void getIndexRange(openvdb::CoordBBox&) const override {} bool evalLeafBoundingBox(openvdb::CoordBBox& bbox) const override @@ -87,11 +91,19 @@ class ProxyTree: public openvdb::TreeBase bool evalLeafDim(openvdb::Coord& dim) const override { dim = openvdb::Coord(0, 0, 0); return false; } +#if OPENVDB_ABI_VERSION_NUMBER >= 12 openvdb::Index64 treeDepth() const override { return 0; } openvdb::Index64 leafCount() const override { return 0; } std::vector nodeCount() const override { return std::vector(DEPTH, 0); } openvdb::Index64 nonLeafCount() const override { return 0; } +#else + openvdb::Index32 treeDepth() const override { return 0; } + openvdb::Index32 leafCount() const override { return 0; } + std::vector nodeCount() const override + { return std::vector(DEPTH, 0); } + openvdb::Index32 nonLeafCount() const override { return 0; } +#endif openvdb::Index64 activeVoxelCount() const override { return 0UL; } openvdb::Index64 inactiveVoxelCount() const override { return 0UL; } openvdb::Index64 activeLeafVoxelCount() const override { return 0UL; } diff --git a/openvdb/openvdb/unittest/TestNodeVisitor.cc b/openvdb/openvdb/unittest/TestNodeVisitor.cc index 5899b7c591..111a8d3d23 100644 --- a/openvdb/openvdb/unittest/TestNodeVisitor.cc +++ b/openvdb/openvdb/unittest/TestNodeVisitor.cc @@ -36,9 +36,13 @@ TEST_F(TestNodeVisitor, testNodeCount) tools::visitNodesDepthFirst(grid->tree(), nodeCountOp); std::vector nodeCount1 = nodeCountOp.counts; +#if OPENVDB_ABI_VERSION_NUMBER >= 12 std::vector nodeCount2 = grid->tree().nodeCount(); +#else + std::vector nodeCount2 = grid->tree().nodeCount(); +#endif - EXPECT_EQ(nodeCount1.size(), nodeCount2.size()); + EXPECT_EQ(nodeCount1.size(), Index64(nodeCount2.size())); for (size_t i = 0; i < nodeCount1.size(); i++) { EXPECT_EQ(nodeCount1[i], nodeCount2[i]); @@ -141,10 +145,15 @@ TEST_F(TestNodeVisitor, testOriginArray) using namespace openvdb; FloatGrid::Ptr grid = tools::createLevelSetCube(/*scale=*/10.0f); - - std::vector nodeCount = grid->tree().nodeCount(); + Index64 totalNodeCount(0); +#if OPENVDB_ABI_VERSION_NUMBER >= 12 + std::vector nodeCount = grid->tree().nodeCount(); for (Index64 count : nodeCount) totalNodeCount += count; +#else + std::vector nodeCount = grid->tree().nodeCount(); + for (Index32 count : nodeCount) totalNodeCount += Index64(count); +#endif // use an offset size_t offset = 10; From afbd819f029e066337b1e10e79d33490b0599f5b Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:53:11 -0400 Subject: [PATCH 57/98] Update TestNodeVisitor.cc trailing space Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/unittest/TestNodeVisitor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/unittest/TestNodeVisitor.cc b/openvdb/openvdb/unittest/TestNodeVisitor.cc index 111a8d3d23..e24bf72bb2 100644 --- a/openvdb/openvdb/unittest/TestNodeVisitor.cc +++ b/openvdb/openvdb/unittest/TestNodeVisitor.cc @@ -145,7 +145,7 @@ TEST_F(TestNodeVisitor, testOriginArray) using namespace openvdb; FloatGrid::Ptr grid = tools::createLevelSetCube(/*scale=*/10.0f); - + Index64 totalNodeCount(0); #if OPENVDB_ABI_VERSION_NUMBER >= 12 std::vector nodeCount = grid->tree().nodeCount(); From a76faad8b65e3b4bcaabde6fc1703fae7109bb00 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:27:18 -0400 Subject: [PATCH 58/98] Update TestVolumeExecutable.cc AX tests for correct leafCount return type. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- .../test/compiler/TestVolumeExecutable.cc | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc index e84ec2c1c3..4327a6bfc8 100644 --- a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc +++ b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc @@ -12,6 +12,12 @@ class TestVolumeExecutable : public CppUnit::TestCase { public: + +#if OPENVDB_ABI_VERSION_NUMBER >= 12 + using LeafIndexType = openvdb::Index64; +#else + using LeafIndexType = openvdb::Index32; +#endif CPPUNIT_TEST_SUITE(TestVolumeExecutable); CPPUNIT_TEST(testConstructionDestruction); @@ -155,7 +161,7 @@ TestVolumeExecutable::testTreeExecutionLevel() const openvdb::FloatTree copy = tree; // check config auto CHECK_CONFIG = [&]() { - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(3), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-4), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); @@ -357,7 +363,7 @@ TestVolumeExecutable::testActiveTileStreaming() CPPUNIT_ASSERT_EQUAL(openvdb::Index(openvdb::FloatTree::DEPTH-1), max); executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(3), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-4), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); @@ -404,7 +410,7 @@ TestVolumeExecutable::testActiveTileStreaming() openvdb::Index64(NodeT1::NUM_VOXELS) + openvdb::Index64(NodeT0::NUM_VOXELS); - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-1), tree.getValueDepth(openvdb::Coord(0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-1), tree.getValueDepth(openvdb::Coord(NodeT1::DIM))); @@ -463,7 +469,7 @@ TestVolumeExecutable::testActiveTileStreaming() ((n1ChildCount * (n2ChildAxisCount * n2ChildAxisCount)) - leafs) // NodeT1 face tiles (NodeT0) - leafs + 1 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT2::DIM))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-2), tree.getValueDepth(openvdb::Coord(NodeT2::DIM+NodeT1::DIM))); @@ -512,7 +518,7 @@ TestVolumeExecutable::testActiveTileStreaming() executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(0), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(5), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*0, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); @@ -567,7 +573,7 @@ TestVolumeExecutable::testActiveTileStreaming() (n1ChildCount - leafs) // NodeT1 face tiles (NodeT0) - leafs + 3 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(openvdb::BoolTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(openvdb::BoolTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*2, 0, 0))); @@ -624,7 +630,7 @@ TestVolumeExecutable::testActiveTileStreaming() (n1ChildCount - leafs) // NodeT1 face tiles (NodeT0) - leafs + 3 /*NodeT1*/ + 1 /*NodeT0*/; - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(leafs), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(leafs), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(tiles), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(int(StringTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*1, 0, 0))); CPPUNIT_ASSERT_EQUAL(int(StringTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(NodeT1::DIM*2, 0, 0))); @@ -668,7 +674,7 @@ TestVolumeExecutable::testActiveTileStreaming() executable->execute(grid); - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(1), tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(1), tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(2), tree.activeTileCount()); CPPUNIT_ASSERT(tree.hasSameTopology(copy)); CPPUNIT_ASSERT_EQUAL(int(openvdb::FloatTree::DEPTH-3), tree.getValueDepth(openvdb::Coord(0))); @@ -715,7 +721,7 @@ TestVolumeExecutable::testActiveTileStreaming() openvdb::Index64(NodeT1::NUM_VOXELS) + openvdb::Index64(NodeT0::NUM_VOXELS); - CPPUNIT_ASSERT_EQUAL(openvdb::Index64(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS) + 1, tree.leafCount()); + CPPUNIT_ASSERT_EQUAL(LeafIndexType(voxels / openvdb::FloatTree::LeafNodeType::NUM_VOXELS) + 1, tree.leafCount()); CPPUNIT_ASSERT_EQUAL(openvdb::Index64(0), tree.activeTileCount()); CPPUNIT_ASSERT_EQUAL(voxels, tree.activeVoxelCount()); CPPUNIT_ASSERT_EQUAL(leaf, tree.probeLeaf(openvdb::Coord(NodeT1::DIM + NodeT0::DIM))); From 97d6750ef1234865b4bbcb10d72aac66a459239d Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:28:33 -0400 Subject: [PATCH 59/98] Update TestVolumeExecutable.cc trailing space Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc index 4327a6bfc8..f0b9eeef8f 100644 --- a/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc +++ b/openvdb_ax/openvdb_ax/test/compiler/TestVolumeExecutable.cc @@ -12,7 +12,7 @@ class TestVolumeExecutable : public CppUnit::TestCase { public: - + #if OPENVDB_ABI_VERSION_NUMBER >= 12 using LeafIndexType = openvdb::Index64; #else From 607db982d390fdfad2fa8eb6324ad638251f1ca6 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:41:23 -0400 Subject: [PATCH 60/98] Update TestPointExecutable.cc AX test failures Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- .../openvdb_ax/test/compiler/TestPointExecutable.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc b/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc index 14da8b3828..a619856140 100644 --- a/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc +++ b/openvdb_ax/openvdb_ax/test/compiler/TestPointExecutable.cc @@ -20,6 +20,12 @@ class TestPointExecutable : public CppUnit::TestCase { public: +#if OPENVDB_ABI_VERSION_NUMBER >= 12 + using LeafIndexType = openvdb::Index64; +#else + using LeafIndexType = openvdb::Index32; +#endif + CPPUNIT_TEST_SUITE(TestPointExecutable); CPPUNIT_TEST(testConstructionDestruction); CPPUNIT_TEST(testCreateMissingAttributes); @@ -545,7 +551,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), LeafIndexType(1)); // collapsed uniform 0 attributes points::appendAttribute(points->tree(), "f"); @@ -641,7 +647,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), LeafIndexType(1)); // collapsed uniform 0 attributes points::appendAttribute>(points->tree(), "fpu8"); @@ -728,7 +734,7 @@ TestPointExecutable::testAttributeCodecs() points = points::createPointDataGrid , points::PointDataGrid> (twoPoints, *defaultTransform); - CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), Index64(1)); + CPPUNIT_ASSERT_EQUAL(points->tree().leafCount(), LeafIndexType(1)); points::appendAttribute(points->tree(), "t"); points::appendAttribute>(points->tree(), "f"); From 26f0ad1ea6a1a3b69307a9e4c969fa01e2f86499 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:52:51 -0400 Subject: [PATCH 61/98] deprecation suppression deprecation suppression in recursive nodeCount calls. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/InternalNode.h | 6 +++++- openvdb/openvdb/tree/RootNode.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 9f91514a61..8bb01ae7f6 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -1156,7 +1156,11 @@ InternalNode::nodeCount(std::vector &vec) const OPENVDB_ASSERT(vec.size() > ChildNodeType::LEVEL); const auto count = mChildMask.countOn(); if (ChildNodeType::LEVEL > 0 && count > 0) { - for (auto iter = this->cbeginChildOn(); iter; ++iter) iter->nodeCount(vec); + for (auto iter = this->cbeginChildOn(); iter; ++iter) { + OPENVDB_NO_DEPRECATION_WARNING_BEGIN + iter->nodeCount(vec); + OPENVDB_NO_DEPRECATION_WARNING_END + } } vec[ChildNodeType::LEVEL] += count; } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 47c8653015..232040f371 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -1745,7 +1745,9 @@ RootNode::nodeCount(std::vector &vec) const for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { if (isChild(i)) { ++sum; + OPENVDB_NO_DEPRECATION_WARNING_BEGIN getChild(i).nodeCount(vec); + OPENVDB_NO_DEPRECATION_WARNING_END } } vec[LEVEL] = 1;// one root node From aba7d2d4352aa9a893250e5353290476858222c5 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:00:36 -0400 Subject: [PATCH 62/98] define deprecated nodeCount for all versions. define deprecated nodeCount for all versions. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/InternalNode.h | 4 ---- openvdb/openvdb/tree/LeafNode.h | 3 --- openvdb/openvdb/tree/LeafNodeBool.h | 3 --- openvdb/openvdb/tree/LeafNodeMask.h | 3 --- openvdb/openvdb/tree/RootNode.h | 4 ---- 5 files changed, 17 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 8bb01ae7f6..97caafeeda 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -282,10 +282,8 @@ class InternalNode Index32 nonLeafCount() const; #endif void nodeCount(std::vector &vec) const; -#if OPENVDB_ABI_VERSION_NUMBER < 12 OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &vec) const; -#endif Index32 childCount() const; Index64 onVoxelCount() const; Index64 offVoxelCount() const; @@ -1148,7 +1146,6 @@ InternalNode::nodeCount(std::vector &vec) const vec[ChildNodeType::LEVEL] += count; } -#if OPENVDB_ABI_VERSION_NUMBER < 12 template inline void InternalNode::nodeCount(std::vector &vec) const @@ -1164,7 +1161,6 @@ InternalNode::nodeCount(std::vector &vec) const } vec[ChildNodeType::LEVEL] += count; } -#endif #if OPENVDB_ABI_VERSION_NUMBER >= 12 diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 5e9857e4b6..33df861354 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -136,11 +136,8 @@ class LeafNode #endif /// no-op void nodeCount(std::vector &) const {} -#if OPENVDB_ABI_VERSION_NUMBER < 12 - /// no-op OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} -#endif /// Return the non-leaf count for this node, which is zero. #if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index cce8d1205b..e5f61e57bb 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -138,11 +138,8 @@ class LeafNode #endif /// no-op void nodeCount(std::vector &) const {} -#if OPENVDB_ABI_VERSION_NUMBER < 12 - /// no-op OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} -#endif #if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index b8f93701ec..b9a62248e8 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -119,11 +119,8 @@ class LeafNode #endif /// no-op void nodeCount(std::vector &) const {} -#if OPENVDB_ABI_VERSION_NUMBER < 12 - /// no-op OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} -#endif /// Return the non-leaf count for this node, which is zero. #if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 232040f371..bf8809cea7 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -501,10 +501,8 @@ class RootNode Index64 offLeafVoxelCount() const; Index64 onTileCount() const; void nodeCount(std::vector &vec) const; -#if OPENVDB_ABI_VERSION_NUMBER < 12 OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &vec) const; -#endif bool isValueOn(const Coord& xyz) const; @@ -1735,7 +1733,6 @@ RootNode::nodeCount(std::vector &vec) const vec[ChildNodeType::LEVEL] = sum; } -#if OPENVDB_ABI_VERSION_NUMBER < 12 template inline void RootNode::nodeCount(std::vector &vec) const @@ -1753,7 +1750,6 @@ RootNode::nodeCount(std::vector &vec) const vec[LEVEL] = 1;// one root node vec[ChildNodeType::LEVEL] = sum; } -#endif //////////////////////////////////////// From 52d61fd779603efdcf4ee7b2b8cd4760de36ba25 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:25:05 -0400 Subject: [PATCH 63/98] treeDepth stays Index Keep Index return type for treeDepth. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/Tree.h | 12 ++---------- openvdb/openvdb/unittest/TestGrid.cc | 3 +-- openvdb/openvdb/unittest/TestNodeIterator.cc | 8 ++++---- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index 796f3756a7..a92241acde 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -115,11 +115,7 @@ class OPENVDB_API TreeBase /// @brief Return the depth of this tree. /// /// A tree with only a root node and leaf nodes has depth 2, for example. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 - virtual Index64 treeDepth() const = 0; -#else - virtual Index32 treeDepth() const = 0; -#endif + virtual Index treeDepth() const = 0; /// Return the number of leaf nodes. #if OPENVDB_ABI_VERSION_NUMBER >= 12 virtual Index64 leafCount() const = 0; @@ -361,11 +357,7 @@ class Tree: public TreeBase /// @brief Return the depth of this tree. /// /// A tree with only a root node and leaf nodes has depth 2, for example. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 - Index64 treeDepth() const override { return Index64(DEPTH); } -#else - Index32 treeDepth() const override { return DEPTH; } -#endif + Index treeDepth() const override { return DEPTH; } /// Return the number of leaf nodes. #if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const override { return mRoot.leafCount(); } diff --git a/openvdb/openvdb/unittest/TestGrid.cc b/openvdb/openvdb/unittest/TestGrid.cc index 6247dbb982..27c76ec0f6 100644 --- a/openvdb/openvdb/unittest/TestGrid.cc +++ b/openvdb/openvdb/unittest/TestGrid.cc @@ -91,14 +91,13 @@ class ProxyTree: public openvdb::TreeBase bool evalLeafDim(openvdb::Coord& dim) const override { dim = openvdb::Coord(0, 0, 0); return false; } + openvdb::Index treeDepth() const override { return 0; } #if OPENVDB_ABI_VERSION_NUMBER >= 12 - openvdb::Index64 treeDepth() const override { return 0; } openvdb::Index64 leafCount() const override { return 0; } std::vector nodeCount() const override { return std::vector(DEPTH, 0); } openvdb::Index64 nonLeafCount() const override { return 0; } #else - openvdb::Index32 treeDepth() const override { return 0; } openvdb::Index32 leafCount() const override { return 0; } std::vector nodeCount() const override { return std::vector(DEPTH, 0); } diff --git a/openvdb/openvdb/unittest/TestNodeIterator.cc b/openvdb/openvdb/unittest/TestNodeIterator.cc index 5f0562e388..a977e4200c 100644 --- a/openvdb/openvdb/unittest/TestNodeIterator.cc +++ b/openvdb/openvdb/unittest/TestNodeIterator.cc @@ -58,7 +58,7 @@ TEST_F(TestNodeIterator, testSinglePositive) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); + EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -108,7 +108,7 @@ TEST_F(TestNodeIterator, testSinglePositive) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); + EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -163,7 +163,7 @@ TEST_F(TestNodeIterator, testSingleNegative) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); + EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); openvdb::CoordBBox range, bbox; tree.getIndexRange(range); iter.getBoundingBox(bbox); @@ -217,7 +217,7 @@ TEST_F(TestNodeIterator, testMultipleBlocks) EXPECT_TRUE(iter); EXPECT_EQ(0U, iter.getDepth()); - EXPECT_EQ(tree.treeDepth(), openvdb::Index64(1 + iter.getLevel())); + EXPECT_EQ(tree.treeDepth(), 1 + iter.getLevel()); // Descend to the depth-1 internal node with bounding box // (-256, -256, -256) -> (-1, -1, -1) containing voxel (-1, -1, -1). From 485373877001a7af4e7475b99d242b544440b5bf Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:41:52 -0400 Subject: [PATCH 64/98] Avoid ABI conditionals in Root/Internal/Leaf Avoid ABI conditionals in Root/Internal/Leaf node files. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tree/InternalNode.h | 33 ----------------------------- openvdb/openvdb/tree/LeafNode.h | 8 ------- openvdb/openvdb/tree/LeafNodeBool.h | 9 -------- openvdb/openvdb/tree/LeafNodeMask.h | 8 ------- openvdb/openvdb/tree/RootNode.h | 33 ----------------------------- openvdb/openvdb/tree/Tree.h | 4 ++-- 6 files changed, 2 insertions(+), 93 deletions(-) diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 97caafeeda..534fc9553d 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -274,13 +274,8 @@ class InternalNode /// Set the transient data value. void setTransientData(Index32 transientData) { mTransientData = transientData; } -#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const; Index64 nonLeafCount() const; -#else - Index32 leafCount() const; - Index32 nonLeafCount() const; -#endif void nodeCount(std::vector &vec) const; OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &vec) const; @@ -1108,7 +1103,6 @@ InternalNode::~InternalNode() //////////////////////////////////////// -#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 InternalNode::leafCount() const @@ -1120,19 +1114,6 @@ InternalNode::leafCount() const } return sum; } -#else -template -inline Index32 -InternalNode::leafCount() const -{ - if (ChildNodeType::getLevel() == 0) return mChildMask.countOn(); - Index32 sum = 0; - for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { - sum += iter->leafCount(); - } - return sum; -} -#endif template inline void @@ -1163,7 +1144,6 @@ InternalNode::nodeCount(std::vector &vec) const } -#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 InternalNode::nonLeafCount() const @@ -1175,19 +1155,6 @@ InternalNode::nonLeafCount() const } return sum; } -#else -template -inline Index32 -InternalNode::nonLeafCount() const -{ - Index32 sum = 1; - if (ChildNodeType::getLevel() == 0) return sum; - for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) { - sum += iter->nonLeafCount(); - } - return sum; -} -#endif template diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index 33df861354..c47bac7ed6 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -129,21 +129,13 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } -#else - static Index32 leafCount() { return 1; } -#endif /// no-op void nodeCount(std::vector &) const {} OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} /// Return the non-leaf count for this node, which is zero. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } -#else - static Index32 nonLeafCount() { return 0; } -#endif /// Return the child count for this node, which is zero. static Index32 childCount() { return 0; } diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index e5f61e57bb..15145ae874 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -131,21 +131,12 @@ class LeafNode static void getNodeLog2Dims(std::vector& dims) { dims.push_back(Log2Dim); } static Index getChildDim() { return 1; } -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } -#else - static Index32 leafCount() { return 1; } -#endif /// no-op void nodeCount(std::vector &) const {} OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} - -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } -#else - static Index32 nonLeafCount() { return 0; } -#endif /// Return the number of active voxels. Index64 onVoxelCount() const { return mValueMask.countOn(); } diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index b9a62248e8..b861685f5b 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -112,21 +112,13 @@ class LeafNode /// Return the dimension of child nodes of this LeafNode, which is one for voxels. static Index getChildDim() { return 1; } /// Return the leaf count for this node, which is one. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 leafCount() { return 1; } -#else - static Index32 leafCount() { return 1; } -#endif /// no-op void nodeCount(std::vector &) const {} OPENVDB_DEPRECATED_MESSAGE("Use input type std::vector for nodeCount.") void nodeCount(std::vector &) const {} /// Return the non-leaf count for this node, which is zero. -#if OPENVDB_ABI_VERSION_NUMBER >= 12 static Index64 nonLeafCount() { return 0; } -#else - static Index32 nonLeafCount() { return 0; } -#endif /// Return the number of active voxels. Index64 onVoxelCount() const { return mBuffer.mData.countOn(); } diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index bf8809cea7..88a9dfa6f8 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -484,13 +484,8 @@ class RootNode template static bool hasCompatibleValueType(const RootNode& other); -#if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const; Index64 nonLeafCount() const; -#else - Index32 leafCount() const; - Index32 nonLeafCount() const; -#endif Index32 childCount() const; Index32 tileCount() const; Index32 activeTileCount() const; @@ -1545,7 +1540,6 @@ RootNode::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const } -#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 RootNode::leafCount() const @@ -1556,21 +1550,8 @@ RootNode::leafCount() const } return sum; } -#else -template -inline Index32 -RootNode::leafCount() const -{ - Index32 sum = 0; - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) sum += getChild(i).leafCount(); - } - return sum; -} -#endif -#if OPENVDB_ABI_VERSION_NUMBER >= 12 template inline Index64 RootNode::nonLeafCount() const @@ -1583,20 +1564,6 @@ RootNode::nonLeafCount() const } return sum; } -#else -template -inline Index32 -RootNode::nonLeafCount() const -{ - Index32 sum = 1; - if (ChildT::LEVEL != 0) { - for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) { - if (isChild(i)) sum += getChild(i).nonLeafCount(); - } - } - return sum; -} -#endif template diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index a92241acde..9db13edcc2 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -362,7 +362,7 @@ class Tree: public TreeBase #if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 leafCount() const override { return mRoot.leafCount(); } #else - Index32 leafCount() const override { return mRoot.leafCount(); } + Index32 leafCount() const override { return static_cast(mRoot.leafCount()); } #endif /// Return a vector with node counts. The number of nodes of type NodeType /// is given as element NodeType::LEVEL in the return vector. Thus, the size @@ -388,7 +388,7 @@ class Tree: public TreeBase #if OPENVDB_ABI_VERSION_NUMBER >= 12 Index64 nonLeafCount() const override { return mRoot.nonLeafCount(); } #else - Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); } + Index32 nonLeafCount() const override { return static_cast(mRoot.nonLeafCount()); } #endif /// Return the number of active voxels stored in leaf nodes. Index64 activeLeafVoxelCount() const override { return tools::countActiveLeafVoxels(*this); } From 11686a8028b7809633ae546819bf592ea74afcd2 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:00:53 -0400 Subject: [PATCH 65/98] Update TestTree.cc Remove migrated tests. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/unittest/TestTree.cc | 201 --------------------------- 1 file changed, 201 deletions(-) diff --git a/openvdb/openvdb/unittest/TestTree.cc b/openvdb/openvdb/unittest/TestTree.cc index aca4c5e93a..a5ac2afade 100644 --- a/openvdb/openvdb/unittest/TestTree.cc +++ b/openvdb/openvdb/unittest/TestTree.cc @@ -2756,204 +2756,3 @@ TEST_F(TestTree, testNodeCount) EXPECT_EQ(tree.leafCount(), nodeCount2.front());// leaf nodes for (size_t i=0; i children; - root.stealNodes(children); - EXPECT_TRUE(root.empty()); - - // insert the root node children directly - for (ChildType* child : children) { - root.addChild(child); - } - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(2), root.childCount()); - - { // verify the coordinates of the root node children - auto rootIter = root.cbeginChildOn(); - EXPECT_EQ(c0, rootIter.getCoord()); - ++rootIter; - EXPECT_EQ(c1, rootIter.getCoord()); - } - } - - { // test inserting tiles and replacing them with child nodes - RootNodeType root(0.0f); - EXPECT_TRUE(root.empty()); - - // no-op - root.addChild(nullptr); - - // populate the root node by inserting tiles - root.addTile(c0, /*value=*/1.0f, /*state=*/true); - root.addTile(c1, /*value=*/2.0f, /*state=*/true); - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(0), root.childCount()); - EXPECT_TRUE(root.hasActiveTiles()); - ASSERT_DOUBLES_EXACTLY_EQUAL(1.0f, root.getValue(c0)); - ASSERT_DOUBLES_EXACTLY_EQUAL(2.0f, root.getValue(c1)); - - // insert child nodes with the same coordinates - root.addChild(new ChildType(c0, 3.0f)); - root.addChild(new ChildType(c1, 4.0f)); - - // insert a new child at c0 - root.addChild(new ChildType(c0, 5.0f)); - - // verify active tiles have been replaced by child nodes - EXPECT_EQ(openvdb::Index(2), root.getTableSize()); - EXPECT_EQ(openvdb::Index32(2), root.childCount()); - EXPECT_TRUE(!root.hasActiveTiles()); - - { // verify the coordinates of the root node children - auto rootIter = root.cbeginChildOn(); - EXPECT_EQ(c0, rootIter.getCoord()); - ASSERT_DOUBLES_EXACTLY_EQUAL(5.0f, root.getValue(c0)); - ++rootIter; - EXPECT_EQ(c1, rootIter.getCoord()); - } - } - - { // test transient data - RootNodeType rootNode(0.0f); - EXPECT_EQ(openvdb::Index32(0), rootNode.transientData()); - rootNode.setTransientData(openvdb::Index32(5)); - EXPECT_EQ(openvdb::Index32(5), rootNode.transientData()); - RootNodeType rootNode2(rootNode); - EXPECT_EQ(openvdb::Index32(5), rootNode2.transientData()); - RootNodeType rootNode3 = rootNode; - EXPECT_EQ(openvdb::Index32(5), rootNode3.transientData()); - } -} - -TEST_F(TestTree, testInternalNode) -{ - const openvdb::Coord c0(1000, 1000, 1000); - const openvdb::Coord c1(896, 896, 896); - - using InternalNodeType = InternalNodeType1; - using ChildType = LeafNodeType; - - { // test inserting child nodes directly and indirectly - openvdb::Coord c2 = c1.offsetBy(8,0,0); - openvdb::Coord c3 = c1.offsetBy(16,16,16); - - InternalNodeType internalNode(c1, 0.0f); - internalNode.touchLeaf(c2); - internalNode.touchLeaf(c3); - - EXPECT_EQ(openvdb::Index64(2), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - - { // verify c0 and c1 are the root node coordinates - auto childIter = internalNode.cbeginChildOn(); - EXPECT_EQ(c2, childIter.getCoord()); - ++childIter; - EXPECT_EQ(c3, childIter.getCoord()); - } - - // copy the internal node - InternalNodeType internalNodeCopy(internalNode); - - // steal the internal node children leaving it empty again - std::vector children; - internalNode.stealNodes(children, 0.0f, false); - EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // insert the root node children directly - for (ChildType* child : children) { - internalNode.addChild(child); - } - EXPECT_EQ(openvdb::Index64(2), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(2), internalNode.childCount()); - - { // verify the coordinates of the root node children - auto childIter = internalNode.cbeginChildOn(); - EXPECT_EQ(c2, childIter.getCoord()); - ++childIter; - EXPECT_EQ(c3, childIter.getCoord()); - } - } - - { // test inserting a tile and replacing with a child node - InternalNodeType internalNode(c1, 0.0f); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // add a tile - internalNode.addTile(openvdb::Index(0), /*value=*/1.0f, /*state=*/true); - EXPECT_TRUE(internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index64(0), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(0), internalNode.childCount()); - - // replace the tile with a child node - EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 2.0f))); - EXPECT_TRUE(!internalNode.hasActiveTiles()); - EXPECT_EQ(openvdb::Index64(1), internalNode.leafCount()); - EXPECT_EQ(openvdb::Index32(1), internalNode.childCount()); - EXPECT_EQ(c1, internalNode.cbeginChildOn().getCoord()); - ASSERT_DOUBLES_EXACTLY_EQUAL(2.0f, internalNode.cbeginChildOn()->getValue(0)); - - // replace the child node with another child node - EXPECT_TRUE(internalNode.addChild(new ChildType(c1, 3.0f))); - ASSERT_DOUBLES_EXACTLY_EQUAL(3.0f, internalNode.cbeginChildOn()->getValue(0)); - } - - { // test inserting child nodes that do and do not belong to the internal node - InternalNodeType internalNode(c1, 0.0f); - - // succeed if child belongs to this internal node - EXPECT_TRUE(internalNode.addChild(new ChildType(c0.offsetBy(8,0,0)))); - EXPECT_TRUE(internalNode.probeLeaf(c0.offsetBy(8,0,0))); - openvdb::Index index1 = internalNode.coordToOffset(c0); - openvdb::Index index2 = internalNode.coordToOffset(c0.offsetBy(8,0,0)); - EXPECT_TRUE(!internalNode.isChildMaskOn(index1)); - EXPECT_TRUE(internalNode.isChildMaskOn(index2)); - - // fail otherwise - auto* child = new ChildType(c0.offsetBy(8000,0,0)); - EXPECT_TRUE(!internalNode.addChild(child)); - delete child; - } - - { // test transient data - InternalNodeType internalNode(c1, 0.0f); - EXPECT_EQ(openvdb::Index32(0), internalNode.transientData()); - internalNode.setTransientData(openvdb::Index32(5)); - EXPECT_EQ(openvdb::Index32(5), internalNode.transientData()); - InternalNodeType internalNode2(internalNode); - EXPECT_EQ(openvdb::Index32(5), internalNode2.transientData()); - InternalNodeType internalNode3 = internalNode; - EXPECT_EQ(openvdb::Index32(5), internalNode3.transientData()); - } -} From 3a023b4404dd8eb8fc5da8e74bb0112cd4ed5fc6 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 13:58:04 -0700 Subject: [PATCH 66/98] Remove pdal from vcpkg Signed-off-by: Dan Bailey --- ci/install_windows.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/install_windows.ps1 b/ci/install_windows.ps1 index ce8d908951..6054cb96bf 100644 --- a/ci/install_windows.ps1 +++ b/ci/install_windows.ps1 @@ -7,7 +7,6 @@ $vcpkgPackages = @( "zlib", "libpng", "openexr", - "pdal", "tbb", "gtest", "cppunit", From d8c33bdf8cfc356e84da24f0aeec709af307148a Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 14:42:05 -0700 Subject: [PATCH 67/98] Update dependencies and enforce minimum versions Signed-off-by: Dan Bailey --- CMakeLists.txt | 4 ++-- ci/install_llvm_windows.sh | 2 +- cmake/config/OpenVDBVersions.cmake | 27 +++++++++++----------- doc/dependencies.txt | 22 +++++++++--------- nanovdb/nanovdb/CMakeLists.txt | 8 +++---- openvdb_ax/openvdb_ax/test/TestAXCmd.cmake | 2 +- openvdb_cmd/vdb_render/CMakeLists.txt | 4 ++-- openvdb_cmd/vdb_tool/CMakeLists.txt | 8 +++---- pyproject.toml | 4 +--- 9 files changed, 39 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d061bc73..2feab47219 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -479,8 +479,8 @@ endif() if(OPENVDB_BUILD_PYTHON_MODULE OR (OPENVDB_BUILD_NANOVDB AND NANOVDB_BUILD_PYTHON_MODULE)) # Call find_package(Python ...) - find_package(Python 3.8 REQUIRED COMPONENTS Development Interpreter) - find_package(nanobind REQUIRED) + 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}) diff --git a/ci/install_llvm_windows.sh b/ci/install_llvm_windows.sh index 642013d46a..c174c50296 100644 --- a/ci/install_llvm_windows.sh +++ b/ci/install_llvm_windows.sh @@ -4,7 +4,7 @@ set -ex LLVM_CRT="$1" -git clone -b llvmorg-12.0.0 --depth 1 https://github.com/llvm/llvm-project.git llvm +git clone -b llvmorg-14.0.0 --depth 1 https://github.com/llvm/llvm-project.git llvm cd llvm mkdir .build diff --git a/cmake/config/OpenVDBVersions.cmake b/cmake/config/OpenVDBVersions.cmake index fadad1104d..fd175e629e 100644 --- a/cmake/config/OpenVDBVersions.cmake +++ b/cmake/config/OpenVDBVersions.cmake @@ -34,24 +34,23 @@ if(NOT DISABLE_DEPENDENCY_VERSION_CHECKS) # 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 9.3.1) + set(MINIMUM_GCC_VERSION 11.2.1) set(MINIMUM_CLANG_VERSION 5.0) set(MINIMUM_ICC_VERSION 19) - set(MINIMUM_MSVC_VERSION 19.28) # 1928 (Visual Studio 2019 Version 16.8 + 16.9) + set(MINIMUM_MSVC_VERSION 19.30) # 1928 (Visual Studio 2019 Version 16.8 + 16.9) - # Should be 1.76 for VFX 22, but only version in apt is 1.73 - set(MINIMUM_BOOST_VERSION 1.73) + set(MINIMUM_BOOST_VERSION 1.80) set(MINIMUM_PYBIND_VERSION 2.9.1) 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 10.0.0) + 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.9.1) - set(MINIMUM_NUMPY_VERSION 1.20.0) + 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) @@ -66,20 +65,20 @@ endif() # @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) # 1930 (Visual Studio 2022) +# 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.20) -# set(FUTURE_MINIMUM_OPENEXR_VERSION 3.1) -set(FUTURE_MINIMUM_BOOST_VERSION 1.80) +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_BLOSC_VERSION 1.17.0) # set(FUTURE_MINIMUM_TBB_VERSION 2020.3) -set(FUTURE_MINIMUM_PYTHON_VERSION 3.10) -set(FUTURE_MINIMUM_NUMPY_VERSION 1.23.0) +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 13.0.0) +# set(FUTURE_MINIMUM_LLVM_VERSION 13.0.0) diff --git a/doc/dependencies.txt b/doc/dependencies.txt index c20ba77bb1..2ea810e5ea 100644 --- a/doc/dependencies.txt +++ b/doc/dependencies.txt @@ -56,22 +56,22 @@ OpenVDB Documentation | Doxygen | - Package | Minimum | Recommended | Description | apt-get | Homebrew | Source -------------- | ------- | ----------- | ----------------------------------------------------------------- | ------- | -------- | ------ -CMake | 3.18 | Latest | Cross-platform family of tools designed to help build software | Y | Y | https://cmake.org -GCC | 9.3.1 | 11.2.1 | C++ 17 Compiler: The GNU Compiler Collection | Y | Y | https://www.gnu.org/software/gcc +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.28 | 19.30 | C++ 17 Compiler: Microsoft Visual C++ Compiler | Y | Y | https://visualstudio.microsoft.com/vs +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.2 | 2020.3 | Threading Building Blocks - template library for task parallelism | Y | Y | https://www.threadingbuildingblocks.org +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.73 | 1.80 | Components: iostreams | Y | Y | https://www.boost.org -LLVM | 10.0.0 | 13.0.0* | Target-independent code generation | Y | Y | https://llvm.org/ -Bison | 3.0.0 | 3.7.0 | General-purpose parser generator | Y | Y | https://www.gnu.org/software/gcc -Flex | 2.6.0 | 2.6.4 | Fast lexical analyzer generator | Y | Y | https://github.com/westes/flex -Python | 3.9.1 | 3.10 | The python interpreter and libraries | Y | Y | https://www.python.org +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 | Latest | C++/python bindings | Y | Y | https://nanobind.readthedocs.io -NumPy | 1.20.0 | 1.23.0 | Scientific computing with Python | Y | Y | http://www.numpy.org +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 @@ -145,7 +145,7 @@ apt-get install zlibc # zlib apt-get install libboost-iostreams-dev # Boost::iostream apt-get install libblosc-dev # Blosc # AX -apt-get install llvm-10-dev # LLVM +apt-get install llvm-15-dev # LLVM # Python apt-get install python-dev # Python apt-get install python-numpy # NumPy diff --git a/nanovdb/nanovdb/CMakeLists.txt b/nanovdb/nanovdb/CMakeLists.txt index 1c50d2eade..cb33dedde7 100644 --- a/nanovdb/nanovdb/CMakeLists.txt +++ b/nanovdb/nanovdb/CMakeLists.txt @@ -74,7 +74,7 @@ endif() #if(NANOVDB_BUILD_UNITTESTS OR NANOVDB_BUILD_BENCHMARK) if(NANOVDB_BUILD_UNITTESTS) - find_package(GTest REQUIRED) + find_package(GTest ${MINIMUM_GOOGLETEST_VERSION} REQUIRED) endif() if(NANOVDB_USE_CUDA) @@ -124,15 +124,15 @@ if(NANOVDB_USE_OPENVDB) endif() if(NANOVDB_USE_TBB AND NOT TARGET TBB::tbb) - find_package(TBB REQUIRED) + find_package(TBB ${MINIMUM_TBB_VERSION} REQUIRED) endif() if(NANOVDB_USE_BLOSC AND NOT TARGET Blosc::blosc) - find_package(Blosc REQUIRED) + find_package(Blosc ${MINIMUM_BLOSC_VERSION} REQUIRED) endif() if(NANOVDB_USE_ZLIB AND NOT TARGET ZLIB::ZLIB) - find_package(ZLIB REQUIRED) + find_package(ZLIB ${MINIMUM_ZLIB_VERSION} REQUIRED) endif() if(NANOVDB_USE_MAGICAVOXEL) diff --git a/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake b/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake index 7cccd639c4..117b9e97d0 100644 --- a/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake +++ b/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake @@ -33,7 +33,7 @@ set(SPHERE_VDB ${CMAKE_BINARY_DIR}/sphere.vdb) set(TORUS_VDB ${CMAKE_BINARY_DIR}/torus.vdb) if(DOWNLOAD_VDBS) - find_package(Python COMPONENTS Interpreter REQUIRED) + find_package(Python ${MINIMUM_PYTHON_VERSION} COMPONENTS Interpreter REQUIRED) if(NOT EXISTS ${SPHERE_VDB} OR NOT EXISTS ${TORUS_VDB} OR NOT EXISTS ${SPHERE_POINTS_VDB}) diff --git a/openvdb_cmd/vdb_render/CMakeLists.txt b/openvdb_cmd/vdb_render/CMakeLists.txt index f19134b2f1..0a63ba8115 100644 --- a/openvdb_cmd/vdb_render/CMakeLists.txt +++ b/openvdb_cmd/vdb_render/CMakeLists.txt @@ -17,11 +17,11 @@ if(USE_PNG) endif() if(USE_IMATH_HALF) - find_package(Imath CONFIG REQUIRED) + find_package(Imath ${MINIMUM_IMATH_VERSION} CONFIG REQUIRED) endif() if(USE_EXR) - find_package(OpenEXR CONFIG REQUIRED) + find_package(OpenEXR ${MINIMUM_OPENEXR_VERSION} CONFIG REQUIRED) endif() set(SOURCE_FILES main.cc) diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index f20d69d291..a58784b75c 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -51,12 +51,12 @@ if(OPENVDB_TOOL_USE_NANO) target_compile_definitions(vdb_tool_common INTERFACE "VDB_TOOL_USE_NANO") if(OPENVDB_TOOL_NANO_USE_ZIP) target_compile_definitions(vdb_tool_common INTERFACE "NANOVDB_USE_ZIP") - find_package(ZLIB REQUIRED) + find_package(ZLIB ${MINIMUM_ZLIB_VERSION} REQUIRED) target_link_libraries(vdb_tool_common INTERFACE ZLIB::ZLIB) endif() if(OPENVDB_TOOL_NANO_USE_BLOSC) target_compile_definitions(vdb_tool_common INTERFACE "NANOVDB_USE_BLOSC") - find_package(Blosc REQUIRED) + find_package(Blosc ${MINIMUM_BLOSC_VERSION} REQUIRED) target_link_libraries(vdb_tool_common INTERFACE blosc) endif() #target_include_directories(vdb_tool_common INTERFACE ${PROJECT_SOURCE_DIR}/../nanovdb/) @@ -107,7 +107,7 @@ endif() if(OPENVDB_TOOL_USE_EXR) target_compile_definitions(vdb_tool_common INTERFACE "VDB_TOOL_USE_EXR") - find_package(OpenEXR REQUIRED) + find_package(OpenEXR ${MINIMUM_OPENEXR_VERSION} REQUIRED) target_link_libraries(vdb_tool_common INTERFACE OpenEXR::IlmImf) endif() @@ -186,7 +186,7 @@ install(TARGETS vdb_tool RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) # unit test if(BUILD_TEST) - find_package(GTest CONFIG REQUIRED) + find_package(GTest ${MINIMUM_GOOGLETEST_VERSION} CONFIG REQUIRED) add_executable(vdb_tool_test src/unittest.cpp) target_include_directories(vdb_tool_test PRIVATE vdb_tool_common) diff --git a/pyproject.toml b/pyproject.toml index 33f87d4a35..aa2cf63d26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,11 +12,9 @@ dependencies = [ authors = [ { name = "OpenVDB Developer Team", email = "openvdb-dev@lists.aswf.io" }, ] -requires-python = ">=3.8" +requires-python = ">=3.10" classifiers = [ "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", ] From 7d6410ba435c11b15f0baed1b2d85a106f408545 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 10:39:14 -0700 Subject: [PATCH 68/98] Bump CMake minimum 3.18 -> 3.20 Signed-off-by: Dan Bailey --- CMakeLists.txt | 2 +- ci/test_install.sh | 2 +- cmake/FindBlosc.cmake | 2 +- cmake/FindCppUnit.cmake | 2 +- cmake/FindJemalloc.cmake | 2 +- cmake/FindLog4cplus.cmake | 2 +- cmake/FindOpenEXR.cmake | 2 +- cmake/FindOpenVDB.cmake | 2 +- cmake/FindTBB.cmake | 2 +- cmake/OpenVDBGLFW3Setup.cmake | 2 +- cmake/OpenVDBHoudiniSetup.cmake | 2 +- cmake/OpenVDBMayaSetup.cmake | 2 +- cmake/OpenVDBUtils.cmake | 2 +- cmake/Uninstall.cmake | 2 +- cmake/config/OpenVDBCXX.cmake | 2 +- cmake/config/OpenVDBVersions.cmake | 2 +- doc/CMakeLists.txt | 2 +- doc/build.txt | 2 +- nanovdb/nanovdb/CMakeLists.txt | 10 ++++------ nanovdb/nanovdb/cmd/CMakeLists.txt | 2 +- nanovdb/nanovdb/examples/CMakeLists.txt | 2 +- nanovdb/nanovdb/unittest/CMakeLists.txt | 2 +- openvdb/openvdb/CMakeLists.txt | 2 +- openvdb/openvdb/python/CMakeLists.txt | 2 +- openvdb/openvdb/unittest/CMakeLists.txt | 2 +- openvdb_ax/openvdb_ax/CMakeLists.txt | 2 +- openvdb_ax/openvdb_ax/test/CMakeLists.txt | 2 +- openvdb_ax/openvdb_ax/test/TestAXCmd.cmake | 2 +- openvdb_cmd/CMakeLists.txt | 2 +- openvdb_cmd/vdb_ax/CMakeLists.txt | 2 +- openvdb_cmd/vdb_lod/CMakeLists.txt | 2 +- openvdb_cmd/vdb_print/CMakeLists.txt | 2 +- openvdb_cmd/vdb_render/CMakeLists.txt | 2 +- openvdb_cmd/vdb_tool/CMakeLists.txt | 2 +- openvdb_cmd/vdb_view/CMakeLists.txt | 2 +- openvdb_houdini/openvdb_houdini/CMakeLists.txt | 2 +- openvdb_houdini/openvdb_houdini/abitest/CMakeLists.txt | 2 +- openvdb_maya/openvdb_maya/CMakeLists.txt | 2 +- 38 files changed, 41 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2feab47219..7ae4335401 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ # note: cmake_minimum_required must be called before project commands to # ensure policy scope is set up correctly -cmake_minimum_required(VERSION 3.18) +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(). diff --git a/ci/test_install.sh b/ci/test_install.sh index be6a477dd8..da4bc0f004 100755 --- a/ci/test_install.sh +++ b/ci/test_install.sh @@ -8,7 +8,7 @@ set -e # the expected VDB installation cmakelists=" -cmake_minimum_required(VERSION 3.18) +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\") diff --git a/cmake/FindBlosc.cmake b/cmake/FindBlosc.cmake index fedf1ad4d3..158050e216 100644 --- a/cmake/FindBlosc.cmake +++ b/cmake/FindBlosc.cmake @@ -88,7 +88,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) mark_as_advanced( diff --git a/cmake/FindCppUnit.cmake b/cmake/FindCppUnit.cmake index 8d9f973ebd..34bdced9ed 100644 --- a/cmake/FindCppUnit.cmake +++ b/cmake/FindCppUnit.cmake @@ -83,7 +83,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/FindJemalloc.cmake b/cmake/FindJemalloc.cmake index 7f8a483cd0..9b2e14555c 100644 --- a/cmake/FindJemalloc.cmake +++ b/cmake/FindJemalloc.cmake @@ -64,7 +64,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/FindLog4cplus.cmake b/cmake/FindLog4cplus.cmake index dc00598960..7e3a584806 100644 --- a/cmake/FindLog4cplus.cmake +++ b/cmake/FindLog4cplus.cmake @@ -87,7 +87,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/FindOpenEXR.cmake b/cmake/FindOpenEXR.cmake index 4601a0fbbb..a8aea21d01 100644 --- a/cmake/FindOpenEXR.cmake +++ b/cmake/FindOpenEXR.cmake @@ -93,7 +93,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/FindOpenVDB.cmake b/cmake/FindOpenVDB.cmake index 30e8e352f0..33b08388c0 100644 --- a/cmake/FindOpenVDB.cmake +++ b/cmake/FindOpenVDB.cmake @@ -109,7 +109,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index db5601249c..eda06bb754 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -93,7 +93,7 @@ may be provided to tell this module where to look. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) diff --git a/cmake/OpenVDBGLFW3Setup.cmake b/cmake/OpenVDBGLFW3Setup.cmake index 78e2f2170f..21ae81bb4c 100644 --- a/cmake/OpenVDBGLFW3Setup.cmake +++ b/cmake/OpenVDBGLFW3Setup.cmake @@ -47,7 +47,7 @@ The following variables may be provided to tell this module where to look. # Find the glfw3 installation and use glfw's CMake to initialize # the glfw lib -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) set(_FIND_GLFW3_ADDITIONAL_OPTIONS "") if(DISABLE_CMAKE_SEARCH_PATHS) diff --git a/cmake/OpenVDBHoudiniSetup.cmake b/cmake/OpenVDBHoudiniSetup.cmake index b28174f12d..a4ab24f2e0 100644 --- a/cmake/OpenVDBHoudiniSetup.cmake +++ b/cmake/OpenVDBHoudiniSetup.cmake @@ -73,7 +73,7 @@ may be provided to tell this module where to look. # Find the Houdini installation and use Houdini's CMake to initialize # the Houdini lib -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) # Include utility functions for version information include(${CMAKE_CURRENT_LIST_DIR}/OpenVDBUtils.cmake) diff --git a/cmake/OpenVDBMayaSetup.cmake b/cmake/OpenVDBMayaSetup.cmake index fb05ae919b..4ff3166a2e 100644 --- a/cmake/OpenVDBMayaSetup.cmake +++ b/cmake/OpenVDBMayaSetup.cmake @@ -51,7 +51,7 @@ variables may be provided to tell this module where to look. # Find the Maya installation and use Maya's CMake to initialize # the Maya lib -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) set(_FIND_MAYA_ADDITIONAL_OPTIONS "") diff --git a/cmake/OpenVDBUtils.cmake b/cmake/OpenVDBUtils.cmake index 6e8426c112..b2f07c7549 100644 --- a/cmake/OpenVDBUtils.cmake +++ b/cmake/OpenVDBUtils.cmake @@ -57,7 +57,7 @@ The following functions are provided: #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) function(OPENVDB_GET_VERSION_DEFINE HEADER KEY VALUE) diff --git a/cmake/Uninstall.cmake b/cmake/Uninstall.cmake index d2a99e3faf..e95c4c5229 100644 --- a/cmake/Uninstall.cmake +++ b/cmake/Uninstall.cmake @@ -16,7 +16,7 @@ existing from a previous run of cmake. #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") diff --git a/cmake/config/OpenVDBCXX.cmake b/cmake/config/OpenVDBCXX.cmake index 365c5d5cde..3586732bdb 100644 --- a/cmake/config/OpenVDBCXX.cmake +++ b/cmake/config/OpenVDBCXX.cmake @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) ############################################################################### diff --git a/cmake/config/OpenVDBVersions.cmake b/cmake/config/OpenVDBVersions.cmake index fd175e629e..a0ba4f2008 100644 --- a/cmake/config/OpenVDBVersions.cmake +++ b/cmake/config/OpenVDBVersions.cmake @@ -8,7 +8,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) ############################################################################### diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a6f4f26731..67e5f259e5 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBDocs LANGUAGES NONE) include(GNUInstallDirs) diff --git a/doc/build.txt b/doc/build.txt index 83c5788c49..3048731a55 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -514,7 +514,7 @@ 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.18) +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) diff --git a/nanovdb/nanovdb/CMakeLists.txt b/nanovdb/nanovdb/CMakeLists.txt index cb33dedde7..4e0284ecbf 100644 --- a/nanovdb/nanovdb/CMakeLists.txt +++ b/nanovdb/nanovdb/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(NanoVDB LANGUAGES C CXX) include(GNUInstallDirs) @@ -81,11 +81,9 @@ if(NANOVDB_USE_CUDA) set(CMAKE_CUDA_STANDARD 17) set(CMAKE_CUDA_STANDARD_REQUIRED ON) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) - # Allow the user to provide CMAKE_CUDA_ARCHITECTURES - if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) - set(CMAKE_CUDA_ARCHITECTURES 75) - endif() + # Allow the user to provide CMAKE_CUDA_ARCHITECTURES + if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + set(CMAKE_CUDA_ARCHITECTURES 75) endif() enable_language(CUDA) diff --git a/nanovdb/nanovdb/cmd/CMakeLists.txt b/nanovdb/nanovdb/cmd/CMakeLists.txt index 6513b14d2a..985a7d1d70 100644 --- a/nanovdb/nanovdb/cmd/CMakeLists.txt +++ b/nanovdb/nanovdb/cmd/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(NanoVDBExamples LANGUAGES CXX) include(GNUInstallDirs) diff --git a/nanovdb/nanovdb/examples/CMakeLists.txt b/nanovdb/nanovdb/examples/CMakeLists.txt index cfbc33de0c..d06371cd95 100644 --- a/nanovdb/nanovdb/examples/CMakeLists.txt +++ b/nanovdb/nanovdb/examples/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(NanoVDBExamples LANGUAGES CXX) include(GNUInstallDirs) diff --git a/nanovdb/nanovdb/unittest/CMakeLists.txt b/nanovdb/nanovdb/unittest/CMakeLists.txt index de9f355f0b..ac63a610d4 100644 --- a/nanovdb/nanovdb/unittest/CMakeLists.txt +++ b/nanovdb/nanovdb/unittest/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(NanoVDBTests LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb/openvdb/CMakeLists.txt b/openvdb/openvdb/CMakeLists.txt index 2ea9974698..3db0e4e144 100644 --- a/openvdb/openvdb/CMakeLists.txt +++ b/openvdb/openvdb/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBCore LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb/openvdb/python/CMakeLists.txt b/openvdb/openvdb/python/CMakeLists.txt index cfdd4727bf..c67884bce3 100644 --- a/openvdb/openvdb/python/CMakeLists.txt +++ b/openvdb/openvdb/python/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBPython LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb/openvdb/unittest/CMakeLists.txt b/openvdb/openvdb/unittest/CMakeLists.txt index 3339c97195..b1e04ebcfe 100644 --- a/openvdb/openvdb/unittest/CMakeLists.txt +++ b/openvdb/openvdb/unittest/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBUnitTests LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_ax/openvdb_ax/CMakeLists.txt b/openvdb_ax/openvdb_ax/CMakeLists.txt index 9bde5bb921..e0d95caeb7 100644 --- a/openvdb_ax/openvdb_ax/CMakeLists.txt +++ b/openvdb_ax/openvdb_ax/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) # There is a bug introduced with LLVM 14 config files which causes CMake to # complain if the project is not init-ted with LANGUAGES C diff --git a/openvdb_ax/openvdb_ax/test/CMakeLists.txt b/openvdb_ax/openvdb_ax/test/CMakeLists.txt index 5dead7b2da..a5997e2099 100644 --- a/openvdb_ax/openvdb_ax/test/CMakeLists.txt +++ b/openvdb_ax/openvdb_ax/test/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBAXUnitTests LANGUAGES CXX) option(OPENVDB_AX_TEST_PROFILE "Switch on profiling for some of the unit tests." OFF) diff --git a/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake b/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake index 117b9e97d0..9f1743877f 100644 --- a/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake +++ b/openvdb_ax/openvdb_ax/test/TestAXCmd.cmake @@ -12,7 +12,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) option(UPDATE_BASELINES "Replace the expected outputs whilst running tests" OFF) option(DOWNLOAD_VDBS "Fetch .vdb files required for some tests" OFF) diff --git a/openvdb_cmd/CMakeLists.txt b/openvdb_cmd/CMakeLists.txt index 02c02e2641..edbb1a4e59 100644 --- a/openvdb_cmd/CMakeLists.txt +++ b/openvdb_cmd/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBBinaries LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_cmd/vdb_ax/CMakeLists.txt b/openvdb_cmd/vdb_ax/CMakeLists.txt index 2370d9d902..11562df353 100644 --- a/openvdb_cmd/vdb_ax/CMakeLists.txt +++ b/openvdb_cmd/vdb_ax/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(VDBAX LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_cmd/vdb_lod/CMakeLists.txt b/openvdb_cmd/vdb_lod/CMakeLists.txt index a4348603ad..a67bdde2f4 100644 --- a/openvdb_cmd/vdb_lod/CMakeLists.txt +++ b/openvdb_cmd/vdb_lod/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(VDBLOD LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_cmd/vdb_print/CMakeLists.txt b/openvdb_cmd/vdb_print/CMakeLists.txt index 25f00390c5..de58c90fba 100644 --- a/openvdb_cmd/vdb_print/CMakeLists.txt +++ b/openvdb_cmd/vdb_print/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(VDBPrint LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_cmd/vdb_render/CMakeLists.txt b/openvdb_cmd/vdb_render/CMakeLists.txt index 0a63ba8115..032dfeeb66 100644 --- a/openvdb_cmd/vdb_render/CMakeLists.txt +++ b/openvdb_cmd/vdb_render/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(VDBRender LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index a58784b75c..da1ade24ca 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.18) +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(). diff --git a/openvdb_cmd/vdb_view/CMakeLists.txt b/openvdb_cmd/vdb_view/CMakeLists.txt index e7bf546c5e..9744b9f16a 100644 --- a/openvdb_cmd/vdb_view/CMakeLists.txt +++ b/openvdb_cmd/vdb_view/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(VDBView LANGUAGES CXX) include(GNUInstallDirs) diff --git a/openvdb_houdini/openvdb_houdini/CMakeLists.txt b/openvdb_houdini/openvdb_houdini/CMakeLists.txt index 9680f492c8..204a153f9c 100644 --- a/openvdb_houdini/openvdb_houdini/CMakeLists.txt +++ b/openvdb_houdini/openvdb_houdini/CMakeLists.txt @@ -40,7 +40,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBHoudini LANGUAGES CXX) diff --git a/openvdb_houdini/openvdb_houdini/abitest/CMakeLists.txt b/openvdb_houdini/openvdb_houdini/abitest/CMakeLists.txt index f2c5b3fcd0..62c476d43f 100644 --- a/openvdb_houdini/openvdb_houdini/abitest/CMakeLists.txt +++ b/openvdb_houdini/openvdb_houdini/abitest/CMakeLists.txt @@ -12,7 +12,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBHoudiniABITest) diff --git a/openvdb_maya/openvdb_maya/CMakeLists.txt b/openvdb_maya/openvdb_maya/CMakeLists.txt index 3236fa7fe9..62b9bf6fb5 100644 --- a/openvdb_maya/openvdb_maya/CMakeLists.txt +++ b/openvdb_maya/openvdb_maya/CMakeLists.txt @@ -7,7 +7,7 @@ #]=======================================================================] -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) project(OpenVDBMaya LANGUAGES CXX) message(WARNING "The OpenVDB Maya plugin is currently unmaintained. The plugin " From c884baa6c0dca2299197219d45a2d591c4c52da7 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 14:50:44 -0700 Subject: [PATCH 69/98] Remove some old GCC checks Signed-off-by: Dan Bailey --- openvdb/openvdb/Platform.h | 14 ++++---------- openvdb/openvdb/tools/MeshToVolume.h | 2 +- openvdb_ax/openvdb_ax/test/backend/TestStringIR.cc | 4 ---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/openvdb/openvdb/Platform.h b/openvdb/openvdb/Platform.h index bb99d9bf10..eebd4620ad 100644 --- a/openvdb/openvdb/Platform.h +++ b/openvdb/openvdb/Platform.h @@ -211,16 +211,10 @@ #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END #elif defined __GNUC__ // -Wfloat-conversion was only introduced in GCC 4.9 - #if OPENVDB_CHECK_GCC(4, 9) - #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wconversion\"") \ - _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"") - #else - #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wconversion\"") - #endif + #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wconversion\"") \ + _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"") #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END \ _Pragma("GCC diagnostic pop") #else diff --git a/openvdb/openvdb/tools/MeshToVolume.h b/openvdb/openvdb/tools/MeshToVolume.h index 2d4d3fafad..6d85f23576 100644 --- a/openvdb/openvdb/tools/MeshToVolume.h +++ b/openvdb/openvdb/tools/MeshToVolume.h @@ -16,7 +16,7 @@ #ifndef OPENVDB_TOOLS_MESH_TO_VOLUME_HAS_BEEN_INCLUDED #define OPENVDB_TOOLS_MESH_TO_VOLUME_HAS_BEEN_INCLUDED -#include // for OPENVDB_HAS_CXX11 +#include #include #include // for GodunovsNormSqrd #include // for closestPointOnTriangleToPoint diff --git a/openvdb_ax/openvdb_ax/test/backend/TestStringIR.cc b/openvdb_ax/openvdb_ax/test/backend/TestStringIR.cc index 1301262521..fe5dde8726 100644 --- a/openvdb_ax/openvdb_ax/test/backend/TestStringIR.cc +++ b/openvdb_ax/openvdb_ax/test/backend/TestStringIR.cc @@ -289,10 +289,8 @@ TestStringIR::testStringStringIR() { static auto setInvalidString = [](String& S) { #if defined(__GNUC__) && !defined(__clang__) -#if OPENVDB_CHECK_GCC(8, 0) _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"") -#endif #endif // zero out the data held by a String object (expected to not hold heap memory). // This is used to test the IR methods work as expected with the allocated, but @@ -300,9 +298,7 @@ TestStringIR::testStringStringIR() OPENVDB_ASSERT(S.isLocal()); std::memset(&S, 0, sizeof(String)); // uninit string, invalid class memory #if defined(__GNUC__) && !defined(__clang__) -#if OPENVDB_CHECK_GCC(8, 0) _Pragma("GCC diagnostic pop") -#endif #endif }; From 6a8415f7d49a8970e84d61bc14e2281afffaa6a6 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 14:42:35 -0700 Subject: [PATCH 70/98] Bump version to 12.0.0 Signed-off-by: Dan Bailey --- CHANGES | 2 +- CMakeLists.txt | 4 ++-- doc/changes.txt | 2 +- openvdb/openvdb/openvdb.cc | 12 +++++++++--- openvdb/openvdb/version.h.in | 14 ++++++++++---- pyproject.toml | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 677d8794d7..84e0356393 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,7 @@ OpenVDB Version History ======================= -Version 12.0.0 - In development +Version 12.0.0 - October 31, 2024 OpenVDB: Improvements: diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ae4335401..34df1309df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,9 +52,9 @@ endif() ###### Version -set(OpenVDB_MAJOR_VERSION 11) +set(OpenVDB_MAJOR_VERSION 12) set(OpenVDB_MINOR_VERSION 0) -set(OpenVDB_PATCH_VERSION 1) +set(OpenVDB_PATCH_VERSION 0) set(OpenVDB_VERSION "${OpenVDB_MAJOR_VERSION}.${OpenVDB_MINOR_VERSION}.${OpenVDB_PATCH_VERSION}") project(OpenVDB LANGUAGES CXX VERSION ${OpenVDB_VERSION}) diff --git a/doc/changes.txt b/doc/changes.txt index 24f41674b8..0987ed107e 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -4,7 +4,7 @@ @htmlonly @endhtmlonly @par -Version 12.0.0 - In Development +Version 12.0.0 - October 31, 2024 @par OpenVDB: diff --git a/openvdb/openvdb/openvdb.cc b/openvdb/openvdb/openvdb.cc index bb2431bac7..f1e3b79224 100644 --- a/openvdb/openvdb/openvdb.cc +++ b/openvdb/openvdb/openvdb.cc @@ -26,14 +26,20 @@ #error ABI = 10 is deprecated, CMake option OPENVDB_USE_DEPRECATED_ABI_10 suppresses this error #endif #endif +#ifndef OPENVDB_USE_DEPRECATED_ABI_11 + #if OPENVDB_ABI_VERSION_NUMBER == 11 + PRAGMA(message("NOTE: ABI = 11 is deprecated, define OPENVDB_USE_DEPRECATED_ABI_11 " + "to suppress this message")) + #endif +#endif // If using a future OPENVDB_ABI_VERSION_NUMBER, issue an error directive. // This can be optionally suppressed by defining: // OPENVDB_USE_FUTURE_ABI_=ON. -#ifndef OPENVDB_USE_FUTURE_ABI_12 - #if OPENVDB_ABI_VERSION_NUMBER == 12 +#ifndef OPENVDB_USE_FUTURE_ABI_13 + #if OPENVDB_ABI_VERSION_NUMBER == 13 #error ABI = 12 is still in active development and has not been finalized, \ -CMake option OPENVDB_USE_FUTURE_ABI_12 suppresses this error +CMake option OPENVDB_USE_FUTURE_ABI_13 suppresses this error #endif #endif diff --git a/openvdb/openvdb/version.h.in b/openvdb/openvdb/version.h.in index 6a6c0892f0..1591071955 100644 --- a/openvdb/openvdb/version.h.in +++ b/openvdb/openvdb/version.h.in @@ -175,10 +175,10 @@ // This can be suppressed by defining OPENVDB_USE_FUTURE_ABI_=ON. // Note that, whilst the VDB CMake does not allow this option to be hit, // it exists to propagate this message to downstream targets - #if OPENVDB_ABI_VERSION_NUMBER == 12 - #ifndef OPENVDB_USE_FUTURE_ABI_12 - PRAGMA(message("NOTE: ABI = 12 is still in active development and has not been finalized, " - "define OPENVDB_USE_FUTURE_ABI_11 to suppress this message")) + #if OPENVDB_ABI_VERSION_NUMBER == 13 + #ifndef OPENVDB_USE_FUTURE_ABI_13 + PRAGMA(message("NOTE: ABI = 13 is still in active development and has not been finalized, " + "define OPENVDB_USE_FUTURE_ABI_13 to suppress this message")) #endif #else #error expected OPENVDB_ABI_VERSION_NUMBER <= OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER @@ -195,6 +195,12 @@ "to suppress this message")) #endif #endif +#ifndef OPENVDB_USE_DEPRECATED_ABI_11 + #if OPENVDB_ABI_VERSION_NUMBER == 11 + PRAGMA(message("NOTE: ABI = 11 is deprecated, define OPENVDB_USE_DEPRECATED_ABI_11 " + "to suppress this message")) + #endif +#endif /// By default, the @b OPENVDB_REQUIRE_VERSION_NAME macro is undefined, and /// symbols from the version namespace are promoted to the top-level namespace diff --git a/pyproject.toml b/pyproject.toml index aa2cf63d26..ea644a7831 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "openvdb" -version = "11.0.1" +version = "12.0.0" description= "Python bindings for OpenVDB: sparse volume data structure and tools." dependencies = [ "numpy", From 880a3718ea0fdeadb710606f9ebf8b7c342dc43d Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 21:42:00 -0700 Subject: [PATCH 71/98] Lots of CI updates Signed-off-by: Dan Bailey --- .github/workflows/ax.yml | 13 +++---------- .github/workflows/build.yml | 18 +++++------------- .github/workflows/houdini.yml | 8 -------- .github/workflows/nanovdb.yml | 8 ++------ .github/workflows/weekly.yml | 29 +++-------------------------- ci/build.sh | 1 + 6 files changed, 14 insertions(+), 63 deletions(-) diff --git a/.github/workflows/ax.yml b/.github/workflows/ax.yml index 98c5ed5ba6..e8ed06f5c4 100644 --- a/.github/workflows/ax.yml +++ b/.github/workflows/ax.yml @@ -70,14 +70,8 @@ jobs: - { image: '2023-clang15', cxx: 'clang++', build: 'Release', cmake: '' } - { image: '2023-clang15', cxx: 'g++', build: 'Release', cmake: '' } - { image: '2023-clang15', cxx: 'clang++', build: 'Debug', cmake: '' } - - { image: '2022-clang11', cxx: 'clang++', build: 'Release', cmake: '' } - - { image: '2022-clang11', cxx: 'g++', build: 'Release', cmake: '' } fail-fast: false steps: - - name: Enable Node 16 - if: contains(matrix.config.image, '2022') - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: nanobind #if: contains(matrix.config.image, '2023') == false @@ -126,10 +120,9 @@ jobs: strategy: matrix: config: - #@note llvm10 never got its own brew formula... + #@note llvm15 never got its own brew formula... # Last macos runner befor M1 (macos-14) - - { runner: 'macos-13', cxx: 'clang++', build: 'Release', llvm: '12' } - - { runner: 'macos-13', cxx: 'clang++', build: 'Release', llvm: '13' } + - { runner: 'macos-13', cxx: 'clang++', build: 'Release', llvm: '15' } fail-fast: false steps: - uses: actions/checkout@v3 @@ -159,7 +152,7 @@ jobs: github.event.inputs.type == 'grammar' runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-20.04-8c-32g-300h') || 'ubuntu-latest' }} container: - image: aswf/ci-openvdb:2022-clang11 + image: aswf/ci-openvdb:2023-clang15 steps: - uses: actions/checkout@v3 - name: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 394729dcab..3e7798e8fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,23 +76,15 @@ jobs: strategy: matrix: config: - - { cxx: clang++, image: '2024', abi: '11', build: 'Release', cmake: '' } - - { cxx: g++, image: '2024', abi: '11', build: 'Release', cmake: '' } - - { cxx: clang++, image: '2024', abi: '11', build: 'Debug', cmake: '' } - - { cxx: clang++, image: '2023', abi: '11', build: 'Release', cmake: '' } - - { cxx: g++, image: '2023', abi: '11', build: 'Release', cmake: '' } - - { cxx: clang++, image: '2022', abi: '10', build: 'Release', cmake: '-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON' } - - { cxx: g++, image: '2022', abi: '10', build: 'Release', cmake: '-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON' } + - { 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: - - name: Enable Node 16 - # Solution taken from https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default - if: contains(matrix.config.image, '2022') - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - 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 diff --git a/.github/workflows/houdini.yml b/.github/workflows/houdini.yml index 2506eb333b..68348e3351 100644 --- a/.github/workflows/houdini.yml +++ b/.github/workflows/houdini.yml @@ -80,15 +80,8 @@ jobs: - { 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' } - - { cxx: clang++, image: '2022', hou_hash: '20_0-oldabi', build: 'Release', components: 'core,hou' } - - { cxx: g++, image: '2022', hou_hash: '20_0-oldabi', build: 'Release', components: 'core,hou' } fail-fast: false steps: - # See note on this step in the Houdini weekly.yml job - # We can remove this when we no longer use < 2023 images - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - name: remove zstd run: yum -y remove zstd - uses: actions/checkout@v3 @@ -99,7 +92,6 @@ jobs: if: contains(matrix.config.image, '2023') == true run: ./ci/install_glfw.sh 3.3.10 - name: cppunit - if: contains(matrix.config.image, '2022') == false run: ./ci/install_cppunit.sh 1.15.1 - name: timestamp id: timestamp diff --git a/.github/workflows/nanovdb.yml b/.github/workflows/nanovdb.yml index dee840e076..43b2c233d9 100644 --- a/.github/workflows/nanovdb.yml +++ b/.github/workflows/nanovdb.yml @@ -67,10 +67,6 @@ jobs: - { cxx: clang++, image: '2024', build: 'Debug' } fail-fast: false steps: - - name: Enable Node 16 - if: contains(matrix.config.image, '2022') - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: setup_cuda_12 run: | @@ -150,8 +146,8 @@ jobs: strategy: matrix: config: - - { runner: 'macos-12', cxx: 'clang++', build: 'Release' } - - { runner: 'macos-12', cxx: 'clang++', build: 'Debug' } + - { runner: 'macos-13', cxx: 'clang++', build: 'Release' } + - { runner: 'macos-13', cxx: 'clang++', build: 'Debug' } fail-fast: false steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 234393c46c..747c8af744 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -70,17 +70,12 @@ jobs: strategy: matrix: config: - - { houdini_version: '19.5', platform: 'linux_x86_64_gcc9.3', hou_hash: '19_5' } - - { houdini_version: '20.0', platform: 'linux_x86_64_gcc9.3', hou_hash: '20_0-oldabi' } - { 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: - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - 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 @@ -172,9 +167,6 @@ jobs: - { name: 'conf', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON' } fail-fast: false steps: - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: nanobind #if: contains(container.image, '2023') == false @@ -224,7 +216,7 @@ jobs: ./ci/build.sh -v --build-type=Release --components=\"core,axcore,python,bin,render,test,axbin\" - --cargs=\"-DCMAKE_CXX_STANDARD=20 -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install ${{ matrix.config.cmake }}\" + --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 @@ -303,20 +295,10 @@ jobs: matrix: config: # Unified - - { image: '2023-clang14', cxx: 'clang++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' } - - { image: '2023-clang14', cxx: 'g++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' } - - { image: '2022-clang13', cxx: 'clang++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' } - - { image: '2022-clang13', cxx: 'g++', build: 'Release', components: 'core,bin,axcore,axbin,axtest', cmake: '' } - # Standalone - - { image: '2022-clang11', cxx: 'clang++', build: 'Debug', components: 'core', cmake: '' } - - { image: '2022-clang11', cxx: 'clang++', build: 'Release', components: 'core', cmake: '' } - - { image: '2022-clang11', cxx: 'g++', build: 'Release', components: 'core', cmake: '' } + - { 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: - - name: Enable Node 16 - if: contains(matrix.config.image, '2022') - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: nanobind #f: contains(matrix.config.image, '2023') == false @@ -364,9 +346,7 @@ jobs: strategy: matrix: config: - - { cxx: 'clang++', build: 'Release', llvm: '14' } - { cxx: 'clang++', build: 'Release', llvm: '15' } - #- { cxx: 'clang++', build: 'Release', llvm: '16' } - not supported yet fail-fast: false steps: - uses: actions/checkout@v3 @@ -522,9 +502,6 @@ jobs: blosc: ['1.18.0','1.19.0','1.20.0','1.21.0'] fail-fast: false steps: - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: install_blosc run: sudo ./ci/install_blosc.sh ${{ matrix.blosc }} diff --git a/ci/build.sh b/ci/build.sh index 2c6d93ac22..b3b318d093 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -185,6 +185,7 @@ set -x # 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 \ From b9f09a2580cc31a5b04a5fd3d7eb3781548e891b Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 23:39:45 -0700 Subject: [PATCH 72/98] Update docs GHA workflow Signed-off-by: Dan Bailey --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2f78f9a787..1fff84b892 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -92,7 +92,7 @@ jobs: github.event.inputs.deploy == 'docs' uses: peaceiris/actions-gh-pages@v3 with: - deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} + deploy_key: ${{ secrets.PRIVATE_KEY }} publish_dir: /usr/local/share/doc/OpenVDB/html destination_dir: documentation/doxygen external_repository: AcademySoftwareFoundation/openvdb-website From 667f4f477a584dfc0bd8ce8c537bd318b9f7827a Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 20:04:00 -0700 Subject: [PATCH 73/98] Fix a memory leak in RootNode Signed-off-by: Dan Bailey --- openvdb/openvdb/tree/RootNode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index c3aba1131b..8bbf2ee618 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -2201,7 +2201,7 @@ RootNode::fill(const CoordBBox& bbox, const ValueType& value, bool activ // with the tile's value and active state. const Tile& tile = getTile(iter); child = new ChildT(xyz, tile.value, tile.active); - mTable.emplace(tileMin, *child); + setChild(iter, *child); } else if (isChild(iter)) { child = &getChild(iter); } From 5768e86d6117d3a7d3a92552a0cc60a4ff011c92 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Wed, 30 Oct 2024 22:03:01 -0700 Subject: [PATCH 74/98] Update change log Signed-off-by: Dan Bailey --- CHANGES | 50 ++++++++++- doc/changes.txt | 138 ++++++++++++++++++++--------- pendingchanges/levelset_fillet.txt | 2 - pendingchanges/probe.txt | 10 --- pendingchanges/unsafe.txt | 16 ---- 5 files changed, 146 insertions(+), 70 deletions(-) delete mode 100644 pendingchanges/levelset_fillet.txt delete mode 100644 pendingchanges/probe.txt delete mode 100644 pendingchanges/unsafe.txt diff --git a/CHANGES b/CHANGES index 84e0356393..f15d035aa5 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,18 @@ OpenVDB Version History Version 12.0.0 - October 31, 2024 + This version introduces ABI changes relative to older major releases, + so to preserve ABI compatibility it might be necessary to define the + macro OPENVDB_ABI_VERSION_NUMBER=N, where, for example, N is 10 for + Houdini 20.0 and 11 for Houdini 20.5. + + GCC 9 is no longer supported. + OpenVDB: + New features: + - Added fillet() method in tools::LevelSetFilter to round off concave edges + to create smoother transition between surfaces. + Improvements: - Added openvdb::assertAbort to replace cassert and a OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle @@ -19,11 +30,49 @@ Version 12.0.0 - October 31, 2024 - ValueAccessors are now defined and created in the Tree class instead of in the Grid class so that custom Tree implementations may define and create their own ValueAccessors if desired. + - Added support for PDAL to vdb_tool [Contributed by Tom Matterson] + - LeafManager and NodeManager now use Index64 for leaf counts internally. + - Added RootNode::probeChild() const. + - Added RootNode::probeChild() and RootNode::probeConstChild(). + - Added RootNode::probe() and RootNode::probeConst() to query key presence, + child node, value and active state. + - Added InternalNode::probeChild() const. + - Added InternalNode::probeChild() and probeChildConst() with coord access + and optionally value and active state. + - Added InternalNode::probeChild() and probeChildConst() with index access + and optionally value and active state. + - Added InternalNode::isValueOff(), LeafNode::isValueOff(), + LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). + - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). + - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), + RootNode::getConstChildUnsafe(). + - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), + InternalNode::getConstChildUnsafe(). + - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), + InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). + - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), + InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). + - For LeafNode, LeafNodeBool and LeafNodeMask - added + LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), + LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), + LeafNode::setValueOffUnsafe(). + + ABI changes: + - Tree::leafCount(), Tree::unallocatedLeafCount(), + Tree::nonLeafCount() and Tree::nodeCount() now use Index64 in their + return types instead of Index32. API Changes: - RootNode::tileCount(), RootNode::activeTileCount() and RootNode::inactiveTileCount() are now public. - RootNode::hasKey() and RootNode::coordToKey() are now public. + - RootNode::leafCount(), RootNode::nonLeafCount() and RootNode::nodeCount() + now use Index64 instead of Index32. The Index32 variant is deprecated. + - InternalNode::leafCount(), InternalNode::nonLeafCount() and + InternalNode::nodeCount() now use Index64 instead of Index32. The Index32 + variant is deprecated. + - LeafNode::leafCount() and LeafNode::nonLeafCount() now use Index64 instead + of Index32. The Index32 variant is deprecated. Bug Fixes: - Fix potential crash reading corrupt .vdb files with invalid @@ -549,7 +598,6 @@ Version 9.1.0 - June 9, 2022 Positional arguments as input files are deprecated. - Added tools::minMax() which supports multithreaded evaluation of active minimum and maximum values. Grid::evalMinMax() has been deprecated. - [Contributed by Greg Hurst] - Significant performance improvements to AX point kernels, primarily due to providing AX access to attribute buffers for superior code generation. - vdb_print now prints both the in-core memory and total memory usage for diff --git a/doc/changes.txt b/doc/changes.txt index 0987ed107e..308bfcad55 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -6,16 +6,33 @@ @par Version 12.0.0 - October 31, 2024 +@par +
+This version introduces ABI changes relative to older major releases, so to +preserve ABI compatibility it might be necessary to define the macro +OPENVDB_ABI_VERSION_NUMBER=N, where, for example, +N is 10 for Houdini 20.0 and 11 for Houdini 20.5. +
+ +
+GCC 9 is no longer supported. +
+ @par OpenVDB: - Improvements: + New features: + - Added fillet() method in tools::LevelSetFilter to round off concave edges + to create smoother transition between surfaces. + + Improvements: - Added openvdb::assertAbort to replace cassert and a - OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle + @c OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle assertions in OpenVDB code, independantly of NDEBUG. Asserts are no longer enabled by default in when NDEBUG is absent (e.g. Debug builds). - - Removed last traces of Boost when OPENVDB_USE_DELAYED_LOADING is OFF - [Reported by Brian McKinnon] + - Removed last traces of Boost when @c OPENVDB_USE_DELAYED_LOADING is OFF + [Reported by Brian McKinnon] - RootNode code cleanup to eliminate redundant key conversion and to create map values in-place. - Add RootNode::deleteChildOrTile() to delete a child or tile of @@ -23,22 +40,61 @@ OpenVDB: - ValueAccessors are now defined and created in the Tree class instead of in the Grid class so that custom Tree implementations may define and create their own ValueAccessors if desired. - -- API Changes: + - Added support for PDAL to vdb_tool [Contributed by Tom Matterson] + - LeafManager and NodeManager now use Index64 for leaf counts internally. + - Added RootNode::probeChild() const. + - Added RootNode::probeChild() and RootNode::probeConstChild(). + - Added RootNode::probe() and RootNode::probeConst() to query key presence, + child node, value and active state. + - Added InternalNode::probeChild() const. + - Added InternalNode::probeChild() and probeChildConst() with coord access + and optionally value and active state. + - Added InternalNode::probeChild() and probeChildConst() with index access + and optionally value and active state. + - Added InternalNode::isValueOff(), LeafNode::isValueOff(), + LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). + - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). + - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), + RootNode::getConstChildUnsafe(). + - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), + InternalNode::getConstChildUnsafe(). + - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), + InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). + - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), + InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). + - For LeafNode, LeafNodeBool and LeafNodeMask - added + LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), + LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), + LeafNode::setValueOffUnsafe(). + + ABI changes: + - Tree::leafCount(), Tree::unallocatedLeafCount(), + Tree::nonLeafCount() and Tree::nodeCount() now use Index64 in their + return types instead of Index32. + + API Changes: - RootNode::tileCount(), RootNode::activeTileCount() and RootNode::inactiveTileCount() are now public. - RootNode::hasKey() and RootNode::coordToKey() are now public. - -- Bug Fixes: + - RootNode::leafCount(), RootNode::nonLeafCount() and RootNode::nodeCount() + now use Index64 instead of Index32. The Index32 variant is deprecated. + - InternalNode::leafCount(), InternalNode::nonLeafCount() and + InternalNode::nodeCount() now use Index64 instead of Index32. The Index32 + variant is deprecated. + - LeafNode::leafCount() and LeafNode::nonLeafCount() now use Index64 instead + of Index32. The Index32 variant is deprecated. + + Bug Fixes: - Fix potential crash reading corrupt .vdb files with invalid blosc or zip chunks. - [Fix thanks to Matthias Ueberheide] + [Reported by Matthias Ueberheide] + - Fix a bug in RootNode::setOrigin() where the origin was updated before the error was thrown potentially leaving the root in an invalid state. - Fixed a thread sanitizer issue which could cause undefined behaviour in VolumeToSpheres::fillWithSpheres - [Reported by Jérémie Dumas] + [Reported by Jérémie Dumas] - Fixed an occurance of undefined behaviour in tools::activate (though this would typically not have manifested with any unintended behaviour) @@ -75,7 +131,7 @@ NanoVDB: - API Changes: - Change mapToGridType to toGridType. - Change mapToMagic to toMagic. - - Change CpuTimer.h to Timer.h. + - Change CpuTimer.h to Timer.h. - API Changes (details): - These APIs are now under the math namespace: Ray, DDA, HDDA, @@ -108,33 +164,33 @@ NanoVDB: - Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. - Move and rename nanovdb::CountOn to nanovdb::util::countOn. - - Move util/GridHandle.h to GridHandle.h. - - Move util/BuildGrid.h to tools/GridBuilder.h. - - Move util/GridBuilder.h to tools/GridBuilder.h. - - Move util/IO.h to io/IO.h. - - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. - - Move util/DitherLUT.h to math/DitherLUT.h. - - Move util/HDDA.h to math/HDDA.h. - - Move util/Ray.h to math/Ray.h. - - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. - - Move util/Stencils.h to nanovdb/math/Stencils.h. - - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. - - Move and rename util/Primitives.h to tools/CreatePrimitives.h. - - Move util/GridChecksum.h to tools/GridChecksum.h. - - Move util/GridStats.h to tools/GridStats.h. - - Move util/GridChecksum.h to tools/GridChecksum.h. - - Move util/GridValidator.h to tools/GridValidator.h. - - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. - - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. - - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. - - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. - - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. - - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. - - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. - - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. - - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. - - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. - - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. + - Move util/GridHandle.h to GridHandle.h. + - Move util/BuildGrid.h to tools/GridBuilder.h. + - Move util/GridBuilder.h to tools/GridBuilder.h. + - Move util/IO.h to io/IO.h. + - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. + - Move util/DitherLUT.h to math/DitherLUT.h. + - Move util/HDDA.h to math/HDDA.h. + - Move util/Ray.h to math/Ray.h. + - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. + - Move util/Stencils.h to nanovdb/math/Stencils.h. + - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. + - Move and rename util/Primitives.h to tools/CreatePrimitives.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridStats.h to tools/GridStats.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridValidator.h to tools/GridValidator.h. + - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. + - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. + - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. + - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. + - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. + - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. + - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. + - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. + - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. + - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. + - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. @par Python: @@ -145,7 +201,7 @@ Python: @par Houdini: - - When OPENVDB_ENABLE_RPATH is ON, the location of + - When @c OPENVDB_ENABLE_RPATH is ON, the location of libopenvdb_houdini is now added to the rpath of all Houdini dsos. @@ -153,11 +209,11 @@ Houdini: Build: - Fixed an issue with OpenVDB AX's CMake on Windows where the static and shared library targets would have the same name - [Reported by Nicholas Yue] - - USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default + [Reported by Nicholas Yue] + - @c USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default due to OOM linker issues. - Jemalloc is now the preferred allocator of choice on all - platforms when CONCURRENT_MALLOC is set to Auto. + platforms when @c CONCURRENT_MALLOC is set to Auto. - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB Windows static library. diff --git a/pendingchanges/levelset_fillet.txt b/pendingchanges/levelset_fillet.txt deleted file mode 100644 index ca96a9f009..0000000000 --- a/pendingchanges/levelset_fillet.txt +++ /dev/null @@ -1,2 +0,0 @@ -New Feature: -- Added fillet() method in tools::LevelSetFilter to round off concave edges to create smoother transition between surfaces. [Contributed by Greg Hurst] \ No newline at end of file diff --git a/pendingchanges/probe.txt b/pendingchanges/probe.txt deleted file mode 100644 index 0786474ffa..0000000000 --- a/pendingchanges/probe.txt +++ /dev/null @@ -1,10 +0,0 @@ -Improvements: - - Added RootNode::probeChild() const. - - Added RootNode::probeChild() and RootNode::probeConstChild(). - - Added RootNode::probe() and RootNode::probeConst() to query key presence, - child node, value and active state. - - Added InternalNode::probeChild() const. - - Added InternalNode::probeChild() and probeChildConst() with coord access - and optionally value and active state. - - Added InternalNode::probeChild() and probeChildConst() with index access - and optionally value and active state. diff --git a/pendingchanges/unsafe.txt b/pendingchanges/unsafe.txt deleted file mode 100644 index 9264bf36fd..0000000000 --- a/pendingchanges/unsafe.txt +++ /dev/null @@ -1,16 +0,0 @@ -Improvements: - - Added InternalNode::isValueOff(), LeafNode::isValueOff(), - LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). - - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). - - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), - RootNode::getConstChildUnsafe(). - - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), - InternalNode::getConstChildUnsafe(). - - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), - InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). - - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), - InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). - - For LeafNode, LeafNodeBool and LeafNodeMask - added - LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), - LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), - LeafNode::setValueOffUnsafe(). From 47b2b5223787dbf16caeb98e26265e04e4e3d05c Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 11:32:02 -0700 Subject: [PATCH 75/98] Add nanobind minimum version Signed-off-by: Dan Bailey --- cmake/config/OpenVDBVersions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/config/OpenVDBVersions.cmake b/cmake/config/OpenVDBVersions.cmake index a0ba4f2008..9973778c80 100644 --- a/cmake/config/OpenVDBVersions.cmake +++ b/cmake/config/OpenVDBVersions.cmake @@ -40,7 +40,7 @@ if(NOT DISABLE_DEPENDENCY_VERSION_CHECKS) set(MINIMUM_MSVC_VERSION 19.30) # 1928 (Visual Studio 2019 Version 16.8 + 16.9) set(MINIMUM_BOOST_VERSION 1.80) - set(MINIMUM_PYBIND_VERSION 2.9.1) + 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) From 7afbe2a7870587d6dafe21c876ea5c0ea018916e Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 11:33:07 -0700 Subject: [PATCH 76/98] Fix ABI=13 error message Signed-off-by: Dan Bailey --- openvdb/openvdb/openvdb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/openvdb.cc b/openvdb/openvdb/openvdb.cc index f1e3b79224..ee58883918 100644 --- a/openvdb/openvdb/openvdb.cc +++ b/openvdb/openvdb/openvdb.cc @@ -38,7 +38,7 @@ // OPENVDB_USE_FUTURE_ABI_=ON. #ifndef OPENVDB_USE_FUTURE_ABI_13 #if OPENVDB_ABI_VERSION_NUMBER == 13 - #error ABI = 12 is still in active development and has not been finalized, \ + #error ABI = 13 is still in active development and has not been finalized, \ CMake option OPENVDB_USE_FUTURE_ABI_13 suppresses this error #endif #endif From 785bed5625b55125bd7f2d1a5e5df312b0e78bd2 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 11:41:42 -0700 Subject: [PATCH 77/98] Fix some documentation formatting issues Signed-off-by: Dan Bailey --- doc/changes.txt | 354 ++++++++++++++++++++++++------------------------ 1 file changed, 177 insertions(+), 177 deletions(-) diff --git a/doc/changes.txt b/doc/changes.txt index 308bfcad55..357794cb03 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -14,208 +14,208 @@ preserve ABI compatibility it might be necessary to define the macro N is 10 for Houdini 20.0 and 11 for Houdini 20.5. +@par
GCC 9 is no longer supported.
@par OpenVDB: -- Improvements: - New features: - - Added fillet() method in tools::LevelSetFilter to round off concave edges - to create smoother transition between surfaces. - - Improvements: - - Added openvdb::assertAbort to replace cassert and a - @c OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle - assertions in OpenVDB code, independantly of NDEBUG. Asserts are - no longer enabled by default in when NDEBUG is absent (e.g. - Debug builds). - - Removed last traces of Boost when @c OPENVDB_USE_DELAYED_LOADING is OFF - [Reported by Brian McKinnon] - - RootNode code cleanup to eliminate redundant key conversion and - to create map values in-place. - - Add RootNode::deleteChildOrTile() to delete a child or tile of - the root node. - - ValueAccessors are now defined and created in the Tree class - instead of in the Grid class so that custom Tree implementations - may define and create their own ValueAccessors if desired. - - Added support for PDAL to vdb_tool [Contributed by Tom Matterson] - - LeafManager and NodeManager now use Index64 for leaf counts internally. - - Added RootNode::probeChild() const. - - Added RootNode::probeChild() and RootNode::probeConstChild(). - - Added RootNode::probe() and RootNode::probeConst() to query key presence, - child node, value and active state. - - Added InternalNode::probeChild() const. - - Added InternalNode::probeChild() and probeChildConst() with coord access - and optionally value and active state. - - Added InternalNode::probeChild() and probeChildConst() with index access - and optionally value and active state. - - Added InternalNode::isValueOff(), LeafNode::isValueOff(), - LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). - - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). - - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), - RootNode::getConstChildUnsafe(). - - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), - InternalNode::getConstChildUnsafe(). - - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), - InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). - - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), - InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). - - For LeafNode, LeafNodeBool and LeafNodeMask - added - LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), - LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), - LeafNode::setValueOffUnsafe(). - - ABI changes: - - Tree::leafCount(), Tree::unallocatedLeafCount(), - Tree::nonLeafCount() and Tree::nodeCount() now use Index64 in their - return types instead of Index32. - - API Changes: - - RootNode::tileCount(), RootNode::activeTileCount() and - RootNode::inactiveTileCount() are now public. - - RootNode::hasKey() and RootNode::coordToKey() are now public. - - RootNode::leafCount(), RootNode::nonLeafCount() and RootNode::nodeCount() - now use Index64 instead of Index32. The Index32 variant is deprecated. - - InternalNode::leafCount(), InternalNode::nonLeafCount() and - InternalNode::nodeCount() now use Index64 instead of Index32. The Index32 - variant is deprecated. - - LeafNode::leafCount() and LeafNode::nonLeafCount() now use Index64 instead - of Index32. The Index32 variant is deprecated. - - Bug Fixes: - - Fix potential crash reading corrupt .vdb files with invalid - blosc or zip chunks. - [Reported by Matthias Ueberheide] - - - Fix a bug in RootNode::setOrigin() where the origin was updated - before the error was thrown potentially leaving the root in an - invalid state. - - Fixed a thread sanitizer issue which could cause undefined - behaviour in VolumeToSpheres::fillWithSpheres - [Reported by Jérémie Dumas] - - Fixed an occurance of undefined behaviour in tools::activate - (though this would typically not have manifested with any - unintended behaviour) + New features: + - Added tools::LevelSetFilter::fillet() method to round off concave edges + to create smoother transition between surfaces. + + Improvements: + - Added openvdb::assertAbort to replace cassert and a + @c OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle + assertions in OpenVDB code, independantly of NDEBUG. Asserts are + no longer enabled by default in when NDEBUG is absent (e.g. + Debug builds). + - Removed last traces of Boost when @c OPENVDB_USE_DELAYED_LOADING is OFF + [Reported by Brian McKinnon] + - RootNode code cleanup to eliminate redundant key conversion and + to create map values in-place. + - Add RootNode::deleteChildOrTile() to delete a child or tile of + the root node. + - ValueAccessors are now defined and created in the Tree class + instead of in the Grid class so that custom Tree implementations + may define and create their own ValueAccessors if desired. + - Added support for PDAL to vdb_tool [Contributed by Tom Matterson] + - LeafManager and NodeManager now use Index64 for leaf counts internally. + - Added RootNode::probeChild() const. + - Added RootNode::probeChild() and RootNode::probeConstChild(). + - Added RootNode::probe() and RootNode::probeConst() to query key presence, + child node, value and active state. + - Added InternalNode::probeChild() const. + - Added InternalNode::probeChild() and probeChildConst() with coord access + and optionally value and active state. + - Added InternalNode::probeChild() and probeChildConst() with index access + and optionally value and active state. + - Added InternalNode::isValueOff(), LeafNode::isValueOff(), + LeafNodeBool::isValueOff(), LeafNodeMask::isValueOff(). + - Added LeafNodeMask::probeValue(Index,val), LeafNodeBool::probeValue(Index,val). + - Added RootNode::getValueUnsafe(), RootNode::getChildUnsafe(), + RootNode::getConstChildUnsafe(). + - Added InternalNode::getValueUnsafe(), InternalNode::getChildUnsafe(), + InternalNode::getConstChildUnsafe(). + - Added InternalNode::setActiveStateUnsafe(), InternalNode::setValueOnlyUnsafe(), + InternalNode::setValueOnUnsafe(), InternalNode::setValueOffUnsafe(). + - Added InternalNode::setChildUnsafe(), InternalNode::resetChildUnsafe(), + InternalNode::stealChildUnsafe(), InternalNode::deleteChildUnsafe(). + - For LeafNode, LeafNodeBool and LeafNodeMask - added + LeafNode::getValueUnsafe(), LeafNode::setActiveStateunsafe(), + LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), + LeafNode::setValueOffUnsafe(). + + ABI changes: + - Tree::leafCount(), Tree::unallocatedLeafCount(), + Tree::nonLeafCount() and Tree::nodeCount() now use Index64 in their + return types instead of Index32. + + API Changes: + - RootNode::tileCount(), RootNode::activeTileCount() and + RootNode::inactiveTileCount() are now public. + - RootNode::hasKey() and RootNode::coordToKey() are now public. + - RootNode::leafCount(), RootNode::nonLeafCount() and RootNode::nodeCount() + now use Index64 instead of Index32. The Index32 variant is deprecated. + - InternalNode::leafCount(), InternalNode::nonLeafCount() and + InternalNode::nodeCount() now use Index64 instead of Index32. The Index32 + variant is deprecated. + - LeafNode::leafCount() and LeafNode::nonLeafCount() now use Index64 instead + of Index32. The Index32 variant is deprecated. + + Bug Fixes: + - Fix potential crash reading corrupt .vdb files with invalid + blosc or zip chunks. + [Reported by Matthias Ueberheide] + + - Fix a bug in RootNode::setOrigin() where the origin was updated + before the error was thrown potentially leaving the root in an + invalid state. + - Fixed a thread sanitizer issue which could cause undefined + behaviour in VolumeToSpheres::fillWithSpheres + [Reported by Jérémie Dumas] + - Fixed an occurance of undefined behaviour in tools::activate + (though this would typically not have manifested with any + unintended behaviour) @par NanoVDB: - Bug fix: - - nanovdb::readGrids works with raw grid buffer. + - nanovdb::readGrids works with raw grid buffer. - Improvements: - - Restructure files location and namespace to be more align with - OpenVDB. The namespaces touched by the restructuring are: io, - cuda, util, tools, and math. - - Add two scripts updateFiles.sh and updateFiles.py to update the - files using NanoVDB. The script updateFiles.py works on both - Windows and Linux. For a more complete list of changes, see API - Changes (details). - - - cuda::PointsToGrid supports target density. - - Add support for NanoVDB Grid of type UInt8. - - Add ability to use externally managed CUDA buffer. - - Add create methods for CudaDeviceBuffer and exceptions. - - Improve GridValidator logic, e.g. include check for grid count. - - Add operator > and >= for class Coord according to lexicographical order. - - Add toCodec to convert string to Codec enumeration type. - - Add nanovdb::strlen(). - - Add strncpy util. - - Add NANOVDB_DISABLE_SYNC_CUDA_MALLOC that maps cudaMallocAsync - and cudaFreeAsync to cudaMalloc and cudaFree respectively. - - Add guard to UINT64_C. - - Remove use of cudaMallocAsync in PointsToGrid.cuh. - - Align PNanoVDB blind metadata to NanoVDB. + - Restructure files location and namespace to be more align with + OpenVDB. The namespaces touched by the restructuring are: io, + cuda, util, tools, and math. + - Add two scripts updateFiles.sh and updateFiles.py to update the + files using NanoVDB. The script updateFiles.py works on both + Windows and Linux. For a more complete list of changes, see API + Changes (details). + + - cuda::PointsToGrid supports target density. + - Add support for NanoVDB Grid of type UInt8. + - Add ability to use externally managed CUDA buffer. + - Add create methods for CudaDeviceBuffer and exceptions. + - Improve GridValidator logic, e.g. include check for grid count. + - Add operator > and >= for class Coord according to lexicographical order. + - Add toCodec to convert string to Codec enumeration type. + - Add nanovdb::strlen(). + - Add strncpy util. + - Add @c NANOVDB_DISABLE_SYNC_CUDA_MALLOC that maps cudaMallocAsync + and cudaFreeAsync to cudaMalloc and cudaFree respectively. + - Add guard to @c UINT64_C. + - Remove use of cudaMallocAsync in PointsToGrid.cuh. + - Align PNanoVDB blind metadata to NanoVDB. - API Changes: - - Change mapToGridType to toGridType. - - Change mapToMagic to toMagic. - - Change CpuTimer.h to Timer.h. + - Change mapToGridType to toGridType. + - Change mapToMagic to toMagic. + - Change CpuTimer.h to Timer.h. - API Changes (details): - - These APIs are now under the math namespace: 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. - - - These APIs are now under the tools namespace: createNanoGrid, - StatsMode, createLevelSetSphere, createFogVolumeSphere, - createFogVolumeSphere, createFogVolumeSphere, - createFogVolumeTorus, createLevelSetBox, CreateNanoGrid, - updateGridStats, evalChecksum, validateChecksum, checkGrid, - Extrema. - - These APIs are now under the util namespace: is_floating_point, - findLowestOn, findHighestOn, Range, streq, strcpy, strcat, - empty, Split, invoke, forEach, reduce, prefixSum, is_same, - is_specialization, PtrAdd, PtrDiff. - - - Move nanovdb::build to nanovdb::tools::build. - - Rename nanovdb::BBoxR to nanovdb::Vec3dBBox. - - Rename nanovdb::BBox to nanovdb::Vec3dBbox. - - Move nanovdb::cudaCreateNodeManager to nanovdb::cuda::createNodeManager. - - Move and rename nanovdb::cudaVoxelsToGrid to nanovdb::cuda::voxelsToGrid. - - Move and rename nanovdb::cudaPointsToGrid to nanovdb::cuda::pointsToGrid. - - Move nanovdb::DitherLUT to nanovdb::math::DitherLUT. - - Move and rename nanovdb::PackedRGBA8 to nanovdb::math::Rgba8. - - Move nanovdb::Rgba8 to nanovdb::math::Rgba8. - - Move and rename nanovdb::CpuTimer to nanovdb::util::Timer. - - Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. - - Move and rename nanovdb::CountOn to nanovdb::util::countOn. - - - Move util/GridHandle.h to GridHandle.h. - - Move util/BuildGrid.h to tools/GridBuilder.h. - - Move util/GridBuilder.h to tools/GridBuilder.h. - - Move util/IO.h to io/IO.h. - - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. - - Move util/DitherLUT.h to math/DitherLUT.h. - - Move util/HDDA.h to math/HDDA.h. - - Move util/Ray.h to math/Ray.h. - - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. - - Move util/Stencils.h to nanovdb/math/Stencils.h. - - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. - - Move and rename util/Primitives.h to tools/CreatePrimitives.h. - - Move util/GridChecksum.h to tools/GridChecksum.h. - - Move util/GridStats.h to tools/GridStats.h. - - Move util/GridChecksum.h to tools/GridChecksum.h. - - Move util/GridValidator.h to tools/GridValidator.h. - - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. - - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. - - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. - - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. - - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. - - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. - - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. - - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. - - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. - - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. - - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. + - These APIs are now under the math namespace: 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. + + - These APIs are now under the tools namespace: createNanoGrid, + StatsMode, createLevelSetSphere, createFogVolumeSphere, + createFogVolumeSphere, createFogVolumeSphere, + createFogVolumeTorus, createLevelSetBox, CreateNanoGrid, + updateGridStats, evalChecksum, validateChecksum, checkGrid, + Extrema. + - These APIs are now under the util namespace: is_floating_point, + findLowestOn, findHighestOn, Range, streq, strcpy, strcat, + empty, Split, invoke, forEach, reduce, prefixSum, is_same, + is_specialization, PtrAdd, PtrDiff. + + - Move nanovdb::build to nanovdb::tools::build. + - Rename nanovdb::BBoxR to nanovdb::Vec3dBBox. + - Rename nanovdb::BBox to nanovdb::Vec3dBbox. + - Move nanovdb::cudaCreateNodeManager to nanovdb::cuda::createNodeManager. + - Move and rename nanovdb::cudaVoxelsToGrid to nanovdb::cuda::voxelsToGrid. + - Move and rename nanovdb::cudaPointsToGrid to nanovdb::cuda::pointsToGrid. + - Move nanovdb::DitherLUT to nanovdb::math::DitherLUT. + - Move and rename nanovdb::PackedRGBA8 to nanovdb::math::Rgba8. + - Move nanovdb::Rgba8 to nanovdb::math::Rgba8. + - Move and rename nanovdb::CpuTimer to nanovdb::util::Timer. + - Move nanovdb::GpuTimer to nanovdb::util::cuda::Timer. + - Move and rename nanovdb::CountOn to nanovdb::util::countOn. + + - Move util/GridHandle.h to GridHandle.h. + - Move util/BuildGrid.h to tools/GridBuilder.h. + - Move util/GridBuilder.h to tools/GridBuilder.h. + - Move util/IO.h to io/IO.h. + - Move util/CSampleFromVoxels.h to math/CSampleFromVoxels.h. + - Move util/DitherLUT.h to math/DitherLUT.h. + - Move util/HDDA.h to math/HDDA.h. + - Move util/Ray.h to math/Ray.h. + - Move util/SampleFromVoxels.h to math/SampleFromVoxels.h. + - Move util/Stencils.h to nanovdb/math/Stencils.h. + - Move util/CreateNanoGrid.h to tools/CreateNanoGrid.h. + - Move and rename util/Primitives.h to tools/CreatePrimitives.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridStats.h to tools/GridStats.h. + - Move util/GridChecksum.h to tools/GridChecksum.h. + - Move util/GridValidator.h to tools/GridValidator.h. + - Move util/NanoToOpenVDB.h to tools/NanoToOpenVDB.h. + - Move util/cuda/CudaGridChecksum.cuh to tools/cuda/CudaGridChecksum.cuh. + - Move util/cuda/CudaGridStats.cuh to tools/cuda/CudaGridStats.cuh. + - Move util/cuda/CudaGridValidator.cuh to tools/cuda/CudaGridValidator.cuh. + - Move util/cuda/CudaIndexToGrid.cuh to tools/cuda/CudaIndexToGrid.cuh. + - Move and rename util/cuda/CudaPointsToGrid.cuh to tools/cuda/PointsToGrid.cuh. + - Move util/cuda/CudaSignedFloodFill.cuh to tools/cuda/CudaSignedFloodFill.cuh. + - Move and rename util/cuda/CudaDeviceBuffer.h to cuda/DeviceBuffer.h. + - Move and rename util/cuda/CudaGridHandle.cuh to cuda/GridHandle.cuh. + - Move and rename util/cuda/CudaUtils.h to util/cuda/Util.h. + - Move and consolidate util/cuda/GpuTimer.h to util/cuda/Timer.h. @par Python: - - OpenVDB Python bindings are now implemented using nanobind - instead of pybind11 - - The OpenVDB Python module has been changed from pyopenvdb to openvdb - - Added Python bindings for NanoVDB + - OpenVDB Python bindings are now implemented using nanobind + instead of pybind11 + - The OpenVDB Python module has been changed from pyopenvdb to openvdb + - Added Python bindings for NanoVDB @par Houdini: - - When @c OPENVDB_ENABLE_RPATH is ON, the location of - libopenvdb_houdini is now added to the rpath of all Houdini - dsos. + - When @c OPENVDB_ENABLE_RPATH is @c ON, the location of + libopenvdb_houdini is now added to the rpath of all Houdini + dsos. @par Build: - - Fixed an issue with OpenVDB AX's CMake on Windows where the - static and shared library targets would have the same name - [Reported by Nicholas Yue] - - @c USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default - due to OOM linker issues. - - Jemalloc is now the preferred allocator of choice on all - platforms when @c CONCURRENT_MALLOC is set to Auto. - - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB - Windows static library. + - Fixed an issue with OpenVDB AX's CMake on Windows where the + static and shared library targets would have the same name + [Reported by Nicholas Yue] + - @c USE_EXPLICIT_INSTANTIATION is now disabled on Windows by default + due to OOM linker issues. + - Jemalloc is now the preferred allocator of choice on all + platforms when @c CONCURRENT_MALLOC is set to Auto. + - Fixed an issue with the Blosc CMake FindPackage for the OpenVDB + Windows static library. @htmlonly @endhtmlonly From bd86b3781c8c1e25155d98253b6a854c5c369a9a Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 12:01:51 -0700 Subject: [PATCH 78/98] Revert nanobind minimum version, more cleanup and refined future versions Signed-off-by: Dan Bailey --- cmake/OpenVDBGLFW3Setup.cmake | 12 ------------ cmake/config/OpenVDBVersions.cmake | 10 +++++++--- doc/dependencies.txt | 2 +- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/cmake/OpenVDBGLFW3Setup.cmake b/cmake/OpenVDBGLFW3Setup.cmake index 21ae81bb4c..26980fc6ff 100644 --- a/cmake/OpenVDBGLFW3Setup.cmake +++ b/cmake/OpenVDBGLFW3Setup.cmake @@ -109,18 +109,6 @@ endif() set(glfw3_FIND_VERSION ${MINIMUM_GLFW_VERSION}) find_package(glfw3 ${MINIMUM_GLFW_VERSION} REQUIRED) -# We only use find_package_handle_standard_args to verify and print -# appropriate messages. This now explicitly errors in 3.19... -# @todo Improve this entire GLFW3 search -# https://gitlab.kitware.com/cmake/cmake/-/issues/21505 -if(${CMAKE_VERSION} VERSION_LESS 3.19) - find_package(PackageHandleStandardArgs) - find_package_handle_standard_args(glfw3 - REQUIRED_VARS glfw3_DIR glfw3_FOUND - VERSION_VAR glfw3_VERSION - ) -endif() - 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} " diff --git a/cmake/config/OpenVDBVersions.cmake b/cmake/config/OpenVDBVersions.cmake index 9973778c80..0b8dd5ef6a 100644 --- a/cmake/config/OpenVDBVersions.cmake +++ b/cmake/config/OpenVDBVersions.cmake @@ -40,7 +40,10 @@ if(NOT DISABLE_DEPENDENCY_VERSION_CHECKS) set(MINIMUM_MSVC_VERSION 19.30) # 1928 (Visual Studio 2019 Version 16.8 + 16.9) set(MINIMUM_BOOST_VERSION 1.80) - set(MINIMUM_NANOBIND_VERSION 2.0.0) + # 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) @@ -70,15 +73,16 @@ endif() # set(FUTURE_MINIMUM_ICC_VERSION 19) # set(FUTURE_MINIMUM_CXX_STANDARD 20) -set(FUTURE_MINIMUM_CMAKE_VERSION 3.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 13.0.0) +set(FUTURE_MINIMUM_LLVM_VERSION 15.0.0) diff --git a/doc/dependencies.txt b/doc/dependencies.txt index 2ea810e5ea..041fb834c0 100644 --- a/doc/dependencies.txt +++ b/doc/dependencies.txt @@ -70,7 +70,7 @@ LLVM | 13.0.0 | 15.0.0* | Target-independent code generation 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 | Latest | C++/python bindings | Y | Y | https://nanobind.readthedocs.io +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 From 94fcd865c4a1cd9eeee37e90261e51848d52b1ad Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 12:03:49 -0700 Subject: [PATCH 79/98] More docs formatting fixes Signed-off-by: Dan Bailey --- doc/changes.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/changes.txt b/doc/changes.txt index 357794cb03..520a029f56 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -21,11 +21,11 @@ GCC 9 is no longer supported. @par OpenVDB: - New features: +- New features: - Added tools::LevelSetFilter::fillet() method to round off concave edges to create smoother transition between surfaces. - Improvements: +- Improvements: - Added openvdb::assertAbort to replace cassert and a @c OPENVDB_ENABLE_ASSERTS cmake argument/compile define to toggle assertions in OpenVDB code, independantly of NDEBUG. Asserts are @@ -67,12 +67,12 @@ OpenVDB: LeafNode::setValueOnlyUnsafe(), LeafNode::setValueOnUnsafe(), LeafNode::setValueOffUnsafe(). - ABI changes: +- ABI changes: - Tree::leafCount(), Tree::unallocatedLeafCount(), Tree::nonLeafCount() and Tree::nodeCount() now use Index64 in their return types instead of Index32. - API Changes: +- API Changes: - RootNode::tileCount(), RootNode::activeTileCount() and RootNode::inactiveTileCount() are now public. - RootNode::hasKey() and RootNode::coordToKey() are now public. @@ -84,7 +84,7 @@ OpenVDB: - LeafNode::leafCount() and LeafNode::nonLeafCount() now use Index64 instead of Index32. The Index32 variant is deprecated. - Bug Fixes: +- Bug Fixes: - Fix potential crash reading corrupt .vdb files with invalid blosc or zip chunks. [Reported by Matthias Ueberheide] From c6161d7c678d539127913ba0fc58b78bbc0d9eb2 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 13:07:38 -0700 Subject: [PATCH 80/98] Add a note to the change log about the re-licensing Signed-off-by: Dan Bailey --- CHANGES | 2 ++ doc/changes.txt | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/CHANGES b/CHANGES index f15d035aa5..41166b30d5 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ OpenVDB Version History Version 12.0.0 - October 31, 2024 + OpenVDB is now licensed under the Apache 2.0 license, instead of the MPL 2.0 license. + This version introduces ABI changes relative to older major releases, so to preserve ABI compatibility it might be necessary to define the macro OPENVDB_ABI_VERSION_NUMBER=N, where, for example, N is 10 for diff --git a/doc/changes.txt b/doc/changes.txt index 520a029f56..11c40c0c1e 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -6,6 +6,11 @@ @par Version 12.0.0 - October 31, 2024 +@par +
+OpenVDB is now licensed under the Apache 2.0 license, instead of the MPL 2.0 license. +
+ @par
This version introduces ABI changes relative to older major releases, so to From 700390df40f347f5818a473d3c1bcc943edb2ffd Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 13:16:01 -0700 Subject: [PATCH 81/98] A few minor docs updates Signed-off-by: Dan Bailey --- doc/build.txt | 4 +--- doc/codingstyle.txt | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/build.txt b/doc/build.txt index 3048731a55..81be6e1a68 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -238,10 +238,8 @@ it's a good idea to read the above section on DCC | Supported Version | OpenVDB ABI | -------- | ----------------- | ----------- | -Houdini | 19.5 | 9 | Houdini | 20.0 | 10 | -Maya | 2018 | Any | -Maya | 2019 | Any | +Houdini | 20.5 | 11 | @subsection buildBuildHou Building Against Houdini diff --git a/doc/codingstyle.txt b/doc/codingstyle.txt index 2a9a60aaf9..6f298e83e7 100644 --- a/doc/codingstyle.txt +++ b/doc/codingstyle.txt @@ -7,7 +7,7 @@ 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@gmail.com. +clarified, changed, or added, please send a note to openvdb-dev@lists.aswf.io. @section sStyleContents Contents From c0197d2e395c1d050e56ce79cfab0f19f3ef01c3 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 13:16:52 -0700 Subject: [PATCH 82/98] A few small docs updates Signed-off-by: Dan Bailey --- doc/build.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/doc/build.txt b/doc/build.txt index 81be6e1a68..c04e870aa3 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -605,13 +605,6 @@ OpenVDB uses [imported targets](https://cmake.org/cmake/help/latest/command/add_ for all its dependencies. For imported Boost compatibility, the following versions of CMake are required: - - Boost 1.73 requires CMake 3.17.2 or newer. - - Boost 1.74 requires CMake 3.19 or newer. - - Boost 1.75 requires CMake 3.19.5 or newer. - - Boost 1.76 requires CMake 3.20.3 or newer. - - Boost 1.77 requires CMake 3.21.3 or newer. - - Boost 1.78 requires CMake 3.22.2 or newer. - - Boost 1.79 requires CMake 3.23.2 or newer. - 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. From 269300808a4651daa65836214fc20f78e1c0eb7f Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Thu, 31 Oct 2024 15:58:05 -0700 Subject: [PATCH 83/98] Add LLVM 13 back into AX matrix Signed-off-by: Dan Bailey --- .github/workflows/ax.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ax.yml b/.github/workflows/ax.yml index e8ed06f5c4..83ac4500e7 100644 --- a/.github/workflows/ax.yml +++ b/.github/workflows/ax.yml @@ -120,9 +120,9 @@ jobs: strategy: matrix: config: - #@note llvm15 never got its own brew formula... - # Last macos runner befor M1 (macos-14) + # 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 From 79d056ce42863d9667b552f99bfb5f1c65ba9825 Mon Sep 17 00:00:00 2001 From: Dan Bailey <5251654+danrbailey@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:35:52 -0700 Subject: [PATCH 84/98] Bump to v12.0.1 (#1960) Signed-off-by: Dan Bailey --- CHANGES | 2 ++ CMakeLists.txt | 2 +- doc/changes.txt | 6 +++++- pyproject.toml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 41166b30d5..ca2d030a4e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ OpenVDB Version History ======================= +Version 12.0.1 - In development + Version 12.0.0 - October 31, 2024 OpenVDB is now licensed under the Apache 2.0 license, instead of the MPL 2.0 license. diff --git a/CMakeLists.txt b/CMakeLists.txt index 34df1309df..e17ee726b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ endif() set(OpenVDB_MAJOR_VERSION 12) set(OpenVDB_MINOR_VERSION 0) -set(OpenVDB_PATCH_VERSION 0) +set(OpenVDB_PATCH_VERSION 1) set(OpenVDB_VERSION "${OpenVDB_MAJOR_VERSION}.${OpenVDB_MINOR_VERSION}.${OpenVDB_PATCH_VERSION}") project(OpenVDB LANGUAGES CXX VERSION ${OpenVDB_VERSION}) diff --git a/doc/changes.txt b/doc/changes.txt index 11c40c0c1e..1ed11d5f11 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -2,7 +2,11 @@ @page changes Release Notes -@htmlonly @endhtmlonly +@htmlonly @endhtmlonly +@par +Version 12.0.1 - In development + +@htmlonly @endhtmlonly @par Version 12.0.0 - October 31, 2024 diff --git a/pyproject.toml b/pyproject.toml index ea644a7831..b42bcd5c80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "openvdb" -version = "12.0.0" +version = "12.0.1" description= "Python bindings for OpenVDB: sparse volume data structure and tools." dependencies = [ "numpy", From a692c44df76aa7020c41097bc5716abdc2e81693 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:42:36 -0500 Subject: [PATCH 85/98] Create 2024-11-05.md Meeting notes from 2024-11-05. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- tsc/meetings/2024-11-05.md | 98 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tsc/meetings/2024-11-05.md diff --git a/tsc/meetings/2024-11-05.md b/tsc/meetings/2024-11-05.md new file mode 100644 index 0000000000..4aa80c99c5 --- /dev/null +++ b/tsc/meetings/2024-11-05.md @@ -0,0 +1,98 @@ +Minutes from OpenVDB TSC meeting, October 29th, 2024 + +Attendees: *Ken* M., *Andre* P, *Dan* B., *Greg* H, *Nick* A. + +Additional Attendees: Jonathan Swartz (NVIDIA), Barry Dempsey + +Regrets: *Jeff* L., *Richard* J. + +Agenda: + +1) Confirm quorum +2) Secretary +3) Meeting Times +4) V12 post mortum +5) 12.1 release +6) File format updates +7) Dilation + +------------ + +1) Confirm quorum + +Quorum is present. + +2) Secretary + +Secretary is Greg Hurst. + +3) Meeting Times + +Tentativley we'd like to move meetings to Wednesdays at 11:00 PST if we get a buy in from Jeff and Rich. + +4) V12 post mortum + +Release wasn't too bad -- getting CI in order was a bit of work but started a bit early. + +Having a X.1, X.2, etc. release there would be less of a squeeze for new features. + +Ken: perhaps 3 releases per year, including the major release. + +Nick: Would be nice if we could be in a place where patch releases are simple whenever there's a new feature. This means we can't put anything into master unless we're completely happy with it. We also need to make sure that the weekly tests are always in working order and when a failure happens, we need to address ASAP. + +CI could be more complicated once we start adding GPU's into the mix. + +Linux & Mac OS migrations have happenend and switching from bash to shell in Windows had made more stable. + +Chat groups can be much easier to manage the CI compared to emails, which we currently operate like. Perhaps Slack or Google chat? + +Ken: Could Nick add documentation or a presentation about the current CI? It's complex and a bit intimidating right now. + +Porting AX tests to GTest from CPPTest can help a bit with CI. + +5) 12.1 release + +March 1, 2025 release? + +* Tubes + Dilated Meshes +* HalfGrid +* Large Nano updates + +6) File format updates + +Migrate away from Blosc in favor from LZ4? + +Blosc brings a lot of compression codecs with it, so we could precondition ourselves and then just bring in LZ4. + +7) Dilation + +Dan presents on dilation -- noticed serial dilation was faster when making volume advection calls + +Active ideas of how we can speed up the multithreaded code. + +Vague description: + +Current: dilate into multiple grids then merge +Future: create 1 grid and dilate into it, parallelize over internal nodes directly above leaf nodes + +1. Partial Topology Copy, turn dense leaf nodes into active tiles +2. Node dilation, iterate over leafs and touch leaf neighbors +3. Mask dilation, scatter method but make sure you're not writing to the same leaf node at the same time. Split into center, face, edge, and corner passes, so 4 passes instead of 7. Still does scattering over a copy of the data since multiple passes are used. +4. Prune tree + +Tentatively a ~4-5x speedup for 'dense-like' grids and ~2x speedup for higher SA/V grids. + +TODOs +* Topology Copy + * Skip Topology Copy and Re-use Input Topology +* Node Dilation + * Apply Center, Face, Edge, Corner Scheme + * Avoid Naive Root Children Dilation +* Mask Dilation + * Cache Neighboring Internal Nodes + * Thread Corner Cases + * Simplify Edge Cases + * Extend to NN_FACE_EDGE/NN_FACE_EDGE_VERTEX modes +* Testing + * Build Worst Case and Poorly Balanced Trees + * Multiple Iterations From 74ae69803002dd945c66a01c797fcccf96603380 Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Wed, 6 Nov 2024 12:38:48 -0500 Subject: [PATCH 86/98] Update 2024-11-05.md Some corrections suggested by Andre. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- tsc/meetings/2024-11-05.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tsc/meetings/2024-11-05.md b/tsc/meetings/2024-11-05.md index 4aa80c99c5..3ad3b8c5e4 100644 --- a/tsc/meetings/2024-11-05.md +++ b/tsc/meetings/2024-11-05.md @@ -1,4 +1,4 @@ -Minutes from OpenVDB TSC meeting, October 29th, 2024 +Minutes from OpenVDB TSC meeting, November 5th, 2024 Attendees: *Ken* M., *Andre* P, *Dan* B., *Greg* H, *Nick* A. @@ -10,11 +10,11 @@ Agenda: 1) Confirm quorum 2) Secretary -3) Meeting Times -4) V12 post mortum -5) 12.1 release -6) File format updates -7) Dilation +3) V12 post mortem +4) 12.1 release +5) File format updates +6) Dilation +7) Next meeting ------------ @@ -26,11 +26,7 @@ Quorum is present. Secretary is Greg Hurst. -3) Meeting Times - -Tentativley we'd like to move meetings to Wednesdays at 11:00 PST if we get a buy in from Jeff and Rich. - -4) V12 post mortum +3) V12 post mortem Release wasn't too bad -- getting CI in order was a bit of work but started a bit early. @@ -50,7 +46,7 @@ Ken: Could Nick add documentation or a presentation about the current CI? It's c Porting AX tests to GTest from CPPTest can help a bit with CI. -5) 12.1 release +4) 12.1 release March 1, 2025 release? @@ -58,13 +54,13 @@ March 1, 2025 release? * HalfGrid * Large Nano updates -6) File format updates +5) File format updates Migrate away from Blosc in favor from LZ4? Blosc brings a lot of compression codecs with it, so we could precondition ourselves and then just bring in LZ4. -7) Dilation +6) Dilation Dan presents on dilation -- noticed serial dilation was faster when making volume advection calls @@ -96,3 +92,9 @@ TODOs * Testing * Build Worst Case and Poorly Balanced Trees * Multiple Iterations + +7) Next meeting + +Tentativley we'd like to move meetings to Wednesdays at 11:00 PST if we get a buy in from Jeff and Rich. + +If this is the case, the next meeting is Wednesday Novermber 20, 2024 at 11:00 PST. From 7d44132801e4bb7d26e6fad8430f9c3de5072245 Mon Sep 17 00:00:00 2001 From: Ken Museth <1495380+kmuseth@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:24:18 -0800 Subject: [PATCH 87/98] added read/write support of OFF files to vdb_tool (#1971) * added read/write support of OFF files to vdb_tool Signed-off-by: Ken Museth * added pendingchanges/vdb_tool.txt Signed-off-by: Ken Museth * added patch from Jonathan S Signed-off-by: Ken Museth * minor cleanup Signed-off-by: Ken Museth * addressed review comments Signed-off-by: Ken Museth * before major improvements to readPLY Signed-off-by: Ken Museth * cleanup Signed-off-by: Ken Museth * removed whitespace Signed-off-by: Ken Museth * added nanovdb::vdb_tool::swapBytes Signed-off-by: Ken Museth * added more documentation Signed-off-by: Ken Museth * patch by Jonathan S to fix CI Signed-off-by: Ken Museth * Fix gtest install for rpm. not deb Signed-off-by: Jonathan Swartz * Building gtest from source; newer version required than available on distro Signed-off-by: Jonathan Swartz * permissions fix Signed-off-by: Jonathan Swartz * Attempting to fix doxygen node version issue Missing iomanip include in TestNanoVDB Signed-off-by: Jonathan Swartz * Bump container versions attempt to fix doxygen test Signed-off-by: Jonathan Swartz * install_latex fix Signed-off-by: Jonathan Swartz * added ascii option to Geometry::writePLY Signed-off-by: Ken Museth * fixing issue introduced in the previous commit Signed-off-by: Ken Museth --------- Signed-off-by: Ken Museth Signed-off-by: Jonathan Swartz Co-authored-by: Jonathan Swartz --- .github/workflows/ax.yml | 2 + .github/workflows/build.yml | 2 + .github/workflows/docs.yml | 11 +- .github/workflows/houdini.yml | 2 + .github/workflows/nanovdb.yml | 6 +- ci/build.sh | 1 + ci/install_gtest.sh | 16 ++ nanovdb/nanovdb/unittest/TestNanoVDB.cc | 1 + openvdb_cmd/vdb_tool/CMakeLists.txt | 5 +- openvdb_cmd/vdb_tool/README.md | 15 +- openvdb_cmd/vdb_tool/include/Geometry.h | 350 +++++++++++++----------- openvdb_cmd/vdb_tool/include/Tool.h | 50 ++-- openvdb_cmd/vdb_tool/include/Util.h | 25 ++ openvdb_cmd/vdb_tool/src/unittest.cpp | 131 ++++++--- pendingchanges/vdb_tool.txt | 1 + 15 files changed, 385 insertions(+), 233 deletions(-) create mode 100755 ci/install_gtest.sh create mode 100644 pendingchanges/vdb_tool.txt diff --git a/.github/workflows/ax.yml b/.github/workflows/ax.yml index 83ac4500e7..be512fbc2c 100644 --- a/.github/workflows/ax.yml +++ b/.github/workflows/ax.yml @@ -76,6 +76,8 @@ jobs: - 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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e7798e8fb..6d479e57a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,6 +89,8 @@ jobs: - 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 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1fff84b892..617ae20a12 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,12 +40,9 @@ jobs: 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:2022 + image: aswf/ci-openvdb:2024 steps: - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install_doxygen run: ./ci/install_doxygen.sh 1_8_11 - name: nanobind @@ -55,10 +52,6 @@ jobs: # run: pip install epydoc - name: install_latex run: | - # Fix error: Cannot prepare internal mirrorlist: No URLs in mirrorlist. CentOS 8 reached EOL means need to replace the official mirror to vault.centos.org - # Comment out mirrorlist and replace #baseurl=...mirror.centos.org with baseurl=...vault.centos.org in files starting with CentOS- in /etc/yum.repos.d folder - sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* - sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* yum -y install texlive-latex-bin texlive-dvips texlive-collection-fontsrecommended texlive-collection-latexrecommended - name: build run: > diff --git a/.github/workflows/houdini.yml b/.github/workflows/houdini.yml index 68348e3351..28efc703b8 100644 --- a/.github/workflows/houdini.yml +++ b/.github/workflows/houdini.yml @@ -93,6 +93,8 @@ jobs: 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 diff --git a/.github/workflows/nanovdb.yml b/.github/workflows/nanovdb.yml index 43b2c233d9..0efc4580a8 100644 --- a/.github/workflows/nanovdb.yml +++ b/.github/workflows/nanovdb.yml @@ -170,12 +170,12 @@ jobs: github.event.inputs.type == 'all' || github.event.inputs.type == 'linux' runs-on: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && 'ubuntu-20.04-8c-32g-300h') || 'ubuntu-latest' }} + container: + image: aswf/ci-openvdb:2024 steps: - uses: actions/checkout@v3 - name: install_gtest - run: | - sudo apt-get update - sudo apt-get -q install -y libgtest-dev + run: ./ci/install_gtest.sh 1.15.2 - name: build_and_test run: | cd nanovdb/nanovdb diff --git a/ci/build.sh b/ci/build.sh index b3b318d093..110455c881 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -189,6 +189,7 @@ cmake \ -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]} \ diff --git a/ci/install_gtest.sh b/ci/install_gtest.sh new file mode 100755 index 0000000000..71d7fbd7bb --- /dev/null +++ b/ci/install_gtest.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +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 diff --git a/nanovdb/nanovdb/unittest/TestNanoVDB.cc b/nanovdb/nanovdb/unittest/TestNanoVDB.cc index 7eacd07915..33e120c063 100644 --- a/nanovdb/nanovdb/unittest/TestNanoVDB.cc +++ b/nanovdb/nanovdb/unittest/TestNanoVDB.cc @@ -4,6 +4,7 @@ // Uncomment to temporarily disable testing of PNanoVDB //#define DISABLE_PNANOVDB +#include #include #include #include // for std::stringstream diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index da1ade24ca..c0a2d64277 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -26,7 +26,7 @@ list(APPEND CMAKE_MODULE_PATH ${OPENVDB_CMAKE_PATH}) add_library(vdb_tool_common INTERFACE) # Optional components -option(BUILD_TEST "Build unit tests" OFF) +option(OPENVDB_BUILD_VDB_TOOL_UNITTESTS "Build unit tests" OFF) option(OPENVDB_TOOL_USE_NANO "Compile with NanoVDB support" OFF) option(OPENVDB_TOOL_NANO_USE_ZIP "Compile NanoVDB with zip compression support. Requires OPENVDB_TOOL_USE_NANO=ON to have effect" ON) @@ -185,10 +185,11 @@ install(TARGETS vdb_tool RUNTIME DESTINATION ${OPENVDB_INSTALL_BINDIR}) # unit test -if(BUILD_TEST) +if(OPENVDB_BUILD_VDB_TOOL_UNITTESTS) find_package(GTest ${MINIMUM_GOOGLETEST_VERSION} CONFIG REQUIRED) add_executable(vdb_tool_test src/unittest.cpp) target_include_directories(vdb_tool_test PRIVATE vdb_tool_common) target_link_libraries(vdb_tool_test PRIVATE vdb_tool_common GTest::gmock GTest::gtest GTest::gmock_main GTest::gtest_main) + add_test(vdb_tool_unit_test vdb_tool_test) endif() diff --git a/openvdb_cmd/vdb_tool/README.md b/openvdb_cmd/vdb_tool/README.md index f64ebb6bea..23bb29066f 100644 --- a/openvdb_cmd/vdb_tool/README.md +++ b/openvdb_cmd/vdb_tool/README.md @@ -10,8 +10,8 @@ This command-line tool, dubbed vdb_tool, can combine any number of the of high-l | **eval** | Evaluate an expression written in our Reverse Polish Notation (see below) | | **config** | Load a configuration file and add the actions for processing | | **default** | Set default values used by all subsequent actions | -| **read** | Read mesh, points and level sets as obj, ply, abc, stl, pts, vdb or nvdb files | -| **write** | Write a polygon mesh, points or level set as a obj, ply, stl, abc or vdb file | +| **read** | Read mesh, points and level sets as obj, ply, abc, stl, off, pts, vdb or nvdb files | +| **write** | Write a polygon mesh, points or level set as a obj, ply, stl, off, abc or vdb file | | **vdb2points** | Extracts points from a VDB grid | | **mesh2ls** | Convert a polygon mesh to a narrow-band level set | | **points2ls** | Convert points into a narrow-band level set | @@ -59,9 +59,10 @@ For support, bug-reports or ideas for improvements please contact ken.museth@gma | Extension | Actions | Description | |-------|-------|-------| | vdb | read and write | OpenVDB sparse volume files with float, Vec3f and points | -| obj | read and write | ASCII OBJ mesh files with triangle, quad or points | -| ply | read and write | Binary and ASCII PLY mesh files with triangle, quad or points | +| obj | read and write | ASCII OBJ mesh files with triangles, quads or points | +| ply | read and write | Binary and ASCII PLY mesh files with triangles, quads or points | | stl | read and write | Binary STL mesh files with triangles | +| off | read and write | ASCI OFF mesh files with triangles, quads or points | | pts | read | ASCII PTS points files with one or more point clouds | | abc | optional read and write | Alembic binary mesh files | | nvdb| optional read and write | NanoVDB file with voxels or points | @@ -73,7 +74,7 @@ For support, bug-reports or ideas for improvements please contact ken.museth@gma # Terminology -We introduce terms: **actions**, **options**, **expressions**, and **instructions**. Actions are high-level openvdb tools, which each have unique options, e.g. -mesh2ls geo=1 voxel=0.1, where "-mesh2ls" is an action with two options "geo" and "voxel". Expressions are strings of code with one or more low-level instructions in our stack-based programming language (see below). These expressions start with "{" and ends with "}", and ":" is used to separate values and instructions. E.g. {1:2:+} is an expression with two values (1 and 2) and one instruction "+", and it reduces to the string value "3". See section on the "Stack-based string expressions" below for more details. +We introduce the following terms: **actions**, **options**, **expressions**, and **instructions**. Actions are high-level openvdb tools, which each have unique options, e.g. -mesh2ls geo=1 voxel=0.1, where "-mesh2ls" is an action with two options "geo" and "voxel". Expressions are strings of code with one or more low-level instructions in our stack-based programming language (see below). These expressions start with "{" and ends with "}", and ":" is used to separate values and instructions. E.g. {1:2:+} is an expression with two values (1 and 2) and one instruction "+", and it reduces to the string value "3". See section on the "Stack-based string expressions" below for more details. Note that **actions** always start with one or more "-" and (except for file names) its associated **options** always contain a "=" and an optional number of leading characters used for identification, e.g. "-erode r=2" is identical to "-erode radius=2.0", but "-erode rr=2" will produce an error since "rr" does not match the first two characters of any option associated with the action "erode". @@ -88,7 +89,7 @@ This tool supports its own light-weight stack-oriented programming language that This tool is using CMake for build on Linux and Windows. The only mandatory dependency of is [OpenVDB](http://www.openvdb.org). Optional dependencies include NanoVDB, libpng, libjpeg, OpenEXR, and Alembic. To enable them use the `-DUSE_=ON` flags. See the CMakeLists.txt for details. -The included unit test are using Gtest. Add `-DBUILD_TEST=ON` to the cmake command line to build it. +The included unit test are using Gtest. Add `-DOPENVDB_BUILD_VDB_TOOL_UNITTESTS=ON` to the cmake command line to build it. ## Building OpenVDB @@ -102,7 +103,7 @@ To generate the makefile, navigate to the cloned directory of vdb_tool, then fol ```bash mkdir build cd build -cmake -DOPENVDB_CMAKE_PATH=/usr/local/lib/cmake/OpenVDB -DUSE_ALL=ON -DBUILD_TEST=ON .. +cmake -DOPENVDB_CMAKE_PATH=/usr/local/lib/cmake/OpenVDB -DUSE_ALL=ON -DOPENVDB_BUILD_VDB_TOOL_UNITTESTS=ON .. ``` Update the OpenVDB cmake path above as needed. diff --git a/openvdb_cmd/vdb_tool/include/Geometry.h b/openvdb_cmd/vdb_tool/include/Geometry.h index 2d6472dcde..ebd497b3bb 100644 --- a/openvdb_cmd/vdb_tool/include/Geometry.h +++ b/openvdb_cmd/vdb_tool/include/Geometry.h @@ -33,7 +33,7 @@ #ifdef VDB_TOOL_USE_NANO #include -#include +#include #endif #ifdef VDB_TOOL_USE_ABC @@ -66,6 +66,8 @@ OPENVDB_USE_VERSION_NAMESPACE namespace OPENVDB_VERSION_NAME { namespace vdb_tool { +#define MY_CLEAN_VERSION + /// @brief Class that encapsulates (explicit) geometry, i.e. vertices/points, /// triangles and quads. It is used to represent points and polygon meshes class Geometry @@ -104,17 +106,20 @@ class Geometry // Reads all the vertices in the file and treats them as Geometry void write(const std::string &fileName) const; void writeOBJ(const std::string &fileName) const; - void writePLY(const std::string &fileName) const; + void writeOFF(const std::string &fileName) const; + void writePLY(const std::string &fileName, bool binary = true) const; void writeSTL(const std::string &fileName) const; void writeGEO(const std::string &fileName) const; void writeABC(const std::string &fileName) const; void writeOBJ(std::ostream &os) const; - void writePLY(std::ostream &os) const; + void writeOFF(std::ostream &os) const; + void writePLY(std::ostream &os, bool binary = true) const; void writeSTL(std::ostream &os) const; void read(const std::string &fileName); void readOBJ(const std::string &fileName); + void readOFF(const std::string &fileName); void readPLY(const std::string &fileName); void readSTL(const std::string &fileName); void readPTS(const std::string &fileName); @@ -125,6 +130,7 @@ class Geometry void readNVDB(const std::string &fileName); void readOBJ(std::istream &is); + void readOFF(std::istream &is); void readPLY(std::istream &is); size_t vtxCount() const { return mVtx.size(); } @@ -229,7 +235,7 @@ const math::BBox& Geometry::bbox() const void Geometry::write(const std::string &fileName) const { - switch (findFileExt(fileName, {"geo", "obj", "ply", "stl", "abc"})) { + switch (findFileExt(fileName, {"geo", "obj", "ply", "stl", "abc", "off"})) { case 1: this->writeGEO(fileName); break; @@ -245,30 +251,33 @@ void Geometry::write(const std::string &fileName) const case 5: this->writeABC(fileName); break; + case 6: + this->writeOFF(fileName); + break; default: throw std::invalid_argument("Geometry file \"" + fileName + "\" has an invalid extension"); } }// Geometry::write -void Geometry::writePLY(const std::string &fileName) const +void Geometry::writePLY(const std::string &fileName, bool binary) const { if (fileName == "stdout.ply") { //if (isatty(fileno(stdout))) throw std::invalid_argument("writePLY: stdout is not connected to the terminal!"); - this->writePLY(std::cout); + this->writePLY(std::cout, binary); } else { std::ofstream outfile(fileName, std::ios_base::binary); if (!outfile.is_open()) throw std::invalid_argument("Error writing to ply file \""+fileName+"\""); - this->writePLY(outfile);; + this->writePLY(outfile, binary); } }// Geometry::writePLY -void Geometry::writePLY(std::ostream &os) const +void Geometry::writePLY(std::ostream &os, bool binary) const { - os << "ply\n"; - if (isLittleEndian()) { - os << "format binary_little_endian 1.0\n"; + os << "ply\nformat "; + if (binary) { + os << "binary_" << (isLittleEndian() ? "little" : "big") << "_endian 1.0\n"; } else { - os << "format binary_big_endian 1.0\n"; + os << "ascii 1.0\n"; } os << "comment created by vdb_tool" << std::endl; os << "element vertex " << mVtx.size() << std::endl; @@ -279,32 +288,26 @@ void Geometry::writePLY(std::ostream &os) const os << "property list uchar int vertex_index\n"; os << "end_header\n"; static_assert(sizeof(Vec3s) == 3 * sizeof(float), "Unexpected sizeof(Vec3s)"); - os.write((const char *)mVtx.data(), mVtx.size() * 3 * sizeof(float)); - if (mTri.size()>0) { - const size_t size = sizeof(char) + 3*sizeof(uint32_t); - char *buffer = static_cast(std::malloc(mTri.size()*size)), *p = buffer;// uninitialized - if (buffer==nullptr) throw std::invalid_argument("Geometry::writePLY: failed to allocate buffer"); - static_assert(sizeof(Vec3I) == 3 * sizeof(uint32_t), "Unexpected sizeof(Vec3I)"); - for (const Vec3I *t = mTri.data(), *e = t + mTri.size(); t!=e; ++t) { - *p = 3; - std::memcpy(p + 1, t, 3*sizeof(uint32_t)); - p += size; - } - os.write(buffer, mTri.size()*size); - std::free(buffer); - } - if (mQuad.size()>0) { - const size_t size = sizeof(char) + 4*sizeof(uint32_t); - char *buffer = static_cast(std::malloc(mQuad.size()*size)), *p = buffer;// uninitialized - if (buffer==nullptr) throw std::invalid_argument("Geometry::writePLY: failed to allocate buffer"); - static_assert(sizeof(Vec4I) == 4 * sizeof(uint32_t), "Unexpected sizeof(Vec4I)"); - for (const Vec4I *q = mQuad.data(), *e = q + mQuad.size(); q!=e; ++q) { - *p = 4; - std::memcpy(p + 1, q, 4*sizeof(uint32_t)); - p += size; - } - os.write(buffer, mQuad.size()*size); - std::free(buffer); + if (binary) { + os.write((const char *)mVtx.data(), mVtx.size() * 3 * sizeof(float));// write x,y,z vertex coordinates + auto writeFaces = [](std::ostream &os, const uint32_t *faces, size_t count, uint8_t n) { + if (count==0) return; + const int size = 1 + 4*n; + char *buffer = (char*)std::malloc(count*size), *p = buffer;// uninitialized + if (buffer==nullptr) throw std::invalid_argument("Geometry::writePLY: failed to allocate buffer"); + for (const uint32_t *f = faces, *e = f + n*count; f!=e; f+=n, p += size) { + *p = (char)n; + std::memcpy(p + 1, f, 4*n); + } + os.write(buffer, count*size); + std::free(buffer); + }; + writeFaces(os, (const uint32_t*)mTri.data(), mTri.size(), 3); + writeFaces(os, (const uint32_t*)mQuad.data(), mQuad.size(), 4); + } else {// ascii + for (auto &v : mVtx) os << v[0] << " " << v[1] << " " << v[2] << "\n"; + for (auto &t : mTri) os << "3 " << t[0] << " " << t[1] << " " << t[2] << "\n"; + for (auto &q : mQuad) os << "4 " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << "\n"; } }// Geometry::writePLY @@ -316,24 +319,38 @@ void Geometry::writeOBJ(const std::string &fileName) const } else { std::ofstream outfile(fileName); if (!outfile.is_open()) throw std::invalid_argument("Error writing to obj file \""+fileName+"\""); - this->writeOBJ(outfile);; + this->writeOBJ(outfile); } }// Geometry::writeOBJ void Geometry::writeOBJ(std::ostream &os) const { - os << "# Created by vdb_tool\n"; - for (auto &v : mVtx) { - os << "v " << v[0] << " " << v[1] << " " << v[2] << "\n"; - } - for (auto &t : mTri) { - os << "f " << t[0]+1 << " " << t[1]+1 << " " << t[2]+1 << "\n";// obj is 1-based - } - for (auto &q : mQuad) { - os << "f " << q[0]+1 << " " << q[1]+1 << " " << q[2]+1 << " " << q[3]+1 << "\n";// obj is 1-based - } + os << "# obj file created by vdb_tool\n"; + for (auto &v : mVtx) os << "v " << v[0] << " " << v[1] << " " << v[2] << "\n"; + for (auto &t : mTri) os << "f " << t[0]+1 << " " << t[1]+1 << " " << t[2]+1 << "\n";// obj is 1-based + for (auto &q : mQuad) os << "f " << q[0]+1 << " " << q[1]+1 << " " << q[2]+1 << " " << q[3]+1 << "\n";// obj is 1-based }// Geometry::writeOBJ +void Geometry::writeOFF(const std::string &fileName) const +{ + if (fileName=="stdout.off") { + this->writeOFF(std::cout); + } else { + std::ofstream outfile(fileName); + if (!outfile.is_open()) throw std::invalid_argument("Error writing to off file \""+fileName+"\""); + this->writeOFF(outfile); + } +}// Geometry::writeOFF + +void Geometry::writeOFF(std::ostream &os) const +{ + os << "OFF\n# Created by vdb_tool\n"; + os << mVtx.size() << " " << (mTri.size() + mQuad.size()) << " " << 0 << "\n"; + for (auto &v : mVtx) os << v[0] << " " << v[1] << " " << v[2] << "\n"; + for (auto &t : mTri) os << "3 " << t[0] << " " << t[1] << " " << t[2] << "\n"; + for (auto &q : mQuad) os << "4 " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << "\n"; +}// Geometry::writeOFF + void Geometry::writeSTL(const std::string &fileName) const { if (fileName == "stdout.stl") { @@ -342,7 +359,7 @@ void Geometry::writeSTL(const std::string &fileName) const } else { std::ofstream outfile(fileName, std::ios::out | std::ios_base::binary); if (!outfile.is_open()) throw std::invalid_argument("Error writing to stl file \""+fileName+"\""); - this->writeSTL(outfile);; + this->writeSTL(outfile); } }// Geometry::writeSTL @@ -381,7 +398,7 @@ void Geometry::writeGEO(const std::string &fileName) const void Geometry::read(const std::string &fileName) { - switch (findFileExt(fileName, {"obj", "ply", "pts", "stl", "abc", "vdb", "nvdb", "geo"})) { + switch (findFileExt(fileName, {"obj", "ply", "pts", "stl", "abc", "vdb", "nvdb", "geo", "off"})) { case 1: this->readOBJ(fileName); break; @@ -406,6 +423,9 @@ void Geometry::read(const std::string &fileName) case 8: this->readGEO(fileName); break; + case 9: + this->readOFF(fileName); + break; default: #if VDB_TOOL_USE_PDAL pdal::StageFactory factory; @@ -519,6 +539,63 @@ void Geometry::readPDAL(const std::string &fileName) mBBox = BBoxT(); //invalidate BBox }// Geometry::readPDAL +void Geometry::readOFF(const std::string &fileName) +{ + if (fileName == "stdin.off") { + this->readOFF(std::cin); + } else { + std::ifstream infile(fileName); + if (!infile.is_open()) throw std::invalid_argument("Error opening Geometry file \""+fileName+"\""); + this->readOFF(infile); + } +}// Geometry::readOFF + +void Geometry::readOFF(std::istream &is) +{ + // read header + std::string line; + if (!std::getline(is, line) || line != "OFF") { + throw std::invalid_argument("Geometry::readOFF: expected header \"OFF\" but read \"" + line + "\""); + } + + // read vertex and face counts + size_t vtxCount=0, faceCount=0, edgeCount=0, nGon=0; + while (vtxCount == 0 && std::getline(is, line)) { + if (line.empty() || line[0] == '#') continue; + std::istringstream iss(line); + iss >> vtxCount >> faceCount >> edgeCount; + } + + // read vertices + Vec3f p; + vtxCount += mVtx.size(); + while (mVtx.size() < vtxCount && std::getline(is, line)) { + if (line.empty() || line[0] == '#') continue; + std::istringstream iss(line); + iss >> p[0] >> p[1] >> p[2]; + mVtx.push_back(p); + } + + // read faces + int f[4]; + faceCount += mTri.size() + mQuad.size(); + while (mTri.size() + mQuad.size() < faceCount && std::getline(is, line)) { + if (line.empty() || line[0] == '#') continue; + std::istringstream iss(line); + iss >> nGon; + if (nGon == 3) { + iss >> f[0] >> f[1] >> f[2]; + mTri.emplace_back(f[0],f[1],f[2]); + } else if (nGon == 4) { + iss >> f[0] >> f[1] >> f[2] >> f[3]; + mQuad.emplace_back(f[0],f[1],f[2],f[3]); + } else { + throw std::invalid_argument("Geometry::readOFF: " + std::to_string(nGon) + "-gons are not supported"); + } + } + mBBox = BBoxT();//invalidate BBox +}// Geometry::readOFF + void Geometry::readPLY(const std::string &fileName) { if (fileName == "stdin.ply") { @@ -545,9 +622,7 @@ void Geometry::readPLY(std::istream &is) auto tokens = tokenize_line(); auto test = [&tokens](int i, std::vector str) { if (i >= static_cast(tokens.size())) return false; - for (auto &s : str) { - if (tokens[i] == s) return true; - } + for (auto &s : str) if (tokens[i] == s) return true; return false; }; auto error = [&tokens](const std::string &msg){ @@ -556,8 +631,19 @@ void Geometry::readPLY(std::istream &is) std::cerr << "\"\n"; throw std::invalid_argument(msg); }; + auto sizeOf = [test, error](int i){ + if ( test(i, {"float", "float32", "int", "int32"}) ) return 4; + if ( test(i, {"double", "float64"}) ) return 8; + if ( test(i, {"int16", "uint16"}) ) return 2; + if ( test(i, {"uchar", "int8"}) ) return 1; + error("vdb_tool::readPLY: unsupported type"); + return 0; + }; + // check header if (!test(0, {"ply"})) error("vdb_tool::readPLY: not a ply file"); + + // check file format int format = -1;// 0 is ascii, 1 is little endian and 2 is big endian tokens = tokenize_line(); if (!(test(0, {"format"}) && test(2, {"1.0"})) ) { @@ -573,18 +659,20 @@ void Geometry::readPLY(std::istream &is) } const bool reverseBytes = format && format != (isLittleEndian() ? 1 : 2); // header: https://www.mathworks.com/help/vision/ug/the-ply-format.html - size_t vtxCount = 0, polyCount = 0; - struct Skip {int count, bytes;} vtx_skip[2]={{0,0},{0,0}}, ply_skip[2]={{0,0},{0,0}}; + size_t vtxCount = 0, faceCount = 0; + int vtxStride=0, vtxProps=0;// byte size of all vtx properties, number of vertex properties + struct Triplet {int offset, id, size;} xyz[3];// byte offset, id#, byte size + struct Skip {int count, bytes;} faceSkip[2]={{0,0},{0,0}};// head, {faces}, tail + + // parse header with vertex, face and property information tokens = tokenize_line(); bool run = true; while(run) { if ( test(0, {"element"}) ) { if ( test(1, {"vertex"}) ) { vtxCount = std::stoll(tokens[2]); - int n = 0; const std::string axis[3] = {"x", "y", "z"}; while(true) { - const int m = n>0 ? 1 : 0; tokens = tokenize_line(); if ( test(0, {"end_header"}) ) { run = false; @@ -592,35 +680,16 @@ void Geometry::readPLY(std::istream &is) } else if ( test(0, {"element"}) ) { break; } else if ( test(0, {"property"}) ) { - if ( test(1, {"float", "float32"}) ) { - if ( test(2, {"x", "y", "z"}) ) {// nx,ny.nz - if (n>2 || !test(2, {axis[n++]}) ) error("vdb_tool::readPLY: expected x or y or z"); - } else {// e.g. nx, ny, nz, intensity, s, t etc - if (n!=0 && n!=3) error("vdb_tool::readPLY: vertex float property interlaced with coordinates"); - vtx_skip[m].count += 1; - vtx_skip[m].bytes += static_cast(sizeof(float)); - } - } else if ( test(1, {"int16", "uint16"}) ) {// e.g. material_index etc - if (n!=0 && n!=3) error("vdb_tool::readPLY: vertex int16 property interlaced with coordinates is not supported"); - vtx_skip[m].count += 1; - vtx_skip[m].bytes += static_cast(sizeof(int16_t)); - } else if ( test(1, {"int", "int32"}) ) {// e.g. material_index etc - if (n!=0 && n!=3) error("vdb_tool::readPLY: vertex int32 property interlaced with coordinates is not supported"); - vtx_skip[m].count += 1; - vtx_skip[m].bytes += static_cast(sizeof(int32_t)); - } else if ( test(1, {"uchar", "int8"}) ) {// eg red, green, blue, alpha - if (n!=0 && n!=3) error("vdb_tool::readPLY: vertex int8 property interlaced with coordinates is not supported"); - vtx_skip[m].count += 1; - vtx_skip[m].bytes += static_cast(sizeof(unsigned char)); - } else { - error("vdb_tool::readPLY: invalid vertex property"); - } + Triplet t{vtxStride, vtxProps++, sizeOf(1)}; + for (int i=0; i<3; ++i) if (test(2, {axis[i]})) xyz[i] = t; + vtxStride += t.size; } } - if (n!=3) error("vdb_tool::readPLY: missing vertex coordinates"); + for (int i=0; i<3; ++i) if (xyz[i].size!=4 && xyz[i].size!=8) error("vdb_tool::readPLY: missing "+axis[i]+ + " vertex coordinates or unsupported size "+std::to_string(xyz[i].size)); } else if ( test(1, {"face"}) ) { - polyCount = std::stoll(tokens[2]); - int n = 0; + faceCount = std::stoll(tokens[2]); + int n = 0;// 0 is head and 1 is tail while (true) { tokens = tokenize_line(); if ( test(0, {"end_header"}) ) { @@ -628,15 +697,15 @@ void Geometry::readPLY(std::istream &is) break; } else if (test(0, {"element"}) ) { break; - } else if (test(0, {"property"}) ) { - if (test(1, {"list"}) && - test(2, {"uchar", "uint8"}) && - test(3, {"int", "uint", "int32"}) && + } else if (test(0, {"property"}) ) {// eg: "property list uchar int vertex_indices" + if (test(1, {"list"}) &&// list of vertex ID belonging to a polygon + test(2, {"uchar", "uint8"}) &&// size of polygon, e.g. 3 or 4 + test(3, {"int", "uint", "int32"}) &&// type of vertex id test(4, {"vertex_index", "vertex_indices"}) ) { - n = 1; - } else if ( test(1, {"uchar", "uint8"}) ) { - ply_skip[n].count += 1; - ply_skip[n].bytes += 1; + n = 1;// change from head to tail + } else if ( test(1, {"uchar", "uint8"}) ) {// eg: "property uchar intensity" + faceSkip[n].count += 1; + faceSkip[n].bytes += 1; } else { error("vdb_tool::readPLY: invalid face properties"); } @@ -655,7 +724,7 @@ void Geometry::readPLY(std::istream &is) } else { error("vdb_tool::readPLY: invalid element"); } - } else if ( test(0, {"comment", "obj_info"}) ) { + } else if ( test(0, {"comment", "obj_info"}) ) {// eq: "obj_info 3D colored patch boundaries" and "comment author: Paraform" tokens = tokenize_line(); } else { error("vdb_tool::readPLY: unexpected entry in header"); @@ -665,96 +734,69 @@ void Geometry::readPLY(std::istream &is) // read vertex coordinates mVtx.resize(vtxCount); if (format) {// binary - if (vtx_skip[0].count == 0 && vtx_skip[1].count == 0) {//faster + if (xyz[0].offset==0 && xyz[1].offset==4 && xyz[2].offset==8 && vtxStride==12) {// most common case is.read((char *)(mVtx.data()), vtxCount * 3 * sizeof(float)); + if (reverseBytes) for (Vec3f &v : mVtx) swapBytes(&v[0], 3); } else { - const size_t bSize = vtx_skip[0].bytes + 3*sizeof(float) + vtx_skip[1].bytes; - char *buffer = static_cast(std::malloc(vtxCount*bSize));// uninitialized + char *buffer = static_cast(std::malloc(vtxCount*vtxStride)), *p = buffer;// uninitialized if (buffer==nullptr) throw std::invalid_argument("Geometry::readPLY: failed to allocate buffer"); - is.read(buffer, vtxCount*bSize); - for (size_t i=0; i(buffer + i*bSize + vtx_skip[0].bytes); - mVtx[i] = Vec3f(p); + is.read(buffer, vtxCount*vtxStride); + for (Vec3f &vtx : mVtx) { + for (int i=0; i<3; ++i) { + if (xyz[i].size == 4) { + float v = *(float*)(p + xyz[i].offset); + vtx[i] = reverseBytes ? swapBytes(v) : v; + } else { + double v = *(double*)(p + xyz[i].offset); + vtx[i] = float(reverseBytes ? swapBytes(v) : v); + } + } + p += vtxStride; } std::free(buffer); } - if (reverseBytes) { - auto flipBytes = [](float v)->float{ - float tmp; - char *p = (char*)&v, *q = (char*)&tmp; - q[0] = p[3]; - q[1] = p[2]; - q[2] = p[1]; - q[3] = p[0]; - return tmp; - };// flipBytes in float - for (size_t i = 0; i < mVtx.size(); ++i) { - auto &p = mVtx[i]; - p[0] = flipBytes(p[0]); - p[1] = flipBytes(p[1]); - p[2] = flipBytes(p[2]); - } - } - } else {// ascii + + } else {// ascii vertices for (auto &v : mVtx) { tokens = tokenize_line(); - if (static_cast(tokens.size()) != vtx_skip[0].count + 3 + vtx_skip[1].count) { - error("vdb_tool::readPLY: error reading ascii vertex coordinates"); - } - for (int i = 0; i<3; ++i) { - v[i] = std::stof(tokens[i + vtx_skip[0].count]); - } + if (int(tokens.size()) != vtxProps) error("vdb_tool::readPLY: error reading ascii vertex coordinates"); + for (int i = 0; i<3; ++i) v[i] = std::stof(tokens[xyz[0].id]); }// loop over vertices } // read polygon vertex lists uint32_t vtx[4]; if (format) {// binary - auto flipBytes = [&](int n){ - uint32_t tmp; - char *q = (char*)&tmp; - for (int i=0; i(std::malloc(ply_skip[0].bytes + 1));// uninitialized + char *buffer = static_cast(std::malloc(faceSkip[0].bytes + 1));// uninitialized if (buffer==nullptr) throw std::invalid_argument("Geometry::readPLY: failed to allocate buffer"); - for (size_t i=0; i unsigned int switch (n) { case 3: - is.read((char *)(&vtx), 3*sizeof(uint32_t)); - if (reverseBytes) flipBytes(3); + is.read((char*)vtx, 3*sizeof(uint32_t)); + if (reverseBytes) swapBytes(vtx, 3); mTri.emplace_back(vtx); break; case 4: - is.read((char *)(&vtx), 4*sizeof(uint32_t)); - if (reverseBytes) flipBytes(4); + is.read((char*)vtx, 4*sizeof(uint32_t)); + if (reverseBytes) swapBytes(vtx, 4); mQuad.emplace_back(vtx); break; default: throw std::invalid_argument("Geometry::readPLY: binary " + std::to_string(n) + "-gons are not supported"); break; } - is.ignore(ply_skip[1].bytes); + is.ignore(faceSkip[1].bytes); }// loop over polygons std::free(buffer); - } else {// ascii format - for (size_t i=0; i(std::stoll(tokens[i + 1 + ply_skip[0].count])); - } + const std::string polySize = tokens[faceSkip[0].count]; + const int n = std::stoi(polySize); + if (n!=3 && n!=4) throw std::invalid_argument("Geometry::readPLY: ascii " + polySize + "-gons are not supported"); + for (int i = 0, j=1+faceSkip[0].count; i(std::stoll(tokens[j])); if (n==3) { mTri.emplace_back(vtx); } else { diff --git a/openvdb_cmd/vdb_tool/include/Tool.h b/openvdb_cmd/vdb_tool/include/Tool.h index 5e4cae6899..b24e71696e 100644 --- a/openvdb_cmd/vdb_tool/include/Tool.h +++ b/openvdb_cmd/vdb_tool/include/Tool.h @@ -53,9 +53,9 @@ #ifdef VDB_TOOL_USE_NANO #include -#include -#include -#include +#include +#include +#include #endif #ifdef VDB_TOOL_USE_EXR @@ -369,14 +369,14 @@ void Tool::init() mParser.addAction( "read", "i", "Read one or more geometry or VDB files from disk or STDIN.", - {{"files", "", "{file|stdin}.{abc|obj|ply|stl|vdb}", "list of files or the input stream, e.g. file.vdb,stdin.vdb. Note that \"files=\" is optional since any argument without \"=\" is intrepreted as a file and appended to \"files\""}, + {{"files", "", "{file|stdin}.{abc|obj|ply|stl|off|vdb}", "list of files or the input stream, e.g. file.vdb,stdin.vdb. Note that \"files=\" is optional since any argument without \"=\" is intrepreted as a file and appended to \"files\""}, {"grids", "*", "*|grid_name,...", "list of VDB grids name to be imported (defaults to \"*\", i.e. import all available grids)"}, {"delayed", "true", "1|0|true|false", "toggle delayed loading of VDB grids (enabled by default). This option is ignored by other file types"}}, [](){}, [&](){this->read();}, 0);// anonymous options are treated as to the first option,i.e. "files" mParser.addAction( "write", "o", "Write list of geometry, VDB or config files to disk or STDOUT", - {{"files", "", "{file|stdout}.{obj|ply|stl|vdb|nvdb}", "list of files or the output stream, e.g. file.vdb or stdin.vdb. Note that \"files=\" is optional since any argument without the \"=\" character is intrepreted as a file and appended to \"files\"."}, + {{"files", "", "{file|stdout}.{obj|ply|stl|off|vdb|nvdb}", "list of files or the output stream, e.g. file.vdb or stdin.vdb. Note that \"files=\" is optional since any argument without the \"=\" character is intrepreted as a file and appended to \"files\"."}, {"geo", "0", "0|1...", "geometry to write (defaults to \"0\" which is the latest)."}, {"vdb", "*", "0,1,...", "list of VDB grids to write (defaults to \"*\", i.e. all available grids)."}, {"keep", "", "1|0|true|false", "toggle wether to preserved or deleted geometry and grids after they have been written."}, @@ -925,8 +925,8 @@ std::string Tool::examples() const { const int w = 16; std::stringstream ss; - ss << std::left << std::setw(w) << "Surface points:" << mCmdName << " -read points.[obj/ply/stl/pts] -points2ls d=256 r=2.0 w=3 -dilate r=2 -gauss i=1 w=1 -erode r=2 -ls2m a=0.25 -write output.[ply/obj/stl]\n"; - ss << std::left << std::setw(w) << "Convert mesh: " << mCmdName << " -read mesh.[ply/obj] -mesh2ls d=256 -write output.vdb config.txt\n"; + ss << std::left << std::setw(w) << "Surface points:" << mCmdName << " -read points.[obj/ply/stl/off/pts] -points2ls d=256 r=2.0 w=3 -dilate r=2 -gauss i=1 w=1 -erode r=2 -ls2m a=0.25 -write output.[ply/obj/stl]\n"; + ss << std::left << std::setw(w) << "Convert mesh: " << mCmdName << " -read mesh.[ply/obj/off] -mesh2ls d=256 -write output.vdb config.txt\n"; ss << std::left << std::setw(w) << "Config example:" << mCmdName << " -config config.txt\n"; return ss.str(); } @@ -963,7 +963,7 @@ void Tool::read() { OPENVDB_ASSERT(mParser.getAction().name == "read"); for (auto &fileName : mParser.getVec("files")) { - switch (findFileExt(fileName, {"geo,obj,ply,abc,pts,stl", "vdb", "nvdb"})) { + switch (findFileExt(fileName, {"geo,obj,ply,abc,pts,off,stl", "vdb", "nvdb"})) { case 1: this->readGeo(fileName); break; @@ -1062,7 +1062,7 @@ void Tool::readNVDB(const std::string &fileName) const size_t count = mGrid.size(); if (grids.size()) { for (const auto& gridHandle : grids) { - if (gridNames[0]=="*" || findMatch(gridHandle.gridMetaData()->shortGridName(), gridNames)) mGrid.push_back(nanovdb::nanoToOpenVDB(gridHandle)); + if (gridNames[0]=="*" || findMatch(gridHandle.gridMetaData()->shortGridName(), gridNames)) mGrid.push_back(nanovdb::tools::nanoToOpenVDB(gridHandle)); } } else if (mParser.verbose>0) { std::cerr << "readVDB: no vdb grids in \"" << fileName << "\""; @@ -1135,7 +1135,7 @@ void Tool::write() { OPENVDB_ASSERT(mParser.getAction().name == "write"); for (std::string &fileName : mParser.getVec("files")) { - switch (findFileExt(fileName, {"geo,obj,ply,stl,abc", "vdb", "nvdb", "txt"})) { + switch (findFileExt(fileName, {"geo,obj,ply,stl,off,abc", "vdb", "nvdb", "txt"})) { case 1: this->writeGeo(fileName); break; @@ -1262,26 +1262,26 @@ void Tool::writeNVDB(const std::string &fileName) throw std::invalid_argument("writeNVDB: unsupported bits \""+bits+"\""); } - nanovdb::StatsMode sMode = nanovdb::StatsMode::Default; + nanovdb::tools::StatsMode sMode = nanovdb::tools::StatsMode::Default; if (stats == "none") { - sMode = nanovdb::StatsMode::Disable; + sMode = nanovdb::tools::StatsMode::Disable; } else if (stats == "bbox") { - sMode = nanovdb::StatsMode::BBox; + sMode = nanovdb::tools::StatsMode::BBox; } else if (stats == "extrema") { - sMode = nanovdb::StatsMode::MinMax; + sMode = nanovdb::tools::StatsMode::MinMax; } else if (stats == "all") { - sMode = nanovdb::StatsMode::All; + sMode = nanovdb::tools::StatsMode::All; } else if (stats != "") { throw std::invalid_argument("writeNVDB: unsupported stats \""+stats+"\""); } - nanovdb::ChecksumMode cMode = nanovdb::ChecksumMode::Default; + nanovdb::CheckMode cMode = nanovdb::CheckMode::Default; if (checksum == "none") { - cMode = nanovdb::ChecksumMode::Disable; + cMode = nanovdb::CheckMode::Disable; } else if (checksum == "partial") { - cMode = nanovdb::ChecksumMode::Partial; + cMode = nanovdb::CheckMode::Partial; } else if (checksum == "full") { - cMode = nanovdb::ChecksumMode::Full; + cMode = nanovdb::CheckMode::Full; } else if (checksum != "") { throw std::invalid_argument("writeNVDB: unsupported checksum \""+checksum+"\""); } @@ -1302,21 +1302,21 @@ void Tool::writeNVDB(const std::string &fileName) using SrcGridT = openvdb::FloatGrid; switch (qMode){ case nanovdb::GridType::Fp4: - return nanovdb::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); + return nanovdb::tools::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); case nanovdb::GridType::Fp8: - return nanovdb::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); + return nanovdb::tools::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); case nanovdb::GridType::Fp16: - return nanovdb::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); + return nanovdb::tools::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose); case nanovdb::GridType::FpN: if (absolute) { - return nanovdb::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose, nanovdb::AbsDiff(tolerance)); + return nanovdb::tools::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose, nanovdb::tools::AbsDiff(tolerance)); } else { - return nanovdb::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose, nanovdb::RelDiff(tolerance)); + return nanovdb::tools::createNanoGrid(*floatGrid, sMode, cMode, dither, verbose, nanovdb::tools::RelDiff(tolerance)); } default: break;// 32 bit float grids are handled below }// end of switch } - return nanovdb::openToNanoVDB(base, sMode, cMode, verbose);// float and other grids + return nanovdb::tools::openToNanoVDB(base, sMode, cMode, verbose);// float and other grids };// openToNano if (fileName=="stdout.nvdb") { diff --git a/openvdb_cmd/vdb_tool/include/Util.h b/openvdb_cmd/vdb_tool/include/Util.h index 96c324711c..9d084fb22e 100644 --- a/openvdb_cmd/vdb_tool/include/Util.h +++ b/openvdb_cmd/vdb_tool/include/Util.h @@ -377,6 +377,31 @@ inline bool isLittleEndian() return (*(char *)&tmp == 1); } +/// @brief invert endianess of a type +/// @tparam T Template type to be inverted +/// @param val value to be inverted +/// @return value with reverse bytes +template +inline T swapBytes(T val) +{ + T tmp; + for (char *src=(char*)&val, *dst=(char*)(&tmp)+sizeof(T)-1, *end=src+sizeof(T);src!=end; *dst-- = *src++); + return tmp; +} + +/// @brief invert endianess of an array of values of a specific type +/// @tparam T Template type to be inverted +/// @param val pointer to array with values to be inverted +/// @param n number of elements in the array +template +inline void swapBytes(T *val, int n) +{ + for (T tmp, *last = val + n; val < last; ++val) { + for (char *src=(char*)val, *dst=(char*)(&tmp)+sizeof(T)-1, *end=src+sizeof(T); src!=end; *dst-- = *src++); + *val = tmp; + } +} + /// @brief return a pseudo random uuid string. /// /// @details this function approximates a uuid version 4, variant 1 as detailed diff --git a/openvdb_cmd/vdb_tool/src/unittest.cpp b/openvdb_cmd/vdb_tool/src/unittest.cpp index 71fc4c9ade..0ddd6fb2cf 100644 --- a/openvdb_cmd/vdb_tool/src/unittest.cpp +++ b/openvdb_cmd/vdb_tool/src/unittest.cpp @@ -301,6 +301,52 @@ TEST_F(Test_vdb_tool, Util) } EXPECT_EQ(size, tmp.size()); } + + {//swapBytes + const int i = 4, j = openvdb::vdb_tool::swapBytes(i); + EXPECT_NE(i, j); + EXPECT_EQ(i, openvdb::vdb_tool::swapBytes(j)); + + const float a = 4, b = openvdb::vdb_tool::swapBytes(a); + EXPECT_NE(a, b); + EXPECT_EQ(a, openvdb::vdb_tool::swapBytes(b)); + + const double x = 4, y = openvdb::vdb_tool::swapBytes(x); + EXPECT_NE(x, y); + EXPECT_EQ(x, openvdb::vdb_tool::swapBytes(y)); + + int vec_i[3]={3,4,5}, vec_j[3]; + for (int n=0; n<3; ++n) { + vec_j[n] = openvdb::vdb_tool::swapBytes(vec_i[n]); + EXPECT_NE(vec_i[n], vec_j[n]); + } + openvdb::vdb_tool::swapBytes(vec_j, 3); + for (int n=0; n<3; ++n) EXPECT_EQ(vec_i[n], vec_j[n]); + + float vec_a[3]={3,4,5}, vec_b[3]; + for (int n=0; n<3; ++n) { + vec_b[n] = openvdb::vdb_tool::swapBytes(vec_a[n]); + EXPECT_NE(vec_a[n], vec_b[n]); + } + openvdb::vdb_tool::swapBytes(vec_b, 3); + for (int n=0; n<3; ++n) EXPECT_EQ(vec_a[n], vec_b[n]); + + double vec_x[3]={3,4,5}, vec_y[3]; + for (int n=0; n<3; ++n) { + vec_y[n] = openvdb::vdb_tool::swapBytes(vec_x[n]); + EXPECT_NE(vec_x[n], vec_y[n]); + } + openvdb::vdb_tool::swapBytes(vec_y, 3); + for (int n=0; n<3; ++n) EXPECT_EQ(vec_x[n], vec_y[n]); + } + {// weird pointer behaviour + float vec[4], *p = vec; + EXPECT_EQ(vec, p);// of course + EXPECT_EQ((char*)(vec), (char*)p);// sure + EXPECT_EQ((char*)(&vec), (char*)p);// wait, what?! + EXPECT_NE((char*)(vec), (char*)(&p));// yep + EXPECT_NE((char*)(&p), (char*)p);// of course + } }// Util TEST_F(Test_vdb_tool, getArgs) @@ -371,18 +417,18 @@ TEST_F(Test_vdb_tool, Geometry) EXPECT_EQ(4, geo2.vtxCount()); EXPECT_EQ(2, geo2.triCount()); EXPECT_EQ(1, geo2.quadCount()); - EXPECT_EQ(openvdb::Vec3f(1,2,3), geo.bbox().min()); - EXPECT_EQ(openvdb::Vec3f(10,11,12), geo.bbox().max()); + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.bbox().min()); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.bbox().max()); - EXPECT_EQ(openvdb::Vec3f(1,2,3), geo.vtx()[0]); - EXPECT_EQ(openvdb::Vec3f(4,5,6), geo.vtx()[1]); - EXPECT_EQ(openvdb::Vec3f(7,8,9), geo.vtx()[2]); - EXPECT_EQ(openvdb::Vec3f(10,11,12), geo.vtx()[3]); + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.vtx()[0]); + EXPECT_EQ(openvdb::Vec3f(4,5,6), geo2.vtx()[1]); + EXPECT_EQ(openvdb::Vec3f(7,8,9), geo2.vtx()[2]); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.vtx()[3]); - EXPECT_EQ(openvdb::Vec3I(0,1,2), geo.tri()[0]); - EXPECT_EQ(openvdb::Vec3I(1,2,3), geo.tri()[1]); + EXPECT_EQ(openvdb::Vec3I(0,1,2), geo2.tri()[0]); + EXPECT_EQ(openvdb::Vec3I(1,2,3), geo2.tri()[1]); - EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo.quad()[0]); + EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo2.quad()[0]); } {// write to file std::ofstream os("data/test.geo", std::ios_base::binary); @@ -395,18 +441,38 @@ TEST_F(Test_vdb_tool, Geometry) EXPECT_EQ(4, geo2.vtxCount()); EXPECT_EQ(2, geo2.triCount()); EXPECT_EQ(1, geo2.quadCount()); - EXPECT_EQ(openvdb::Vec3f(1,2,3), geo.bbox().min()); - EXPECT_EQ(openvdb::Vec3f(10,11,12), geo.bbox().max()); + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.bbox().min()); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.bbox().max()); - EXPECT_EQ(openvdb::Vec3f(1,2,3), geo.vtx()[0]); - EXPECT_EQ(openvdb::Vec3f(4,5,6), geo.vtx()[1]); - EXPECT_EQ(openvdb::Vec3f(7,8,9), geo.vtx()[2]); - EXPECT_EQ(openvdb::Vec3f(10,11,12), geo.vtx()[3]); + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.vtx()[0]); + EXPECT_EQ(openvdb::Vec3f(4,5,6), geo2.vtx()[1]); + EXPECT_EQ(openvdb::Vec3f(7,8,9), geo2.vtx()[2]); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.vtx()[3]); - EXPECT_EQ(openvdb::Vec3I(0,1,2), geo.tri()[0]); - EXPECT_EQ(openvdb::Vec3I(1,2,3), geo.tri()[1]); + EXPECT_EQ(openvdb::Vec3I(0,1,2), geo2.tri()[0]); + EXPECT_EQ(openvdb::Vec3I(1,2,3), geo2.tri()[1]); - EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo.quad()[0]); + EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo2.quad()[0]); + } + {// test readOFF and writeOFF + geo.write("data/test.off"); + openvdb::vdb_tool::Geometry geo2; + geo2.read("data/test.off"); + EXPECT_EQ(4, geo2.vtxCount()); + EXPECT_EQ(2, geo2.triCount()); + EXPECT_EQ(1, geo2.quadCount()); + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.bbox().min()); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.bbox().max()); + + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.vtx()[0]); + EXPECT_EQ(openvdb::Vec3f(4,5,6), geo2.vtx()[1]); + EXPECT_EQ(openvdb::Vec3f(7,8,9), geo2.vtx()[2]); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.vtx()[3]); + + EXPECT_EQ(openvdb::Vec3I(0,1,2), geo2.tri()[0]); + EXPECT_EQ(openvdb::Vec3I(1,2,3), geo2.tri()[1]); + + EXPECT_EQ(openvdb::Vec4I(0,1,2,3), geo2.quad()[0]); } #ifdef VDB_TOOL_USE_PDAL {// read from PDAL-supported ASCII format file @@ -425,11 +491,10 @@ TEST_F(Test_vdb_tool, Geometry) geo2.read("data/test.txt"); EXPECT_EQ(4, geo2.vtxCount()); - EXPECT_EQ(openvdb::Vec3f(1,2,3), geo.vtx()[0]); - EXPECT_EQ(openvdb::Vec3f(4,5,6), geo.vtx()[1]); - EXPECT_EQ(openvdb::Vec3f(7,8,9), geo.vtx()[2]); - EXPECT_EQ(openvdb::Vec3f(10,11,12), geo.vtx()[3]); - + EXPECT_EQ(openvdb::Vec3f(1,2,3), geo2.vtx()[0]); + EXPECT_EQ(openvdb::Vec3f(4,5,6), geo2.vtx()[1]); + EXPECT_EQ(openvdb::Vec3f(7,8,9), geo2.vtx()[2]); + EXPECT_EQ(openvdb::Vec3f(10,11,12), geo2.vtx()[3]); } #endif }// Geometry @@ -801,7 +866,7 @@ TEST_F(Test_vdb_tool, ToolParser) float beta = 0.0f, beta_sum = 0.0f; std::string path, base, ext; - Parser p({{"alpha", "64"}, {"beta", "4.56"}}); + Parser p({{"alpha", "64", "", ""}, {"beta", "4.56", "", ""}}); p.addAction("process_a", "a", "docs", {{"alpha", "", "", ""},{"beta", "", "", ""}}, [&](){p.setDefaults();}, @@ -824,7 +889,7 @@ TEST_F(Test_vdb_tool, ToolParser) p.finalize(); auto args = getArgs("vdb_tool -quiet -process_a alpha=128 -for v=0.1,0.4,0.1 -b alpha={$#v:++} beta={$v} -end"); - p.parse(args.size(), args.data()); + p.parse(int(args.size()), args.data()); EXPECT_EQ(0, alpha); EXPECT_EQ(0.0f, beta); EXPECT_EQ(0, alpha_sum); @@ -836,7 +901,7 @@ TEST_F(Test_vdb_tool, ToolParser) EXPECT_EQ(0.1f + 0.2f + 0.3f, beta_sum);// derived from loop args = getArgs("vdb_tool -quiet -each file=path1/base1.ext1,path2/base2.ext2 -c alpha={$file:path} beta={$file:name} gamma={$file:ext} -end"); - p.parse(args.size(), args.data()); + p.parse(int(args.size()), args.data()); p.run(); EXPECT_EQ(path, "path1,path2"); EXPECT_EQ(base, "base1,base2"); @@ -856,7 +921,7 @@ TEST_F(Test_vdb_tool, ToolBasic) EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -sphere r=1.1 -ls2mesh -write data/sphere.ply data/config.txt"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); @@ -877,7 +942,7 @@ TEST_F(Test_vdb_tool, Counter) EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -eval {1:@G} -sphere r=1.1 -ls2mesh -write data/sphere_{$G}.ply data/config_{$G:++}.txt"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); @@ -900,7 +965,7 @@ TEST_F(Test_vdb_tool, ToolForLoop) // test single for-loop EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -for i=0,3 -sphere r=1.{$i} dim=128 name=sphere_{$i} -ls2mesh -write data/sphere_{$#i:++}.ply -end"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); @@ -909,7 +974,7 @@ TEST_F(Test_vdb_tool, ToolForLoop) // test two nested for-loops EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -for v=0.1,0.3,0.1 -each s=sphere_1,sphere_3 -read ./data/{$s}.ply -mesh2ls voxel={$v} -end -end -write data/test.vdb"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); @@ -929,7 +994,7 @@ TEST_F(Test_vdb_tool, ToolError) EXPECT_THROW({ auto args = getArgs("vdb_tool -sphere bla=3 -ls2mesh -write data/sphere.ply data/config.txt -quiet"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }, std::invalid_argument); @@ -952,7 +1017,7 @@ TEST_F(Test_vdb_tool, ToolKeep) EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -default keep=1 -sphere r=2 -ls2mesh vdb=0 -write vdb=0 geo=0 data/sphere.vdb data/sphere.ply data/config.txt"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); @@ -975,7 +1040,7 @@ TEST_F(Test_vdb_tool, ToolConfig) EXPECT_NO_THROW({ auto args = getArgs("vdb_tool -quiet -config data/config.txt"); - Tool vdb_tool(args.size(), args.data()); + Tool vdb_tool(int(args.size()), args.data()); vdb_tool.run(); }); diff --git a/pendingchanges/vdb_tool.txt b/pendingchanges/vdb_tool.txt new file mode 100644 index 0000000000..c68dc25834 --- /dev/null +++ b/pendingchanges/vdb_tool.txt @@ -0,0 +1 @@ +added read and write support for OFF (Object File Format) files to vdb_tool \ No newline at end of file From 930c3acb8e0c7c2f1373f3a70dc197f5d04dfe74 Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Wed, 4 Dec 2024 19:46:48 -0800 Subject: [PATCH 88/98] Fix Clang Template errors (#1977) Upcoming versions of Clang/LLVM change some behaviour around templating that causes OpenVDB to fail to compile. This commit addresses two issues and allows VDB to compile again. 1. There were three instances of an unnecessary template keyword in NodeManager.h that were not followed by a template call, and therefore are illegal to the compiler. 2. GridBuilder.h had a template call to a non-existent method. This was not previously validated, but is now validated. Switching the symbol from `isActive` to `isOn` per Ken's review. See the [changelog](https://releases.llvm.org/19.1.0/tools/clang/docs/ReleaseNotes.html#improvements-to-clang-s-diagnostics:~:text=Clang%20now%20looks%20up%20members%20of%20the%20current%20instantiation%20in%20the%20template%20definition%20context%20if%20the%20current%20instantiation%20has%20no%20dependent%20base%20classes.) for Clang and the associated [PR for the second point above](https://github.com/llvm/llvm-project/pull/84050) Signed-off-by: Dhruv Govil --- nanovdb/nanovdb/tools/GridBuilder.h | 2 +- openvdb/openvdb/tree/NodeManager.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nanovdb/nanovdb/tools/GridBuilder.h b/nanovdb/nanovdb/tools/GridBuilder.h index 30385661d0..428215ba65 100644 --- a/nanovdb/nanovdb/tools/GridBuilder.h +++ b/nanovdb/nanovdb/tools/GridBuilder.h @@ -1158,7 +1158,7 @@ struct LeafNode ValueIterator& operator=(const ValueIterator&) = default; ValueType operator*() const { NANOVDB_ASSERT(*this); return mParent->mValues[mPos];} Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(mPos);} - bool isActive() const { NANOVDB_ASSERT(*this); return mParent->isActive(mPos);} + bool isActive() const { NANOVDB_ASSERT(*this); return mParent->mValueMask.isOn(mPos);} operator bool() const {return mPos < SIZE;} ValueIterator& operator++() {++mPos; return *this;} ValueIterator operator++(int) { diff --git a/openvdb/openvdb/tree/NodeManager.h b/openvdb/openvdb/tree/NodeManager.h index 27a3f82012..1023c00748 100644 --- a/openvdb/openvdb/tree/NodeManager.h +++ b/openvdb/openvdb/tree/NodeManager.h @@ -328,7 +328,7 @@ class NodeList void operator()(const NodeRange& range) const { for (typename NodeRange::Iterator it = range.begin(); it; ++it) { - OpT::template eval(mNodeOp, it); + OpT::eval(mNodeOp, it); } } const NodeOp mNodeOp; @@ -348,7 +348,7 @@ class NodeList void operator()(const NodeRange& range) const { for (typename NodeRange::Iterator it = range.begin(); it; ++it) { - OpT::template eval(mNodeOp, it); + OpT::eval(mNodeOp, it); } } const NodeOp& mNodeOp; @@ -373,7 +373,7 @@ class NodeList void operator()(const NodeRange& range) { for (typename NodeRange::Iterator it = range.begin(); it; ++it) { - OpT::template eval(*mNodeOp, it); + OpT::eval(*mNodeOp, it); } } void join(const NodeReducer& other) From 840df4dc460f48f263b5975f6f50695b7cb6aa35 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Fri, 6 Dec 2024 11:10:51 -0800 Subject: [PATCH 89/98] Meeting notes Signed-off-by: Dan Bailey --- tsc/meetings/2024-12-03.md | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tsc/meetings/2024-12-03.md diff --git a/tsc/meetings/2024-12-03.md b/tsc/meetings/2024-12-03.md new file mode 100644 index 0000000000..e864d84bdd --- /dev/null +++ b/tsc/meetings/2024-12-03.md @@ -0,0 +1,80 @@ +Minutes from OpenVDB TSC meeting, December 3rd, 2024 + +Attendees: *Ken* M., *Andre* P, *Dan* B. + +Additional Attendees: Jonathan Swartz (NVIDIA), Dhruv Govil (Apple) + +Regrets: *Jeff* L., *Richard* J., *Nick* A., *Greg* H. + +Agenda: + +1) Confirm quorum +2) Secretary +3) PR1971 +4) Binary Distribution +5) PR1977 +6) Fluid Example +7) TBB Threading +8) ASWF Code Build +9) Next meeting + +------------ + +1) Confirm quorum + +No quorum. + +2) Secretary + +Secretary is Dan Bailey. + +3) PR1971 + +A bug was discovered with vdb_tool that wasn't caught with CI. This has now been +addressed and the CI extended to test this case. + +4) Binary Distribution + +Brief discussion about binary distribution. Still want to support package +manager maintainers, but hesitant to take this on ourselves. A bigger ROI might +be to focus our efforts on migrating towards CMake config files to make using +OpenVDB as a dependency easier. The autogenerated version.h is a step in that +direction, but could be improved with CMake configs. Other ASWF projects such +as OpenEXR have successfully gone in this direction. + +Anaconda integration has been attempted, but is challenging as it only supports +a single library per module by default. + +5) PR1977 + +Dhruv has submitted this PR to address issues with compiling OpenVDB using Clang +19. This new version is stricter and is catching a few valid issues. + +6) Fluid Example + +All would like this to go in. Andre says that it is blocked on an issue with the +Poisson solver which needs to be resolved. Also, the OpenVDB Remove Divergence +SOP has a bug in how the matrices are initialized that needs to be addressed. + +There is a new NanoVDB poisson solver which is of interest to the group. All +agreed that it would potentially be a good fit for NanoVDB. Dan would also +like an example of how to call it directly from OpenVDB. + +7) TBB Threading + +Question about our use of TBB (#1973). Previously discussed making TBB optional +by wrapping all the data structures and function calls in +openvdb/util/Threading.h. This could provide a route to running +single-threading or providing another threading implementation like Apple's +Grand Central Dispatch. A lot of work needed and not clear how general this +approach would be. + +8) ASWF Code Build + +Jonathan to reach out to CI working group to try and move this forward to get +GPU runtime testing. Ken can escalate to TSC if need be. + +9) Next meeting + +Next meeting is Tuesday December 17, 2024 at 11:00 PST. This will be the last +meeting of the year. \ No newline at end of file From ca4aec122b793c2ec53ed4ee01ec07b79007b1d2 Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Wed, 11 Dec 2024 18:21:55 +1300 Subject: [PATCH 90/98] Changed GH action upload-artifact to v4; fixes #1982 Signed-off-by: Jonathan Swartz --- .github/workflows/ax.yml | 2 +- .github/workflows/weekly.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ax.yml b/.github/workflows/ax.yml index be512fbc2c..4e56d3d721 100644 --- a/.github/workflows/ax.yml +++ b/.github/workflows/ax.yml @@ -160,7 +160,7 @@ jobs: - 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@v2 + uses: actions/upload-artifact@v4 with: name: ax_grammar path: ./build/openvdb_ax/openvdb_ax/openvdb_ax/grammar diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 747c8af744..57dec07ec8 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -589,7 +589,7 @@ jobs: -strict -extended - name: upload_report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: abi_report From caa3969681d019f782916ce2a7c8d8ccf8509974 Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Tue, 17 Dec 2024 15:21:47 +1300 Subject: [PATCH 91/98] Added spdx license identifiers to files missing them. Signed-off-by: Jonathan Swartz --- ci/build.sh | 2 ++ ci/build_sonar.sh | 2 ++ ci/download_houdini.sh | 2 ++ ci/download_vdb_caches.py | 2 ++ ci/extract_test_examples.sh | 2 ++ ci/install_blosc.sh | 2 ++ ci/install_cppunit.sh | 2 ++ ci/install_doxygen.sh | 2 ++ ci/install_glfw.sh | 2 ++ ci/install_gtest.sh | 2 ++ ci/install_llvm_windows.sh | 2 ++ ci/install_macos.sh | 2 ++ ci/install_nanobind.sh | 2 ++ ci/install_tbb_macos.sh | 2 ++ ci/test_install.sh | 2 ++ ci/test_sonar.sh | 2 ++ nanovdb/nanovdb/cmd/updateFiles.py | 2 ++ nanovdb/nanovdb/cmd/updateFiles.sh | 2 ++ nanovdb/nanovdb/docs/CMakeLists.txt | 2 ++ .../read_nanovdb_sphere_accessor.cc | 2 ++ nanovdb/nanovdb/python/CMakeLists.txt | 2 ++ nanovdb/nanovdb/python/NanoVDBModule.cc | 2 ++ nanovdb/nanovdb/python/PyCreateNanoGrid.cc | 2 ++ nanovdb/nanovdb/python/PyCreateNanoGrid.h | 2 ++ nanovdb/nanovdb/python/PyGridChecksum.cc | 2 ++ nanovdb/nanovdb/python/PyGridChecksum.h | 2 ++ nanovdb/nanovdb/python/PyGridHandle.cc | 2 ++ nanovdb/nanovdb/python/PyGridHandle.h | 2 ++ nanovdb/nanovdb/python/PyGridStats.cc | 2 ++ nanovdb/nanovdb/python/PyGridStats.h | 2 ++ nanovdb/nanovdb/python/PyGridValidator.cc | 2 ++ nanovdb/nanovdb/python/PyGridValidator.h | 2 ++ nanovdb/nanovdb/python/PyHostBuffer.cc | 2 ++ nanovdb/nanovdb/python/PyHostBuffer.h | 2 ++ nanovdb/nanovdb/python/PyIO.cc | 2 ++ nanovdb/nanovdb/python/PyIO.h | 2 ++ nanovdb/nanovdb/python/PyMath.cc | 2 ++ nanovdb/nanovdb/python/PyMath.h | 2 ++ nanovdb/nanovdb/python/PyNanoToOpenVDB.cc | 2 ++ nanovdb/nanovdb/python/PyNanoToOpenVDB.h | 2 ++ nanovdb/nanovdb/python/PyPrimitives.cc | 2 ++ nanovdb/nanovdb/python/PyPrimitives.h | 2 ++ nanovdb/nanovdb/python/PySampleFromVoxels.cc | 2 ++ nanovdb/nanovdb/python/PySampleFromVoxels.h | 2 ++ nanovdb/nanovdb/python/PyTools.cc | 2 ++ nanovdb/nanovdb/python/PyTools.h | 2 ++ nanovdb/nanovdb/python/__init__.py | 2 ++ nanovdb/nanovdb/python/cuda/PyDeviceBuffer.cc | 2 ++ nanovdb/nanovdb/python/cuda/PyDeviceBuffer.h | 2 ++ nanovdb/nanovdb/python/cuda/PyDeviceGridHandle.cu | 2 ++ nanovdb/nanovdb/python/cuda/PyPointsToGrid.cu | 2 ++ nanovdb/nanovdb/python/cuda/PyPointsToGrid.h | 2 ++ nanovdb/nanovdb/python/cuda/PySampleFromVoxels.cu | 2 ++ nanovdb/nanovdb/python/cuda/PySampleFromVoxels.h | 2 ++ nanovdb/nanovdb/python/cuda/PySignedFloodFill.cu | 2 ++ nanovdb/nanovdb/python/cuda/PySignedFloodFill.h | 2 ++ nanovdb/nanovdb/python/test/TestNanoVDB.py | 4 +++- openvdb/openvdb/python/__init__.py | 2 ++ openvdb/openvdb/python/pyTypeCasters.h | 2 ++ openvdb_cmd/vdb_tool/CMakeLists.txt | 2 ++ 60 files changed, 121 insertions(+), 1 deletion(-) diff --git a/ci/build.sh b/ci/build.sh index 110455c881..b0b3c8dfb1 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -e diff --git a/ci/build_sonar.sh b/ci/build_sonar.sh index 10012a5c43..1e720bc626 100755 --- a/ci/build_sonar.sh +++ b/ci/build_sonar.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/download_houdini.sh b/ci/download_houdini.sh index 77aa8e3bd9..0f63a4eceb 100755 --- a/ci/download_houdini.sh +++ b/ci/download_houdini.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/download_vdb_caches.py b/ci/download_vdb_caches.py index 8fa6dadb74..55edaaca74 100755 --- a/ci/download_vdb_caches.py +++ b/ci/download_vdb_caches.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 import os import sys diff --git a/ci/extract_test_examples.sh b/ci/extract_test_examples.sh index cc892c12b7..5cdf559863 100755 --- a/ci/extract_test_examples.sh +++ b/ci/extract_test_examples.sh @@ -1,4 +1,6 @@ #!/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 # diff --git a/ci/install_blosc.sh b/ci/install_blosc.sh index 0436fa875e..e40d233f5b 100755 --- a/ci/install_blosc.sh +++ b/ci/install_blosc.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/install_cppunit.sh b/ci/install_cppunit.sh index 7f64238e8a..da7cc300b3 100755 --- a/ci/install_cppunit.sh +++ b/ci/install_cppunit.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex CURL_VERSION="$1" diff --git a/ci/install_doxygen.sh b/ci/install_doxygen.sh index 5c3ab3136d..d89ac38510 100755 --- a/ci/install_doxygen.sh +++ b/ci/install_doxygen.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/install_glfw.sh b/ci/install_glfw.sh index 33108657f4..faeb243ae7 100755 --- a/ci/install_glfw.sh +++ b/ci/install_glfw.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex GLFW_VERSION="$1" diff --git a/ci/install_gtest.sh b/ci/install_gtest.sh index 71d7fbd7bb..9084b31cf4 100755 --- a/ci/install_gtest.sh +++ b/ci/install_gtest.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/install_llvm_windows.sh b/ci/install_llvm_windows.sh index c174c50296..d8866520f0 100644 --- a/ci/install_llvm_windows.sh +++ b/ci/install_llvm_windows.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/install_macos.sh b/ci/install_macos.sh index 80b71d4864..a581229035 100755 --- a/ci/install_macos.sh +++ b/ci/install_macos.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -x diff --git a/ci/install_nanobind.sh b/ci/install_nanobind.sh index 50b6766b81..8a885a6b4a 100755 --- a/ci/install_nanobind.sh +++ b/ci/install_nanobind.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/ci/install_tbb_macos.sh b/ci/install_tbb_macos.sh index 4b71fe9e93..cb8d8d9595 100755 --- a/ci/install_tbb_macos.sh +++ b/ci/install_tbb_macos.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -x diff --git a/ci/test_install.sh b/ci/test_install.sh index da4bc0f004..5ff44aecd4 100755 --- a/ci/test_install.sh +++ b/ci/test_install.sh @@ -1,4 +1,6 @@ #!/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 diff --git a/ci/test_sonar.sh b/ci/test_sonar.sh index 15cc571d23..c8f72a0c86 100755 --- a/ci/test_sonar.sh +++ b/ci/test_sonar.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 set -ex diff --git a/nanovdb/nanovdb/cmd/updateFiles.py b/nanovdb/nanovdb/cmd/updateFiles.py index e4041c91f6..16fe6b8806 100644 --- a/nanovdb/nanovdb/cmd/updateFiles.py +++ b/nanovdb/nanovdb/cmd/updateFiles.py @@ -1,3 +1,5 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 import argparse import os from pathlib import Path diff --git a/nanovdb/nanovdb/cmd/updateFiles.sh b/nanovdb/nanovdb/cmd/updateFiles.sh index 87613c3a44..b75a65656f 100755 --- a/nanovdb/nanovdb/cmd/updateFiles.sh +++ b/nanovdb/nanovdb/cmd/updateFiles.sh @@ -1,4 +1,6 @@ #!/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 diff --git a/nanovdb/nanovdb/docs/CMakeLists.txt b/nanovdb/nanovdb/docs/CMakeLists.txt index 6a131e68e7..81910cbe3b 100644 --- a/nanovdb/nanovdb/docs/CMakeLists.txt +++ b/nanovdb/nanovdb/docs/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 # find_package(doxygen REQUIRED dot ) if(WIN32) set(DOXYGEN_EXECUTABLE "C:/Program Files/doxygen/bin/doxygen.exe") diff --git a/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor/read_nanovdb_sphere_accessor.cc b/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor/read_nanovdb_sphere_accessor.cc index 91010b6cf7..dc763ddc8a 100644 --- a/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor/read_nanovdb_sphere_accessor.cc +++ b/nanovdb/nanovdb/examples/ex_read_nanovdb_sphere_accessor/read_nanovdb_sphere_accessor.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include // 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. diff --git a/nanovdb/nanovdb/python/CMakeLists.txt b/nanovdb/nanovdb/python/CMakeLists.txt index d5c50792ee..f13cf10116 100644 --- a/nanovdb/nanovdb/python/CMakeLists.txt +++ b/nanovdb/nanovdb/python/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 option(NANOVDB_BUILD_PYTHON_UNITTESTS [=[ "Include the NanoVDB Python unit test. Requires a python interpreter]=] ${NANOVDB_BUILD_UNITTESTS}) diff --git a/nanovdb/nanovdb/python/NanoVDBModule.cc b/nanovdb/nanovdb/python/NanoVDBModule.cc index 583b5464f9..89af0ec095 100644 --- a/nanovdb/nanovdb/python/NanoVDBModule.cc +++ b/nanovdb/nanovdb/python/NanoVDBModule.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include #include #include diff --git a/nanovdb/nanovdb/python/PyCreateNanoGrid.cc b/nanovdb/nanovdb/python/PyCreateNanoGrid.cc index c776865306..eed931766c 100644 --- a/nanovdb/nanovdb/python/PyCreateNanoGrid.cc +++ b/nanovdb/nanovdb/python/PyCreateNanoGrid.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyCreateNanoGrid.h" #include diff --git a/nanovdb/nanovdb/python/PyCreateNanoGrid.h b/nanovdb/nanovdb/python/PyCreateNanoGrid.h index 863ca1b396..3402ca67b8 100644 --- a/nanovdb/nanovdb/python/PyCreateNanoGrid.h +++ b/nanovdb/nanovdb/python/PyCreateNanoGrid.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYCREATENANOGRID_HAS_BEEN_INCLUDED #define NANOVDB_PYCREATENANOGRID_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyGridChecksum.cc b/nanovdb/nanovdb/python/PyGridChecksum.cc index ba6e709b10..281fd05c0b 100644 --- a/nanovdb/nanovdb/python/PyGridChecksum.cc +++ b/nanovdb/nanovdb/python/PyGridChecksum.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyGridChecksum.h" #include diff --git a/nanovdb/nanovdb/python/PyGridChecksum.h b/nanovdb/nanovdb/python/PyGridChecksum.h index f8c2048b83..dd988f871c 100644 --- a/nanovdb/nanovdb/python/PyGridChecksum.h +++ b/nanovdb/nanovdb/python/PyGridChecksum.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYGRIDCHECKSUM_HAS_BEEN_INCLUDED #define NANOVDB_PYGRIDCHECKSUM_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyGridHandle.cc b/nanovdb/nanovdb/python/PyGridHandle.cc index 4f4e8ff72d..efd4253337 100644 --- a/nanovdb/nanovdb/python/PyGridHandle.cc +++ b/nanovdb/nanovdb/python/PyGridHandle.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyGridHandle.h" #include diff --git a/nanovdb/nanovdb/python/PyGridHandle.h b/nanovdb/nanovdb/python/PyGridHandle.h index a15c588c83..190c6ab15f 100644 --- a/nanovdb/nanovdb/python/PyGridHandle.h +++ b/nanovdb/nanovdb/python/PyGridHandle.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYGRIDHANDLE_HAS_BEEN_INCLUDED #define NANOVDB_PYGRIDHANDLE_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyGridStats.cc b/nanovdb/nanovdb/python/PyGridStats.cc index 7f8598a7ac..fbd8caec15 100644 --- a/nanovdb/nanovdb/python/PyGridStats.cc +++ b/nanovdb/nanovdb/python/PyGridStats.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyGridStats.h" #include diff --git a/nanovdb/nanovdb/python/PyGridStats.h b/nanovdb/nanovdb/python/PyGridStats.h index c53af4567d..90254bc23b 100644 --- a/nanovdb/nanovdb/python/PyGridStats.h +++ b/nanovdb/nanovdb/python/PyGridStats.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYGRIDSTATS_HAS_BEEN_INCLUDED #define NANOVDB_PYGRIDSTATS_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyGridValidator.cc b/nanovdb/nanovdb/python/PyGridValidator.cc index 278588b466..8e4f20df64 100644 --- a/nanovdb/nanovdb/python/PyGridValidator.cc +++ b/nanovdb/nanovdb/python/PyGridValidator.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyGridValidator.h" #include diff --git a/nanovdb/nanovdb/python/PyGridValidator.h b/nanovdb/nanovdb/python/PyGridValidator.h index 6725f88b4d..659dede241 100644 --- a/nanovdb/nanovdb/python/PyGridValidator.h +++ b/nanovdb/nanovdb/python/PyGridValidator.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYGRIDVALIDATOR_HAS_BEEN_INCLUDED #define NANOVDB_PYGRIDVALIDATOR_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyHostBuffer.cc b/nanovdb/nanovdb/python/PyHostBuffer.cc index 4af48c2040..e8fdfb3946 100644 --- a/nanovdb/nanovdb/python/PyHostBuffer.cc +++ b/nanovdb/nanovdb/python/PyHostBuffer.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyHostBuffer.h" #include diff --git a/nanovdb/nanovdb/python/PyHostBuffer.h b/nanovdb/nanovdb/python/PyHostBuffer.h index f1bf704edc..29b5a917ce 100644 --- a/nanovdb/nanovdb/python/PyHostBuffer.h +++ b/nanovdb/nanovdb/python/PyHostBuffer.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYHOSTBUFFER_HAS_BEEN_INCLUDED #define NANOVDB_PYHOSTBUFFER_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyIO.cc b/nanovdb/nanovdb/python/PyIO.cc index d77cb40f86..b46a52ba74 100644 --- a/nanovdb/nanovdb/python/PyIO.cc +++ b/nanovdb/nanovdb/python/PyIO.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyIO.h" #include diff --git a/nanovdb/nanovdb/python/PyIO.h b/nanovdb/nanovdb/python/PyIO.h index 907ef0f7f9..de857a5148 100644 --- a/nanovdb/nanovdb/python/PyIO.h +++ b/nanovdb/nanovdb/python/PyIO.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYIO_HAS_BEEN_INCLUDED #define NANOVDB_PYIO_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyMath.cc b/nanovdb/nanovdb/python/PyMath.cc index 06a4ad5606..337865ed8c 100644 --- a/nanovdb/nanovdb/python/PyMath.cc +++ b/nanovdb/nanovdb/python/PyMath.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyMath.h" #include diff --git a/nanovdb/nanovdb/python/PyMath.h b/nanovdb/nanovdb/python/PyMath.h index e9a2cde791..13c288e110 100644 --- a/nanovdb/nanovdb/python/PyMath.h +++ b/nanovdb/nanovdb/python/PyMath.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYMATH_HAS_BEEN_INCLUDED #define NANOVDB_PYMATH_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyNanoToOpenVDB.cc b/nanovdb/nanovdb/python/PyNanoToOpenVDB.cc index 8225cd78ca..49dc464a05 100644 --- a/nanovdb/nanovdb/python/PyNanoToOpenVDB.cc +++ b/nanovdb/nanovdb/python/PyNanoToOpenVDB.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyNanoToOpenVDB.h" #include diff --git a/nanovdb/nanovdb/python/PyNanoToOpenVDB.h b/nanovdb/nanovdb/python/PyNanoToOpenVDB.h index ac60fdbf96..54c38501e5 100644 --- a/nanovdb/nanovdb/python/PyNanoToOpenVDB.h +++ b/nanovdb/nanovdb/python/PyNanoToOpenVDB.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYNANOTOOPENVDB_HAS_BEEN_INCLUDED #define NANOVDB_PYNANOTOOPENVDB_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyPrimitives.cc b/nanovdb/nanovdb/python/PyPrimitives.cc index 3b7f11c0d9..29053d4e68 100644 --- a/nanovdb/nanovdb/python/PyPrimitives.cc +++ b/nanovdb/nanovdb/python/PyPrimitives.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyPrimitives.h" #include diff --git a/nanovdb/nanovdb/python/PyPrimitives.h b/nanovdb/nanovdb/python/PyPrimitives.h index 8be1e0208c..a930ee5d8d 100644 --- a/nanovdb/nanovdb/python/PyPrimitives.h +++ b/nanovdb/nanovdb/python/PyPrimitives.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYPRIMITIVES_HAS_BEEN_INCLUDED #define NANOVDB_PYPRIMITIVES_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PySampleFromVoxels.cc b/nanovdb/nanovdb/python/PySampleFromVoxels.cc index 2a3b7e5b6e..82dc9a26d1 100644 --- a/nanovdb/nanovdb/python/PySampleFromVoxels.cc +++ b/nanovdb/nanovdb/python/PySampleFromVoxels.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PySampleFromVoxels.h" #include diff --git a/nanovdb/nanovdb/python/PySampleFromVoxels.h b/nanovdb/nanovdb/python/PySampleFromVoxels.h index 140db2f3be..6c5733f714 100644 --- a/nanovdb/nanovdb/python/PySampleFromVoxels.h +++ b/nanovdb/nanovdb/python/PySampleFromVoxels.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYSAMPLEFROMVOXELS_HAS_BEEN_INCLUDED #define NANOVDB_PYSAMPLEFROMVOXELS_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/PyTools.cc b/nanovdb/nanovdb/python/PyTools.cc index de74380987..4df996d557 100644 --- a/nanovdb/nanovdb/python/PyTools.cc +++ b/nanovdb/nanovdb/python/PyTools.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyTools.h" #include diff --git a/nanovdb/nanovdb/python/PyTools.h b/nanovdb/nanovdb/python/PyTools.h index be6e49ff53..bfb9d42ef8 100644 --- a/nanovdb/nanovdb/python/PyTools.h +++ b/nanovdb/nanovdb/python/PyTools.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_PYTOOLS_HAS_BEEN_INCLUDED #define NANOVDB_PYTOOLS_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/__init__.py b/nanovdb/nanovdb/python/__init__.py index 7bce6a9559..4f955e4a02 100644 --- a/nanovdb/nanovdb/python/__init__.py +++ b/nanovdb/nanovdb/python/__init__.py @@ -1,3 +1,5 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 import sys if sys.platform == "win32": import os diff --git a/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.cc b/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.cc index 58a6d984f3..523e4b5834 100644 --- a/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.cc +++ b/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.cc @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifdef NANOVDB_USE_CUDA #include "PyDeviceBuffer.h" diff --git a/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.h b/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.h index c65239cb69..87a081f638 100644 --- a/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.h +++ b/nanovdb/nanovdb/python/cuda/PyDeviceBuffer.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_CUDA_PYDEVICEBUFFER_HAS_BEEN_INCLUDED #define NANOVDB_CUDA_PYDEVICEBUFFER_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/cuda/PyDeviceGridHandle.cu b/nanovdb/nanovdb/python/cuda/PyDeviceGridHandle.cu index a8dc924d7f..983caebd05 100644 --- a/nanovdb/nanovdb/python/cuda/PyDeviceGridHandle.cu +++ b/nanovdb/nanovdb/python/cuda/PyDeviceGridHandle.cu @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifdef NANOVDB_USE_CUDA #include "../PyGridHandle.h" diff --git a/nanovdb/nanovdb/python/cuda/PyPointsToGrid.cu b/nanovdb/nanovdb/python/cuda/PyPointsToGrid.cu index 82a5826fc4..933f5570b6 100644 --- a/nanovdb/nanovdb/python/cuda/PyPointsToGrid.cu +++ b/nanovdb/nanovdb/python/cuda/PyPointsToGrid.cu @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PyPointsToGrid.h" #include diff --git a/nanovdb/nanovdb/python/cuda/PyPointsToGrid.h b/nanovdb/nanovdb/python/cuda/PyPointsToGrid.h index 4bb530ac22..4af07f5657 100644 --- a/nanovdb/nanovdb/python/cuda/PyPointsToGrid.h +++ b/nanovdb/nanovdb/python/cuda/PyPointsToGrid.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_CUDA_PYPOINTSTOGRID_HAS_BEEN_INCLUDED #define NANOVDB_CUDA_PYPOINTSTOGRID_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.cu b/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.cu index 8bab06e51e..aaebf66772 100644 --- a/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.cu +++ b/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.cu @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PySampleFromVoxels.h" #include diff --git a/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.h b/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.h index c23a97e849..22cc4aec4d 100644 --- a/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.h +++ b/nanovdb/nanovdb/python/cuda/PySampleFromVoxels.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_CUDA_PYSAMPLEFROMVOXELS_HAS_BEEN_INCLUDED #define NANOVDB_CUDA_PYSAMPLEFROMVOXELS_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/cuda/PySignedFloodFill.cu b/nanovdb/nanovdb/python/cuda/PySignedFloodFill.cu index 2b68ca38df..ddbd5c67cb 100644 --- a/nanovdb/nanovdb/python/cuda/PySignedFloodFill.cu +++ b/nanovdb/nanovdb/python/cuda/PySignedFloodFill.cu @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #include "PySignedFloodFill.h" #include diff --git a/nanovdb/nanovdb/python/cuda/PySignedFloodFill.h b/nanovdb/nanovdb/python/cuda/PySignedFloodFill.h index 7ae16defe7..d5f19bcbe2 100644 --- a/nanovdb/nanovdb/python/cuda/PySignedFloodFill.h +++ b/nanovdb/nanovdb/python/cuda/PySignedFloodFill.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef NANOVDB_CUDA_PYSIGNEDFLOODFILL_HAS_BEEN_INCLUDED #define NANOVDB_CUDA_PYSIGNEDFLOODFILL_HAS_BEEN_INCLUDED diff --git a/nanovdb/nanovdb/python/test/TestNanoVDB.py b/nanovdb/nanovdb/python/test/TestNanoVDB.py index fca793295e..03660c6342 100644 --- a/nanovdb/nanovdb/python/test/TestNanoVDB.py +++ b/nanovdb/nanovdb/python/test/TestNanoVDB.py @@ -1,4 +1,6 @@ -# /usr/bin/env python +#!/usr/bin/env python +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 import nanovdb import unittest diff --git a/openvdb/openvdb/python/__init__.py b/openvdb/openvdb/python/__init__.py index 1b25ddfcc5..39242a9737 100644 --- a/openvdb/openvdb/python/__init__.py +++ b/openvdb/openvdb/python/__init__.py @@ -1 +1,3 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 from .lib.openvdb import * diff --git a/openvdb/openvdb/python/pyTypeCasters.h b/openvdb/openvdb/python/pyTypeCasters.h index c9faf3f0bd..56159666bd 100644 --- a/openvdb/openvdb/python/pyTypeCasters.h +++ b/openvdb/openvdb/python/pyTypeCasters.h @@ -1,3 +1,5 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: Apache-2.0 #ifndef OPENVDB_PYTYPECASTERS_HAS_BEEN_INCLUDED #define OPENVDB_PYTYPECASTERS_HAS_BEEN_INCLUDED diff --git a/openvdb_cmd/vdb_tool/CMakeLists.txt b/openvdb_cmd/vdb_tool/CMakeLists.txt index c0a2d64277..8101a78816 100644 --- a/openvdb_cmd/vdb_tool/CMakeLists.txt +++ b/openvdb_cmd/vdb_tool/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright Contributors to the OpenVDB Project +# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20) # CMP0091 allows for MSVC ABI targetting via CMAKE_MSVC_RUNTIME_LIBRARY From b78b48204e89a54b36f88fd3802950716eef42c0 Mon Sep 17 00:00:00 2001 From: Jonathan Swartz Date: Wed, 18 Dec 2024 13:08:04 +1300 Subject: [PATCH 92/98] Fix typo in SPDX license identifier Signed-off-by: Jonathan Swartz --- openvdb_ax/openvdb_ax/compiler/AttributeBindings.h | 2 +- openvdb_ax/openvdb_ax/compiler/AttributeRegistry.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openvdb_ax/openvdb_ax/compiler/AttributeBindings.h b/openvdb_ax/openvdb_ax/compiler/AttributeBindings.h index ebd7bba23b..dd295b2501 100644 --- a/openvdb_ax/openvdb_ax/compiler/AttributeBindings.h +++ b/openvdb_ax/openvdb_ax/compiler/AttributeBindings.h @@ -1,5 +1,5 @@ // Copyright Contributors to the OpenVDB Project -// SPDX-License-Identifier: Apache-2.0/ +// SPDX-License-Identifier: Apache-2.0 /// @file compiler/AttributeBindings.h /// diff --git a/openvdb_ax/openvdb_ax/compiler/AttributeRegistry.h b/openvdb_ax/openvdb_ax/compiler/AttributeRegistry.h index 6f40790d2d..1f03655f54 100644 --- a/openvdb_ax/openvdb_ax/compiler/AttributeRegistry.h +++ b/openvdb_ax/openvdb_ax/compiler/AttributeRegistry.h @@ -1,5 +1,5 @@ // Copyright Contributors to the OpenVDB Project -// SPDX-License-Identifier: Apache-2.0/ +// SPDX-License-Identifier: Apache-2.0 /// @file compiler/AttributeRegistry.h /// From e0824b0b5082949ee3650de107d32a7676d44f4b Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:18:01 -0400 Subject: [PATCH 93/98] Initial support for HalfGrid and ComputeType Initial support for HalfGrid and ComputeType, where the latter enables float computations for HalfGrid which increases accuracy and speed. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/CMakeLists.txt | 1 + openvdb/openvdb/Grid.h | 6 +- openvdb/openvdb/Metadata.h | 1 + openvdb/openvdb/Types.h | 53 ++++---- openvdb/openvdb/math/HalfDecl.h | 30 ++++ openvdb/openvdb/math/Math.h | 110 ++++++++++++--- openvdb/openvdb/math/Stencils.h | 36 ++--- openvdb/openvdb/openvdb.h | 5 +- openvdb/openvdb/tools/FastSweeping.h | 174 ++++++++++++------------ openvdb/openvdb/tools/Interpolation.h | 42 ++++-- openvdb/openvdb/tools/LevelSetAdvect.h | 76 ++++++----- openvdb/openvdb/tools/LevelSetFilter.h | 54 ++++---- openvdb/openvdb/tools/LevelSetMeasure.h | 29 ++-- openvdb/openvdb/tools/LevelSetMorph.h | 98 ++++++------- openvdb/openvdb/tools/LevelSetSphere.h | 27 ++-- openvdb/openvdb/tools/LevelSetTracker.h | 50 +++---- openvdb/openvdb/tools/LevelSetUtil.h | 3 +- openvdb/openvdb/tools/MeshToVolume.h | 6 +- openvdb/openvdb/tools/RayIntersector.h | 56 ++++---- openvdb/openvdb/tools/RayTracer.h | 25 +++- openvdb/openvdb/tools/SignedFloodFill.h | 25 ++-- openvdb/openvdb/tools/VolumeAdvect.h | 22 +-- openvdb/openvdb/tools/VolumeToSpheres.h | 1 + openvdb/openvdb/tree/InternalNode.h | 1 + openvdb/openvdb/tree/LeafManager.h | 1 + openvdb/openvdb/tree/LeafNode.h | 1 + openvdb/openvdb/tree/LeafNodeBool.h | 1 + openvdb/openvdb/tree/LeafNodeMask.h | 1 + openvdb/openvdb/tree/RootNode.h | 1 + openvdb/openvdb/tree/Tree.h | 1 + openvdb/openvdb/tree/ValueAccessor.h | 1 + 31 files changed, 559 insertions(+), 379 deletions(-) create mode 100644 openvdb/openvdb/math/HalfDecl.h diff --git a/openvdb/openvdb/CMakeLists.txt b/openvdb/openvdb/CMakeLists.txt index 3db0e4e144..f45257e413 100644 --- a/openvdb/openvdb/CMakeLists.txt +++ b/openvdb/openvdb/CMakeLists.txt @@ -405,6 +405,7 @@ set(OPENVDB_LIBRARY_MATH_INCLUDE_FILES math/DDA.h math/FiniteDifference.h math/Half.h + math/HalfDecl.h math/LegacyFrustum.h math/Maps.h math/Mat.h diff --git a/openvdb/openvdb/Grid.h b/openvdb/openvdb/Grid.h index cb2d2eba74..4bb72719bc 100644 --- a/openvdb/openvdb/Grid.h +++ b/openvdb/openvdb/Grid.h @@ -577,6 +577,7 @@ class Grid: public GridBase using TreePtrType = typename _TreeType::Ptr; using ConstTreePtrType = typename _TreeType::ConstPtr; using ValueType = typename _TreeType::ValueType; + using ComputeType = typename _TreeType::ComputeType; using BuildType = typename _TreeType::BuildType; using ValueOnIter = typename _TreeType::ValueOnIter; @@ -1781,10 +1782,11 @@ template typename GridType::Ptr createLevelSet(Real voxelSize, Real halfWidth) { - using ValueType = typename GridType::ValueType; + using ValueType = typename GridType::ValueType; + using ComputeType = typename GridType::ComputeType; // GridType::ValueType is required to be a floating-point scalar. - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "level-set grids must be floating-point-valued"); typename GridType::Ptr grid = GridType::create( diff --git a/openvdb/openvdb/Metadata.h b/openvdb/openvdb/Metadata.h index d17082e150..6106944243 100644 --- a/openvdb/openvdb/Metadata.h +++ b/openvdb/openvdb/Metadata.h @@ -359,6 +359,7 @@ operator<<(std::ostream& ostr, const Metadata& metadata) using BoolMetadata = TypedMetadata; using DoubleMetadata = TypedMetadata; using FloatMetadata = TypedMetadata; +using HalfMetadata = TypedMetadata; using Int32Metadata = TypedMetadata; using Int64Metadata = TypedMetadata; using StringMetadata = TypedMetadata; diff --git a/openvdb/openvdb/Types.h b/openvdb/openvdb/Types.h index 9d05033c7d..26b6b5d74a 100644 --- a/openvdb/openvdb/Types.h +++ b/openvdb/openvdb/Types.h @@ -8,27 +8,7 @@ #include "Platform.h" #include "TypeList.h" // backwards compat -#ifdef OPENVDB_USE_IMATH_HALF -#ifdef OPENVDB_IMATH_VERSION -#include -#else -#include -#endif -namespace openvdb { -OPENVDB_USE_VERSION_NAMESPACE -namespace OPENVDB_VERSION_NAME { -namespace math { -using half = half; -}}} -#else -#include -namespace openvdb { -OPENVDB_USE_VERSION_NAMESPACE -namespace OPENVDB_VERSION_NAME { -namespace math { -using half = internal::half; -}}} -#endif +#include #include #include @@ -58,12 +38,13 @@ using Int64 = int64_t; using Int = Int32; using Byte = unsigned char; using Real = double; +using Half = math::half; // Two-dimensional vector types using Vec2R = math::Vec2; using Vec2I = math::Vec2; using Vec2f = math::Vec2; -using Vec2H = math::Vec2; +using Vec2H = math::Vec2; using math::Vec2i; using math::Vec2s; using math::Vec2d; @@ -72,7 +53,7 @@ using math::Vec2d; using Vec3R = math::Vec3; using Vec3I = math::Vec3; using Vec3f = math::Vec3; -using Vec3H = math::Vec3; +using Vec3H = math::Vec3; using Vec3U8 = math::Vec3; using Vec3U16 = math::Vec3; using math::Vec3i; @@ -87,7 +68,7 @@ using BBoxd = math::BBox; using Vec4R = math::Vec4; using Vec4I = math::Vec4; using Vec4f = math::Vec4; -using Vec4H = math::Vec4; +using Vec4H = math::Vec4; using math::Vec4i; using math::Vec4s; using math::Vec4d; @@ -446,6 +427,22 @@ template struct CopyConstness +struct ValueToComputeMap +{ + using Type = T; +}; + +template<> +struct ValueToComputeMap +{ + using Type = float; +}; + + //////////////////////////////////////// @@ -691,11 +688,11 @@ class PartialCreate {}; // For half compilation namespace math { template<> -inline auto cwiseAdd(const math::Vec3& v, const float s) +inline auto cwiseAdd(const Vec3H& v, const float s) { - math::Vec3 out; - const math::half* ip = v.asPointer(); - math::half* op = out.asPointer(); + Vec3H out; + const Half* ip = v.asPointer(); + Half* op = out.asPointer(); for (unsigned i = 0; i < 3; ++i, ++op, ++ip) { OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN *op = *ip + s; diff --git a/openvdb/openvdb/math/HalfDecl.h b/openvdb/openvdb/math/HalfDecl.h new file mode 100644 index 0000000000..f9d654557f --- /dev/null +++ b/openvdb/openvdb/math/HalfDecl.h @@ -0,0 +1,30 @@ +// Copyright Contributors to the OpenVDB Project +// SPDX-License-Identifier: MPL-2.0 + +#ifndef OPENVDB_HALFDECL_HAS_BEEN_INCLUDED +#define OPENVDB_HALFDECL_HAS_BEEN_INCLUDED + +#ifdef OPENVDB_USE_IMATH_HALF +#ifdef OPENVDB_IMATH_VERSION +#include +#else +#include +#endif +namespace openvdb { +OPENVDB_USE_VERSION_NAMESPACE +namespace OPENVDB_VERSION_NAME { +namespace math { +using half = half; +}}} +#else +#include +namespace openvdb { +OPENVDB_USE_VERSION_NAMESPACE +namespace OPENVDB_VERSION_NAME { +namespace math { +using half = internal::half; +}}} +#endif + + +#endif // OPENVDB_HALFDECL_HAS_BEEN_INCLUDED diff --git a/openvdb/openvdb/math/Math.h b/openvdb/openvdb/math/Math.h index 4d5e3423a9..7bc29a3e33 100644 --- a/openvdb/openvdb/math/Math.h +++ b/openvdb/openvdb/math/Math.h @@ -10,6 +10,7 @@ #include #include +#include #include #include // for std::max() #include @@ -145,16 +146,18 @@ template<> inline std::string negative(const std::string& val) { return val; } //@{ /// Tolerance for floating-point comparison -template struct Tolerance { static T value() { return zeroVal(); } }; -template<> struct Tolerance { static float value() { return 1e-8f; } }; -template<> struct Tolerance { static double value() { return 1e-15; } }; +template struct Tolerance { static T value() { return zeroVal(); } }; +template<> struct Tolerance { static math::half value() { return 0.00097656; } }; +template<> struct Tolerance { static float value() { return 1e-8f; } }; +template<> struct Tolerance { static double value() { return 1e-15; } }; //@} //@{ /// Delta for small floating-point offsets -template struct Delta { static T value() { return zeroVal(); } }; -template<> struct Delta { static float value() { return 1e-5f; } }; -template<> struct Delta { static double value() { return 1e-9; } }; +template struct Delta { static T value() { return zeroVal(); } }; +template<> struct Delta { static math::half value() { return 0.00390625; } }; +template<> struct Delta { static float value() { return 1e-5f; } }; +template<> struct Delta { static double value() { return 1e-9; } }; //@} @@ -312,6 +315,11 @@ inline int64_t Abs(int64_t i) "std::abs(int64) broken"); return std::abs(i); } + +// isNegative and operator-() are bitwise ops +// all half types in HalfDecl.h _could_ define abs() as half(FromBits, bits() & 0x7fff) +inline math::half Abs(math::half x) { return x.isNegative() ? -x : x; } + inline float Abs(float x) { return std::fabs(x); } inline double Abs(double x) { return std::fabs(x); } inline long double Abs(long double x) { return std::fabs(x); } @@ -361,6 +369,10 @@ isApproxZero(const Type& x, const Type& tolerance) } +/// Return @c true if @a x is less than zero. +inline bool +isNegative(math::half& x) { return x.isNegative(); } + /// Return @c true if @a x is less than zero. template inline bool @@ -374,6 +386,10 @@ template<> inline bool isNegative(const bool&) { return false; } inline bool isFinite(const float x) { return std::isfinite(x); } +/// Return @c true if @a x is finite. +inline bool +isFinite(const math::half x) { return x.isFinite(); } + /// Return @c true if @a x is finite. template::value, int>::type = 0> inline bool @@ -384,6 +400,10 @@ isFinite(const Type& x) { return std::isfinite(static_cast(x)); } inline bool isInfinite(const float x) { return std::isinf(x); } +/// Return @c true if @a x is an infinity value (either positive infinity or negative infinity). +inline bool +isInfinite(const math::half x) { return x.isInfinity(); } + /// Return @c true if @a x is an infinity value (either positive infinity or negative infinity). template::value, int>::type = 0> inline bool @@ -394,6 +414,10 @@ isInfinite(const Type& x) { return std::isinf(static_cast(x)); } inline bool isNan(const float x) { return std::isnan(x); } +/// Return @c true if @a x is a NaN (Not-A-Number) value. +inline bool +isNan(const math::half x) { return x.isNan(); } + /// Return @c true if @a x is a NaN (Not-A-Number) value. template::value, int>::type = 0> inline bool @@ -569,6 +593,15 @@ Pow(Type x, int n) return ans; } +//@{ +/// Return @a be. +inline math::half +Pow(math::half b, math::half e) +{ + OPENVDB_ASSERT( b >= 0.0f && "Pow(half,half): base is negative" ); + return math::half(powf(float(b),float(e))); +} + //@{ /// Return @a be. inline float @@ -589,12 +622,29 @@ Pow(double b, double e) // ==========> Max <================== +namespace internal { + +inline const math::half& +max_impl(const math::half& a, const math::half& b) +{ + return a > b ? a : b; +} + +template +inline const Type& +max_impl(const Type& a, const Type& b) +{ + return std::max(a,b); +} + +} // namespace internal + /// Return the maximum of two values template inline const Type& Max(const Type& a, const Type& b) { - return std::max(a,b); + return internal::max_impl(a,b); } /// Return the maximum of three values @@ -602,7 +652,7 @@ template inline const Type& Max(const Type& a, const Type& b, const Type& c) { - return std::max(std::max(a,b), c); + return internal::max_impl(internal::max_impl(a,b), c); } /// Return the maximum of four values @@ -610,7 +660,7 @@ template inline const Type& Max(const Type& a, const Type& b, const Type& c, const Type& d) { - return std::max(std::max(a,b), std::max(c,d)); + return internal::max_impl(internal::max_impl(a,b), internal::max_impl(c,d)); } /// Return the maximum of five values @@ -618,7 +668,7 @@ template inline const Type& Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e) { - return std::max(std::max(a,b), Max(c,d,e)); + return internal::max_impl(internal::max_impl(a,b), Max(c,d,e)); } /// Return the maximum of six values @@ -626,7 +676,7 @@ template inline const Type& Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f) { - return std::max(Max(a,b,c), Max(d,e,f)); + return internal::max_impl(Max(a,b,c), Max(d,e,f)); } /// Return the maximum of seven values @@ -635,7 +685,7 @@ inline const Type& Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f, const Type& g) { - return std::max(Max(a,b,c,d), Max(e,f,g)); + return internal::max_impl(Max(a,b,c,d), Max(e,f,g)); } /// Return the maximum of eight values @@ -644,28 +694,48 @@ inline const Type& Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f, const Type& g, const Type& h) { - return std::max(Max(a,b,c,d), Max(e,f,g,h)); + return internal::max_impl(Max(a,b,c,d), Max(e,f,g,h)); } // ==========> Min <================== +namespace internal { + +inline const math::half& +min_impl(const math::half& a, const math::half& b) +{ + return a < b ? a : b; +} + +template +inline const Type& +min_impl(const Type& a, const Type& b) +{ + return std::min(a,b); +} + +} // namespace internal + /// Return the minimum of two values template inline const Type& -Min(const Type& a, const Type& b) { return std::min(a, b); } +Min(const Type& a, const Type& b) { return internal::min_impl(a, b); } /// Return the minimum of three values template inline const Type& -Min(const Type& a, const Type& b, const Type& c) { return std::min(std::min(a, b), c); } +Min(const Type& a, const Type& b, const Type& c) +{ + return internal::min_impl(internal::min_impl(a, b), c); +} /// Return the minimum of four values template inline const Type& Min(const Type& a, const Type& b, const Type& c, const Type& d) { - return std::min(std::min(a, b), std::min(c, d)); + return internal::min_impl(internal::min_impl(a, b), internal::min_impl(c, d)); } /// Return the minimum of five values @@ -673,7 +743,7 @@ template inline const Type& Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e) { - return std::min(std::min(a,b), Min(c,d,e)); + return internal::min_impl(internal::min_impl(a,b), Min(c,d,e)); } /// Return the minimum of six values @@ -681,7 +751,7 @@ template inline const Type& Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f) { - return std::min(Min(a,b,c), Min(d,e,f)); + return internal::min_impl(Min(a,b,c), Min(d,e,f)); } /// Return the minimum of seven values @@ -690,7 +760,7 @@ inline const Type& Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f, const Type& g) { - return std::min(Min(a,b,c,d), Min(e,f,g)); + return internal::min_impl(Min(a,b,c,d), Min(e,f,g)); } /// Return the minimum of eight values @@ -699,7 +769,7 @@ inline const Type& Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f, const Type& g, const Type& h) { - return std::min(Min(a,b,c,d), Min(e,f,g,h)); + return internal::min_impl(Min(a,b,c,d), Min(e,f,g,h)); } diff --git a/openvdb/openvdb/math/Stencils.h b/openvdb/openvdb/math/Stencils.h index 0c4ed2c0c8..285aecb965 100644 --- a/openvdb/openvdb/math/Stencils.h +++ b/openvdb/openvdb/math/Stencils.h @@ -37,7 +37,7 @@ class BaseStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridT::ValueType ValueType; + typedef typename GridT::ComputeType ValueType; typedef tree::ValueAccessor AccessorType; typedef std::vector BufferType; @@ -250,7 +250,7 @@ class SevenPointStencil: public BaseStencil, Gr public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridT::ValueType ValueType; + typedef typename GridT::ComputeType ValueType; static const int SIZE = 7; @@ -304,7 +304,7 @@ class BoxStencil: public BaseStencil, GridT, IsSafe> public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridT::ValueType ValueType; + typedef typename GridT::ComputeType ValueType; static const int SIZE = 8; @@ -475,7 +475,7 @@ class SecondOrderDenseStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 19; @@ -555,7 +555,7 @@ class ThirteenPointStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 13; @@ -686,7 +686,7 @@ class FourthOrderDenseStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 61; @@ -825,7 +825,7 @@ class NineteenPointStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 19; @@ -1041,7 +1041,7 @@ class SixthOrderDenseStencil public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 127; @@ -1235,7 +1235,7 @@ class GradStencil : public BaseStencil, GridT, IsSafe public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 7; @@ -1369,7 +1369,7 @@ class WenoStencil: public BaseStencil, GridT, IsSafe> public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; static const int SIZE = 19; @@ -1519,7 +1519,7 @@ class CurvatureStencil: public BaseStencil, Grid public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridT::ValueType ValueType; + typedef typename GridT::ComputeType ValueType; static const int SIZE = 19; @@ -1545,7 +1545,7 @@ class CurvatureStencil: public BaseStencil, Grid { Real alpha, normGrad; return this->meanCurvature(alpha, normGrad) ? - ValueType(alpha*mInv2Dx/math::Pow3(normGrad)) : 0; + ValueType(alpha*mInv2Dx/math::Pow3(normGrad)) : ValueType(0); } /// @brief Return the Gaussian curvature at the previously buffered location. @@ -1556,7 +1556,7 @@ class CurvatureStencil: public BaseStencil, Grid { Real alpha, normGrad; return this->gaussianCurvature(alpha, normGrad) ? - ValueType(alpha*mInvDx2/math::Pow4(normGrad)) : 0; + ValueType(alpha*mInvDx2/math::Pow4(normGrad)) : ValueType(0); } /// @brief Return both the mean and the Gaussian curvature at the @@ -1571,7 +1571,7 @@ class CurvatureStencil: public BaseStencil, Grid mean = ValueType(alphaM*mInv2Dx/math::Pow3(normGrad)); gauss = ValueType(alphaG*mInvDx2/math::Pow4(normGrad)); } else { - mean = gauss = 0; + mean = gauss = ValueType(0); } } @@ -1585,7 +1585,7 @@ class CurvatureStencil: public BaseStencil, Grid { Real alpha, normGrad; return this->meanCurvature(alpha, normGrad) ? - ValueType(alpha*mInvDx2/(2*math::Pow2(normGrad))) : 0; + ValueType(alpha*mInvDx2/(2*math::Pow2(normGrad))) : ValueType(0); } /// Return the mean Gaussian multiplied by the norm of the @@ -1597,7 +1597,7 @@ class CurvatureStencil: public BaseStencil, Grid { Real alpha, normGrad; return this->gaussianCurvature(alpha, normGrad) ? - ValueType(2*alpha*mInv2Dx*mInvDx2/math::Pow3(normGrad)) : 0; + ValueType(2*alpha*mInv2Dx*mInvDx2/math::Pow3(normGrad)) : ValueType(0); } /// @brief Return both the mean and the Gaussian curvature at the @@ -1627,7 +1627,7 @@ class CurvatureStencil: public BaseStencil, Grid Real alphaM, alphaG, normGrad; if (this->curvatures(alphaM, alphaG, normGrad)) { const Real mean = alphaM*mInv2Dx/math::Pow3(normGrad); - const Real tmp = std::sqrt(mean*mean - alphaG*mInvDx2/math::Pow4(normGrad)); + const Real tmp = math::Sqrt(mean*mean - alphaG*mInvDx2/math::Pow4(normGrad)); pair.first = ValueType(mean - tmp); pair.second = ValueType(mean + tmp); } @@ -1768,7 +1768,7 @@ class DenseStencil: public BaseStencil, GridT, IsSaf public: typedef GridT GridType; typedef typename GridT::TreeType TreeType; - typedef typename GridType::ValueType ValueType; + typedef typename GridType::ComputeType ValueType; DenseStencil(const GridType& grid, int halfWidth) : BaseType(grid, /*size=*/math::Pow3(2 * halfWidth + 1)) diff --git a/openvdb/openvdb/openvdb.h b/openvdb/openvdb/openvdb.h index 1e47cae1a9..ee6d885091 100644 --- a/openvdb/openvdb/openvdb.h +++ b/openvdb/openvdb/openvdb.h @@ -53,6 +53,7 @@ namespace io { class DelayedLoadMetadata; } using BoolTree = tree::Tree4::Type; using DoubleTree = tree::Tree4::Type; using FloatTree = tree::Tree4::Type; +using HalfTree = tree::Tree4::Type; using Int32Tree = tree::Tree4::Type; using Int64Tree = tree::Tree4::Type; using MaskTree = tree::Tree4::Type; @@ -73,6 +74,7 @@ using VectorTree = Vec3fTree; using BoolGrid = Grid; using DoubleGrid = Grid; using FloatGrid = Grid; +using HalfGrid = Grid; using Int32Grid = Grid; using Int64Grid = Grid; using MaskGrid = Grid; @@ -88,7 +90,7 @@ using VectorGrid = Vec3fGrid; /// @name Lists of native Grid Types /// @{ /// The floating point Grid types which OpenVDB will register by default. -using RealGridTypes = TypeList; +using RealGridTypes = TypeList; /// The integer Grid types which OpenVDB will register by default. using IntegerGridTypes = TypeList; /// The scalar Grid types which OpenVDB will register by default. This is a @@ -204,6 +206,7 @@ using MetaTypes = TypeList< BoolMetadata, DoubleMetadata, FloatMetadata, + HalfMetadata, Int32Metadata, Int64Metadata, StringMetadata, diff --git a/openvdb/openvdb/tools/FastSweeping.h b/openvdb/openvdb/tools/FastSweeping.h index b7d652a217..22646aa196 100644 --- a/openvdb/openvdb/tools/FastSweeping.h +++ b/openvdb/openvdb/tools/FastSweeping.h @@ -460,18 +460,20 @@ maskSdf(const GridT &sdfGrid, template class FastSweeping { - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "FastSweeping requires SdfGridT to have floating-point values"); // Defined types related to the signed distance (or fog) grid using SdfValueT = typename SdfGridT::ValueType; + using SdfComputeT = typename SdfGridT::ComputeType; using SdfTreeT = typename SdfGridT::TreeType; using SdfAccT = tree::ValueAccessor;//don't register accessors using SdfConstAccT = typename tree::ValueAccessor;//don't register accessors // define types related to the extension field - using ExtGridT = typename SdfGridT::template ValueConverter::Type; - using ExtTreeT = typename ExtGridT::TreeType; - using ExtAccT = tree::ValueAccessor; + using ExtGridT = typename SdfGridT::template ValueConverter::Type; + using ExtTreeT = typename ExtGridT::TreeType; + using ExtComputeT = typename ExtGridT::ComputeType; + using ExtAccT = tree::ValueAccessor; // define types related to the tree that masks out the active voxels to be solved for using SweepMaskTreeT = typename SdfTreeT::template ValueConverter::Type; @@ -1073,7 +1075,7 @@ struct FastSweeping::DilateKernel } else { switch (mode) { case FastSweepingDomain::SWEEP_ALL : - voxelIter.setValue(value > 0 ? Unknown : -Unknown); + voxelIter.setValue(math::isNegative(value) ? -Unknown : Unknown); break; case FastSweepingDomain::SWEEP_GREATER_THAN_ISOVALUE : if (value > 0) voxelIter.setValue(Unknown); @@ -1085,7 +1087,7 @@ struct FastSweeping::DilateKernel } break; case FastSweepingDomain::SWEEP_LESS_THAN_ISOVALUE : - if (value < 0) voxelIter.setValue(-Unknown); + if (math::isNegative(value)) voxelIter.setValue(-Unknown); else { maskLeaf->setValueOff(voxelIter.pos()); bool isInputOn = sdfInputAcc.probeValue(ijk, inputValue); @@ -1127,8 +1129,8 @@ struct FastSweeping::InitSdf void run(SdfValueT isoValue) { - mIsoValue = isoValue; - mAboveSign = mParent->mIsInputSdf ? SdfValueT(1) : SdfValueT(-1); + mIsoValue = SdfComputeT(isoValue); + mAboveSign = mParent->mIsInputSdf ? SdfComputeT(1) : SdfComputeT(-1); SdfTreeT &tree = mSdfGrid->tree();//sdf const bool hasActiveTiles = tree.hasActiveTiles(); @@ -1166,12 +1168,13 @@ struct FastSweeping::InitSdf { SweepMaskAccT sweepMaskAcc(mParent->mSweepMask); math::GradStencil stencil(*mSdfGrid); - const SdfValueT isoValue = mIsoValue, above = mAboveSign*std::numeric_limits::max();//local copy - const SdfValueT h = mAboveSign*static_cast(mSdfGrid->voxelSize()[0]);//Voxel size + const SdfComputeT isoValue = mIsoValue; + const SdfValueT above = mAboveSign*std::numeric_limits::max();//local copy + const SdfComputeT h = mAboveSign*static_cast(mSdfGrid->voxelSize()[0]);//Voxel size for (auto leafIter = r.begin(); leafIter; ++leafIter) { SdfValueT* sdf = leafIter.buffer(1).data(); for (auto voxelIter = leafIter->beginValueAll(); voxelIter; ++voxelIter) { - const SdfValueT value = *voxelIter; + const SdfComputeT value = SdfComputeT(*voxelIter); const bool isAbove = value > isoValue; if (!voxelIter.isValueOn()) {// inactive voxels sdf[voxelIter.pos()] = isAbove ? above : -above; @@ -1184,21 +1187,21 @@ struct FastSweeping::InitSdf } else {// compute distance to iso-surface // disable boundary voxels from the mask tree sweepMaskAcc.setValueOff(ijk); - const SdfValueT delta = value - isoValue;//offset relative to iso-value + const SdfComputeT delta = value - isoValue;//offset relative to iso-value if (math::isApproxZero(delta)) {//voxel is on the iso-surface sdf[voxelIter.pos()] = 0; } else {//voxel is neighboring the iso-surface - SdfValueT sum = 0; + SdfComputeT sum = 0; for (int i=0; i<6;) { - SdfValueT d = std::numeric_limits::max(), d2; + SdfComputeT d = std::numeric_limits::max(), d2; if (mask.test(i++)) d = math::Abs(delta/(value-stencil.getValue(i))); if (mask.test(i++)) { d2 = math::Abs(delta/(value-stencil.getValue(i))); if (d2 < d) d = d2; } - if (d < std::numeric_limits::max()) sum += 1/(d*d); + if (d < std::numeric_limits::max()) sum += 1/(d*d); } - sdf[voxelIter.pos()] = isAbove ? h / math::Sqrt(sum) : -h / math::Sqrt(sum); + sdf[voxelIter.pos()] = SdfValueT(isAbove ? h / math::Sqrt(sum) : -h / math::Sqrt(sum)); }// voxel is neighboring the iso-surface }// intersecting voxels }// active voxels @@ -1209,18 +1212,19 @@ struct FastSweeping::InitSdf template void operator()(const RootOrInternalNodeT& node) const { - const SdfValueT isoValue = mIsoValue, above = mAboveSign*std::numeric_limits::max(); + const SdfComputeT isoValue = mIsoValue; + const SdfValueT above = mAboveSign*std::numeric_limits::max(); for (auto it = node.cbeginValueAll(); it; ++it) { SdfValueT& v = const_cast(*it); - v = v > isoValue ? above : -above; + v = SdfComputeT(v) > isoValue ? above : -above; }//loop over all tiles }// FastSweeping::InitSdf::operator()(const RootOrInternalNodeT&) // Public member data FastSweeping *mParent; SdfGridT *mSdfGrid;//raw pointer, i.e. lock free - SdfValueT mIsoValue; - SdfValueT mAboveSign;//sign of distance values above the iso-value + SdfComputeT mIsoValue; + SdfComputeT mAboveSign;//sign of distance values above the iso-value };// FastSweeping::InitSdf @@ -1244,7 +1248,7 @@ struct FastSweeping::InitExt } mAboveSign = mParent->mIsInputSdf ? SdfValueT(1) : SdfValueT(-1); - mIsoValue = isoValue; + mIsoValue = SdfComputeT(isoValue); auto &tree1 = mSdfGrid->tree(); auto &tree2 = mExtGrid->tree(); const bool hasActiveTiles = tree1.hasActiveTiles();//very fast @@ -1296,17 +1300,17 @@ struct FastSweeping::InitExt }// FastSweeping::InitExt::run // int implements an update if minD needs to be updated - template::value, int>::type = 0> + template::value, int>::type = 0> void sumHelper(ExtT& sum2, ExtT ext, bool update, const SdfT& /* d2 */) const { if (update) sum2 = ext; }// int implementation // non-int implements a weighted sum - template::value, int>::type = 0> - void sumHelper(ExtT& sum2, ExtT ext, bool /* update */, const SdfT& d2) const { sum2 += static_cast(d2 * ext); }// non-int implementation + template::value, int>::type = 0> + void sumHelper(ExtT& sum2, ExtT ext, bool /* update */, const SdfT& d2) const { sum2 += static_cast(d2 * ext); }// non-int implementation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT extValHelper(ExtT extSum, const SdfT& /* sdfSum */) const { return extSum; }// int implementation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT extValHelper(ExtT extSum, const SdfT& sdfSum) const {return ExtT((SdfT(1) / sdfSum) * extSum); }// non-int implementation void operator()(const LeafRange& r) const @@ -1316,13 +1320,14 @@ struct FastSweeping::InitExt math::GradStencil stencil(*mSdfGrid); const math::Transform& xform = mExtGrid->transform(); typename OpPoolT::reference op = mOpPool->local(); - const SdfValueT isoValue = mIsoValue, above = mAboveSign*std::numeric_limits::max();//local copy - const SdfValueT h = mAboveSign*static_cast(mSdfGrid->voxelSize()[0]);//Voxel size + const SdfComputeT isoValue = mIsoValue; + const SdfValueT above = mAboveSign*std::numeric_limits::max();//local copy + const SdfComputeT h = mAboveSign*static_cast(mSdfGrid->voxelSize()[0]);//Voxel size for (auto leafIter = r.begin(); leafIter; ++leafIter) { SdfValueT *sdf = leafIter.buffer(1).data(); ExtValueT *ext = acc.probeLeaf(leafIter->origin())->buffer().data();//should be safe! for (auto voxelIter = leafIter->beginValueAll(); voxelIter; ++voxelIter) { - const SdfValueT value = *voxelIter; + const SdfComputeT value = SdfComputeT(*voxelIter); const bool isAbove = value > isoValue; if (!voxelIter.isValueOn()) {// inactive voxels sdf[voxelIter.pos()] = isAbove ? above : -above; @@ -1336,20 +1341,20 @@ struct FastSweeping::InitExt } else {// compute distance to iso-surface // disable boundary voxels from the mask tree sweepMaskAcc.setValueOff(ijk); - const SdfValueT delta = value - isoValue;//offset relative to iso-value + const SdfComputeT delta = value - isoValue;//offset relative to iso-value if (math::isApproxZero(delta)) {//voxel is on the iso-surface sdf[voxelIter.pos()] = 0; ext[voxelIter.pos()] = ExtValueT(op(xform.indexToWorld(ijk))); } else {//voxel is neighboring the iso-surface - SdfValueT sum1 = 0; - ExtValueT sum2 = zeroVal(); + SdfComputeT sum1 = 0; + ExtComputeT sum2 = zeroVal(); // minD is used to update sum2 in the integer case, // where we choose the value of the extension grid corresponding to // the smallest value of d in the 6 direction neighboring the current // voxel. - SdfValueT minD = std::numeric_limits::max(); + SdfComputeT minD = std::numeric_limits::max(); for (int n=0, i=0; i<6;) { - SdfValueT d = std::numeric_limits::max(), d2; + SdfComputeT d = std::numeric_limits::max(), d2; if (mask.test(i++)) { d = math::Abs(delta/(value-stencil.getValue(i))); n = i - 1; @@ -1361,19 +1366,19 @@ struct FastSweeping::InitExt n = i - 1; } } - if (d < std::numeric_limits::max()) { + if (d < std::numeric_limits::max()) { d2 = 1/(d*d); sum1 += d2; - const Vec3R xyz(static_cast(ijk[0])+d*static_cast(FastSweeping::mOffset[n][0]), - static_cast(ijk[1])+d*static_cast(FastSweeping::mOffset[n][1]), - static_cast(ijk[2])+d*static_cast(FastSweeping::mOffset[n][2])); + const Vec3R xyz(static_cast(ijk[0])+d*static_cast(FastSweeping::mOffset[n][0]), + static_cast(ijk[1])+d*static_cast(FastSweeping::mOffset[n][1]), + static_cast(ijk[2])+d*static_cast(FastSweeping::mOffset[n][2])); // If current d is less than minD, update minD - sumHelper(sum2, ExtValueT(op(xform.indexToWorld(xyz))), d < minD, d2); + sumHelper(sum2, ExtComputeT(op(xform.indexToWorld(xyz))), d < minD, d2); if (d < minD) minD = d; } }//look over six cases - ext[voxelIter.pos()] = extValHelper(sum2, sum1); - sdf[voxelIter.pos()] = isAbove ? h / math::Sqrt(sum1) : -h / math::Sqrt(sum1); + ext[voxelIter.pos()] = ExtValueT(extValHelper(sum2, sum1)); + sdf[voxelIter.pos()] = SdfValueT(isAbove ? h / math::Sqrt(sum1) : -h / math::Sqrt(sum1)); }// voxel is neighboring the iso-surface }// intersecting voxels }// active voxels @@ -1384,10 +1389,11 @@ struct FastSweeping::InitExt template void operator()(const RootOrInternalNodeT& node) const { - const SdfValueT isoValue = mIsoValue, above = mAboveSign*std::numeric_limits::max(); + const SdfComputeT isoValue = mIsoValue; + const SdfValueT above = mAboveSign*std::numeric_limits::max(); for (auto it = node.cbeginValueAll(); it; ++it) { SdfValueT& v = const_cast(*it); - v = v > isoValue ? above : -above; + v = SdfComputeT(v) > isoValue ? above : -above; }//loop over all tiles } // Public member data @@ -1395,8 +1401,8 @@ struct FastSweeping::InitExt OpPoolT *mOpPool; SdfGridT *mSdfGrid; ExtGridT *mExtGrid; - SdfValueT mIsoValue; - SdfValueT mAboveSign;//sign of distance values above the iso-value + SdfComputeT mIsoValue; + SdfValueT mAboveSign;//sign of distance values above the iso-value };// FastSweeping::InitExt /// Private class of FastSweeping to perform multi-threaded initialization @@ -1592,26 +1598,26 @@ struct FastSweeping::SweepingKernel // Private struct for nearest neighbor grid points (very memory light!) struct NN { - SdfValueT v; + SdfComputeT v; int n; inline static Coord ijk(const Coord &p, int i) { return p + FastSweeping::mOffset[i]; } NN() : v(), n() {} - NN(const SdfAccT &a, const Coord &p, int i) : v(math::Abs(a.getValue(ijk(p,i)))), n(i) {} + NN(const SdfAccT &a, const Coord &p, int i) : v(math::Abs(SdfComputeT(a.getValue(ijk(p,i))))), n(i) {} inline Coord operator()(const Coord &p) const { return ijk(p, n); } inline bool operator<(const NN &rhs) const { return v < rhs.v; } - inline operator bool() const { return v < SdfValueT(1000); } + inline operator bool() const { return v < SdfComputeT(1000); } };// NN /// @note Extending an integer field is based on the nearest-neighbor interpolation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT twoNghbr(const NN& d1, const NN& d2, const SdfT& /* w */, const ExtT& v1, const ExtT& v2) const { return d1.v < d2.v ? v1 : v2; }// int implementation /// @note Extending a non-integer field is based on a weighted interpolation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT twoNghbr(const NN& d1, const NN& d2, const SdfT& w, const ExtT& v1, const ExtT& v2) const { return ExtT(w*(d1.v*v1 + d2.v*v2)); }// non-int implementation /// @note Extending an integer field is based on the nearest-neighbor interpolation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT threeNghbr(const NN& d1, const NN& d2, const NN& d3, const SdfT& /* w */, const ExtT& v1, const ExtT& v2, const ExtT& v3) const { math::Vec3 d(d1.v, d2.v, d3.v); math::Vec3 v(v1, v2, v3); @@ -1619,7 +1625,7 @@ struct FastSweeping::SweepingKernel }// int implementation /// @note Extending a non-integer field is based on a weighted interpolation - template::value, int>::type = 0> + template::value, int>::type = 0> ExtT threeNghbr(const NN& d1, const NN& d2, const NN& d3, const SdfT& w, const ExtT& v1, const ExtT& v2, const ExtT& v3) const { return ExtT(w*(d1.v*v1 + d2.v*v2 + d3.v*v3)); }// non-int implementation @@ -1629,8 +1635,8 @@ struct FastSweeping::SweepingKernel typename ExtGridT::TreeType *tree2 = mParent->mExtGrid ? &mParent->mExtGrid->tree() : nullptr; typename ExtGridT::TreeType *tree3 = mParent->mExtGridInput ? &mParent->mExtGridInput->tree() : nullptr; - const SdfValueT h = static_cast(mParent->mSdfGrid->voxelSize()[0]); - const SdfValueT sqrt2h = math::Sqrt(SdfValueT(2))*h; + const SdfComputeT h = static_cast(mParent->mSdfGrid->voxelSize()[0]); + const SdfComputeT sqrt2h = math::Sqrt(SdfComputeT(2))*h; const FastSweepingDomain mode = mParent->mSweepDirection; const bool isInputSdf = mParent->mIsInputSdf; @@ -1649,7 +1655,7 @@ struct FastSweeping::SweepingKernel SdfAccT acc1(mParent->mSdfGrid->tree()); auto acc2 = std::unique_ptr(tree2 ? new ExtAccT(*tree2) : nullptr); auto acc3 = std::unique_ptr(tree3 ? new ExtAccT(*tree3) : nullptr); - SdfValueT absV, sign, update, D; + SdfComputeT absV, sign, update, D; NN d1, d2, d3;//distance values and coordinates of closest neighbor points const LeafSliceArray& leafSliceArray = mVoxelSliceMap[voxelSliceIndex]; @@ -1686,10 +1692,10 @@ struct FastSweeping::SweepingKernel SdfValueT &value = const_cast(acc1.getValue(ijk)); // Extract the sign - sign = value >= SdfValueT(0) ? SdfValueT(1) : SdfValueT(-1); + sign = math::isNegative(value) ? SdfComputeT(-1) : SdfComputeT(1); // Absolute value - absV = math::Abs(value); + absV = SdfComputeT(math::Abs(value)); // sort values so d1 <= d2 <= d3 if (d2 < d1) std::swap(d1, d2); @@ -1707,12 +1713,12 @@ struct FastSweeping::SweepingKernel // There is an assert upstream to check if mExtGridInput exists if mode != SWEEP_ALL ExtValueT updateExt = acc2->getValue(d1(ijk)); if (mode == FastSweepingDomain::SWEEP_GREATER_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value >= SdfValueT(0)) ? acc2->getValue(d1(ijk)) : acc3->getValue(ijk); - else updateExt = (value <= SdfValueT(0)) ? acc2->getValue(d1(ijk)) : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(value) ? acc3->getValue(ijk) : acc2->getValue(d1(ijk)); + else updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : acc2->getValue(d1(ijk)); } // SWEEP_GREATER_THAN_ISOVALUE else if (mode == FastSweepingDomain::SWEEP_LESS_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value <= SdfValueT(0)) ? acc2->getValue(d1(ijk)) : acc3->getValue(ijk); - else updateExt = (value >= SdfValueT(0)) ? acc2->getValue(d1(ijk)) : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : acc2->getValue(d1(ijk)); + else updateExt = math::isNegative(value) ? acc3->getValue(ijk) : acc2->getValue(d1(ijk)); } // SWEEP_LESS_THAN_ISOVALUE acc2->setValue(ijk, updateExt); }//update ext? @@ -1725,8 +1731,8 @@ struct FastSweeping::SweepingKernel //D = SdfValueT(2) * h * h - math::Pow2(d1.v - d2.v);// = 2h^2-(d1-d2)^2 //if (D >= SdfValueT(0)) {// non-negative discriminant if (d2.v <= sqrt2h + d1.v) { - D = SdfValueT(2) * h * h - math::Pow2(d1.v - d2.v);// = 2h^2-(d1-d2)^2 - update = SdfValueT(0.5) * (d1.v + d2.v + std::sqrt(D)); + D = SdfComputeT(2) * h * h - math::Pow2(d1.v - d2.v);// = 2h^2-(d1-d2)^2 + update = SdfComputeT(0.5) * (d1.v + d2.v + math::Sqrt(D)); if (update > d2.v && update <= d3.v) { if (update < absV) { value = sign * update; @@ -1734,19 +1740,19 @@ struct FastSweeping::SweepingKernel d1.v -= update; d2.v -= update; // affine combination of two neighboring extension values - const SdfValueT w = SdfValueT(1)/(d1.v+d2.v); - const ExtValueT v1 = acc2->getValue(d1(ijk)); - const ExtValueT v2 = acc2->getValue(d2(ijk)); - const ExtValueT extVal = twoNghbr(d1, d2, w, v1, v2); + const SdfComputeT w = SdfComputeT(1)/(d1.v+d2.v); + const ExtComputeT v1 = ExtComputeT(acc2->getValue(d1(ijk))); + const ExtComputeT v2 = ExtComputeT(acc2->getValue(d2(ijk))); + const ExtValueT extVal = ExtValueT(twoNghbr(d1, d2, w, v1, v2)); ExtValueT updateExt = extVal; if (mode == FastSweepingDomain::SWEEP_GREATER_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value >= SdfValueT(0)) ? extVal : acc3->getValue(ijk); - else updateExt = (value <= SdfValueT(0)) ? extVal : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(value) ? acc3->getValue(ijk) : extVal; + else updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : extVal; } // SWEEP_GREATER_THAN_ISOVALUE else if (mode == FastSweepingDomain::SWEEP_LESS_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value <= SdfValueT(0)) ? extVal : acc3->getValue(ijk); - else updateExt = (value >= SdfValueT(0)) ? extVal : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : extVal; + else updateExt = math::isNegative(value) ? acc3->getValue(ijk) : extVal; } // SWEEP_LESS_THAN_ISOVALUE acc2->setValue(ijk, updateExt); }//update ext? @@ -1759,10 +1765,10 @@ struct FastSweeping::SweepingKernel // (x-d1)^2 + (x-d2)^2 + (x-d3)^2 = h^2 // 3x^2 - 2(d1 + d2 + d3)x + d1^2 + d2^2 + d3^2 = h^2 // ax^2 + bx + c=0, a=3, b=-2(d1+d2+d3), c=d1^2 + d2^2 + d3^2 - h^2 - const SdfValueT d123 = d1.v + d2.v + d3.v; - D = d123*d123 - SdfValueT(3)*(d1.v*d1.v + d2.v*d2.v + d3.v*d3.v - h * h); - if (D >= SdfValueT(0)) {// non-negative discriminant - update = SdfValueT(1.0/3.0) * (d123 + std::sqrt(D));//always passes test + const SdfComputeT d123 = d1.v + d2.v + d3.v; + D = d123*d123 - SdfComputeT(3)*(d1.v*d1.v + d2.v*d2.v + d3.v*d3.v - h * h); + if (D >= SdfComputeT(0)) {// non-negative discriminant + update = SdfComputeT(1.0/3.0) * (d123 + std::sqrt(D));//always passes test //if (update > d3.v) {//disabled due to round-off errors if (update < absV) { value = sign * update; @@ -1771,20 +1777,20 @@ struct FastSweeping::SweepingKernel d2.v -= update; d3.v -= update; // affine combination of three neighboring extension values - const SdfValueT w = SdfValueT(1)/(d1.v+d2.v+d3.v); - const ExtValueT v1 = acc2->getValue(d1(ijk)); - const ExtValueT v2 = acc2->getValue(d2(ijk)); - const ExtValueT v3 = acc2->getValue(d3(ijk)); - const ExtValueT extVal = threeNghbr(d1, d2, d3, w, v1, v2, v3); + const SdfComputeT w = SdfComputeT(1)/(d1.v+d2.v+d3.v); + const ExtComputeT v1 = ExtComputeT(acc2->getValue(d1(ijk))); + const ExtComputeT v2 = ExtComputeT(acc2->getValue(d2(ijk))); + const ExtComputeT v3 = ExtComputeT(acc2->getValue(d3(ijk))); + const ExtValueT extVal = ExtValueT(threeNghbr(d1, d2, d3, w, v1, v2, v3)); ExtValueT updateExt = extVal; if (mode == FastSweepingDomain::SWEEP_GREATER_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value >= SdfValueT(0)) ? extVal : acc3->getValue(ijk); - else updateExt = (value <= SdfValueT(0)) ? extVal : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(value) ? acc3->getValue(ijk) : extVal; + else updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : extVal; } // SWEEP_GREATER_THAN_ISOVALUE else if (mode == FastSweepingDomain::SWEEP_LESS_THAN_ISOVALUE) { - if (isInputSdf) updateExt = (value <= SdfValueT(0)) ? extVal : acc3->getValue(ijk); - else updateExt = (value >= SdfValueT(0)) ? extVal : acc3->getValue(ijk); + if (isInputSdf) updateExt = math::isNegative(-value) ? acc3->getValue(ijk) : extVal; + else updateExt = math::isNegative(value) ? acc3->getValue(ijk) : extVal; } // SWEEP_LESS_THAN_ISOVALUE acc2->setValue(ijk, updateExt); }//update ext? diff --git a/openvdb/openvdb/tools/Interpolation.h b/openvdb/openvdb/tools/Interpolation.h index b3870c0838..e84dc3a80c 100644 --- a/openvdb/openvdb/tools/Interpolation.h +++ b/openvdb/openvdb/tools/Interpolation.h @@ -41,6 +41,7 @@ #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED #include // for OPENVDB_VERSION_NAME +#include // for ValueToComputeMap #include // for round() #include // for SmoothUnitStep #include // for Transform @@ -314,7 +315,7 @@ class GridSampler /// @brief Sample value in integer index space /// @param i Integer x-coordinate in index space /// @param j Integer y-coordinate in index space - /// @param k Integer x-coordinate in index space + /// @param k Integer z-coordinate in index space ValueType sampleVoxel(typename Coord::ValueType i, typename Coord::ValueType j, typename Coord::ValueType k) const @@ -393,7 +394,7 @@ class GridSampler, SamplerType> /// @brief Sample value in integer index space /// @param i Integer x-coordinate in index space /// @param j Integer y-coordinate in index space - /// @param k Integer x-coordinate in index space + /// @param k Integer z-coordinate in index space ValueType sampleVoxel(typename Coord::ValueType i, typename Coord::ValueType j, typename Coord::ValueType k) const @@ -745,17 +746,31 @@ BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord, typename TreeT::ValueType& result) { using ValueT = typename TreeT::ValueType; + using ComputeT = typename TreeT::ComputeType; const Vec3i inIdx = local_util::floorVec3(inCoord); const Vec3R uvw = inCoord - inIdx; // Retrieve the values of the eight voxels surrounding the // fractional source coordinates. - ValueT data[2][2][2]; - - const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx)); + ValueT probeData[2][2][2]; + ComputeT computeData[2][2][2]; + bool hasActiveValues; + + if constexpr(std::is_same_v) { + hasActiveValues = BoxSampler::probeValues(computeData, inTree, Coord(inIdx)); + } else { + hasActiveValues = BoxSampler::probeValues(probeData, inTree, Coord(inIdx)); + for (int dx = 0; dx < 2; ++dx) { + for (int dy = 0; dy < 2; ++dy) { + for (int dz = 0; dz < 2; ++dz) { + computeData[dx][dy][dz] = probeData[dx][dy][dz]; + } + } + } + } - result = BoxSampler::trilinearInterpolation(data, uvw); + result = BoxSampler::trilinearInterpolation(computeData, uvw); return hasActiveValues; } @@ -766,17 +781,18 @@ inline typename TreeT::ValueType BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord) { using ValueT = typename TreeT::ValueType; + using ComputeT = typename TreeT::ComputeType; const Vec3i inIdx = local_util::floorVec3(inCoord); const Vec3R uvw = inCoord - inIdx; // Retrieve the values of the eight voxels surrounding the // fractional source coordinates. - ValueT data[2][2][2]; + ComputeT data[2][2][2]; BoxSampler::getValues(data, inTree, Coord(inIdx)); - return BoxSampler::trilinearInterpolation(data, uvw); + return ValueT(BoxSampler::trilinearInterpolation(data, uvw)); } @@ -832,6 +848,7 @@ QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord, typename TreeT::ValueType& result) { using ValueT = typename TreeT::ValueType; + using ComputeT = typename TreeT::ComputeType; const Vec3i inIdx = local_util::floorVec3(inCoord), inLoIdx = inIdx - Vec3i(1, 1, 1); const Vec3R uvw = inCoord - inIdx; @@ -840,15 +857,17 @@ QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord, // fractional source coordinates. bool active = false; ValueT data[3][3][3]; + ComputeT computeData[3][3][3]; for (int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) { for (int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) { for (int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) { if (inTree.probeValue(Coord(ix, iy, iz), data[dx][dy][dz])) active = true; + computeData[dx][dy][dz] = data[dx][dy][dz]; } } } - result = QuadraticSampler::triquadraticInterpolation(data, uvw); + result = QuadraticSampler::triquadraticInterpolation(computeData, uvw); return active; } @@ -858,13 +877,14 @@ inline typename TreeT::ValueType QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord) { using ValueT = typename TreeT::ValueType; + using ComputeT = typename TreeT::ComputeType; const Vec3i inIdx = local_util::floorVec3(inCoord), inLoIdx = inIdx - Vec3i(1, 1, 1); const Vec3R uvw = inCoord - inIdx; // Retrieve the values of the 27 voxels surrounding the // fractional source coordinates. - ValueT data[3][3][3]; + ComputeT data[3][3][3]; for (int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) { for (int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) { for (int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) { @@ -873,7 +893,7 @@ QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord) } } - return QuadraticSampler::triquadraticInterpolation(data, uvw); + return ValueT(QuadraticSampler::triquadraticInterpolation(data, uvw)); } diff --git a/openvdb/openvdb/tools/LevelSetAdvect.h b/openvdb/openvdb/tools/LevelSetAdvect.h index 7d4787d09c..fe9105ae12 100644 --- a/openvdb/openvdb/tools/LevelSetAdvect.h +++ b/openvdb/openvdb/tools/LevelSetAdvect.h @@ -80,6 +80,7 @@ class LevelSetAdvection using LeafType = typename TrackerT::LeafType; using BufferType = typename TrackerT::BufferType; using ValueType = typename TrackerT::ValueType; + using ComputeType = typename TrackerT::ComputeType; using VectorType = typename FieldT::VectorType; /// Main constructor @@ -134,7 +135,7 @@ class LevelSetAdvection /// final time, time1. If time0>time1 backward advection is performed. /// /// @return number of CFL iterations used to advect from time0 to time1 - size_t advect(ValueType time0, ValueType time1); + size_t advect(ComputeType time0, ComputeType time1); private: // disallow copy construction and copy by assignment! @@ -154,7 +155,7 @@ class LevelSetAdvection virtual ~Advect() { if (mIsMaster) this->clearField(); } /// Advect the level set from its current time, time0, to its final time, time1. /// @return number of CFL iterations - size_t advect(ValueType time0, ValueType time1); + size_t advect(ComputeType time0, ComputeType time1); /// Used internally by tbb::parallel_for() void operator()(const LeafRange& r) const { @@ -164,13 +165,13 @@ class LevelSetAdvection /// method calling tbb void cook(const char* msg, size_t swapBuffer = 0); /// Sample field and return the CFL time step - typename GridT::ValueType sampleField(ValueType time0, ValueType time1); - template void sample(const LeafRange& r, ValueType t0, ValueType t1); - inline void sampleXformed(const LeafRange& r, ValueType t0, ValueType t1) + typename GridT::ComputeType sampleField(ComputeType time0, ComputeType time1); + template void sample(const LeafRange& r, ComputeType t0, ComputeType t1); + inline void sampleXformed(const LeafRange& r, ComputeType t0, ComputeType t1) { this->sample(r, t0, t1); } - inline void sampleAligned(const LeafRange& r, ValueType t0, ValueType t1) + inline void sampleAligned(const LeafRange& r, ComputeType t0, ComputeType t1) { this->sample(r, t0, t1); } @@ -178,11 +179,11 @@ class LevelSetAdvection // Convex combination of Phi and a forward Euler advection steps: // Phi(result) = alpha * Phi(phi) + (1-alpha) * (Phi(0) - dt * Speed(speed)*|Grad[Phi(0)]|); template - void euler(const LeafRange&, ValueType, Index, Index); - inline void euler01(const LeafRange& r, ValueType t) {this->euler<0,1>(r, t, 0, 1);} - inline void euler12(const LeafRange& r, ValueType t) {this->euler<1,2>(r, t, 1, 1);} - inline void euler34(const LeafRange& r, ValueType t) {this->euler<3,4>(r, t, 1, 2);} - inline void euler13(const LeafRange& r, ValueType t) {this->euler<1,3>(r, t, 1, 2);} + void euler(const LeafRange&, ComputeType, Index, Index); + inline void euler01(const LeafRange& r, ComputeType t) {this->euler<0,1>(r, t, 0, 1);} + inline void euler12(const LeafRange& r, ComputeType t) {this->euler<1,2>(r, t, 1, 1);} + inline void euler34(const LeafRange& r, ComputeType t) {this->euler<3,4>(r, t, 1, 2);} + inline void euler13(const LeafRange& r, ComputeType t) {this->euler<1,3>(r, t, 1, 2);} LevelSetAdvection& mParent; VectorType* mVelocity; @@ -193,16 +194,16 @@ class LevelSetAdvection }; // end of private Advect struct template - size_t advect1(ValueType time0, ValueType time1); + size_t advect1(ComputeType time0, ComputeType time1); template - size_t advect2(ValueType time0, ValueType time1); + size_t advect2(ComputeType time0, ComputeType time1); template - size_t advect3(ValueType time0, ValueType time1); + size_t advect3(ComputeType time0, ComputeType time1); TrackerT mTracker; //each thread needs a deep copy of the field since it might contain a ValueAccessor @@ -215,7 +216,7 @@ class LevelSetAdvection template size_t -LevelSetAdvection::advect(ValueType time0, ValueType time1) +LevelSetAdvection::advect(ComputeType time0, ComputeType time1) { switch (mSpatialScheme) { case math::FIRST_BIAS: @@ -238,7 +239,7 @@ LevelSetAdvection::advect(ValueType time0, ValueType template template size_t -LevelSetAdvection::advect1(ValueType time0, ValueType time1) +LevelSetAdvection::advect1(ComputeType time0, ComputeType time1) { switch (mTemporalScheme) { case math::TVD_RK1: @@ -257,7 +258,7 @@ LevelSetAdvection::advect1(ValueType time0, ValueType template template size_t -LevelSetAdvection::advect2(ValueType time0, ValueType time1) +LevelSetAdvection::advect2(ComputeType time0, ComputeType time1) { const math::Transform& trans = mTracker.grid().transform(); if (trans.mapType() == math::UniformScaleMap::mapType()) { @@ -282,7 +283,7 @@ template< math::TemporalIntegrationScheme TemporalScheme, typename MapT> size_t -LevelSetAdvection::advect3(ValueType time0, ValueType time1) +LevelSetAdvection::advect3(ComputeType time0, ComputeType time1) { Advect tmp(*this); return tmp.advect(time0, time1); @@ -338,7 +339,7 @@ template< inline size_t LevelSetAdvection:: Advect:: -advect(ValueType time0, ValueType time1) +advect(ComputeType time0, ComputeType time1) { namespace ph = std::placeholders; @@ -352,7 +353,7 @@ advect(ValueType time0, ValueType time1) mParent.mTracker.leafs().rebuildAuxBuffers(TemporalScheme == math::TVD_RK3 ? 2 : 1); //timer.stop(); - const ValueType dt = this->sampleField(time0, time1); + const ComputeType dt = this->sampleField(time0, time1); if ( math::isZero(dt) ) break;//V is essentially zero so terminate OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN //switch is resolved at compile-time @@ -423,10 +424,10 @@ template< typename MapT, math::BiasedGradientScheme SpatialScheme, math::TemporalIntegrationScheme TemporalScheme> -inline typename GridT::ValueType +inline typename GridT::ComputeType LevelSetAdvection:: Advect:: -sampleField(ValueType time0, ValueType time1) +sampleField(ComputeType time0, ComputeType time1) { namespace ph = std::placeholders; @@ -448,19 +449,19 @@ sampleField(ValueType time0, ValueType time1) this->cook("Sampling advection field"); // Find the extrema of the magnitude of the velocities - ValueType maxAbsV = 0; + ComputeType maxAbsV = 0; VectorType* v = mVelocity; for (size_t i = 0; i < voxelCount; ++i, ++v) { - maxAbsV = math::Max(maxAbsV, ValueType(v->lengthSqr())); + maxAbsV = math::Max(maxAbsV, ComputeType(v->lengthSqr())); } // Compute the CFL number - if (math::isApproxZero(maxAbsV, math::Delta::value())) return ValueType(0); - static const ValueType CFL = (TemporalScheme == math::TVD_RK1 ? ValueType(0.3) : - TemporalScheme == math::TVD_RK2 ? ValueType(0.9) : - ValueType(1.0))/math::Sqrt(ValueType(3.0)); - const ValueType dt = math::Abs(time1 - time0), dx = mParent.mTracker.voxelSize(); - return math::Min(dt, ValueType(CFL*dx/math::Sqrt(maxAbsV))); + if (math::isApproxZero(maxAbsV, math::Delta::value())) return ComputeType(0); + static const ValueType CFL = (TemporalScheme == math::TVD_RK1 ? ComputeType(0.3) : + TemporalScheme == math::TVD_RK2 ? ComputeType(0.9) : + ComputeType(1.0))/math::Sqrt(ComputeType(3.0)); + const ComputeType dt = math::Abs(time1 - time0), dx = mParent.mTracker.voxelSize(); + return math::Min(dt, ComputeType(CFL*dx/math::Sqrt(maxAbsV))); } @@ -473,7 +474,7 @@ template inline void LevelSetAdvection:: Advect:: -sample(const LeafRange& range, ValueType time0, ValueType time1) +sample(const LeafRange& range, ComputeType time0, ComputeType time1) { const bool isForward = time0 < time1; using VoxelIterT = typename LeafType::ValueOnCIter; @@ -544,15 +545,15 @@ template inline void LevelSetAdvection:: Advect:: -euler(const LeafRange& range, ValueType dt, Index phiBuffer, Index resultBuffer) +euler(const LeafRange& range, ComputeType dt, Index phiBuffer, Index resultBuffer) { using SchemeT = math::BIAS_SCHEME; using StencilT = typename SchemeT::template ISStencil::StencilType; using VoxelIterT = typename LeafType::ValueOnCIter; using GradT = math::GradientBiased; - static const ValueType Alpha = ValueType(Nominator)/ValueType(Denominator); - static const ValueType Beta = ValueType(1) - Alpha; + static const ComputeType Alpha = ComputeType(Nominator)/ComputeType(Denominator); + static const ComputeType Beta = ComputeType(1) - Alpha; mParent.mTracker.checkInterrupter(); const MapT& map = *mMap; @@ -564,9 +565,9 @@ euler(const LeafRange& range, ValueType dt, Index phiBuffer, Index resultBuffer) for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter, ++vel) { const Index i = voxelIter.pos(); stencil.moveTo(voxelIter); - const ValueType a = - stencil.getValue() - dt * vel->dot(GradT::result(map, stencil, *vel)); - result[i] = Nominator ? Alpha * phi[i] + Beta * a : a; + const ComputeType a = + stencil.getValue() - dt * ComputeType(vel->dot(GradT::result(map, stencil, *vel))); + result[i] = Nominator ? ValueType(Alpha * phi[i] + Beta * a) : ValueType(a); }//loop over active voxels in the leaf of the mask }//loop over leafs of the level set } @@ -583,6 +584,7 @@ euler(const LeafRange& range, ValueType dt, Index phiBuffer, Index resultBuffer) #include #endif +OPENVDB_INSTANTIATE_CLASS LevelSetAdvection, util::NullInterrupter>; OPENVDB_INSTANTIATE_CLASS LevelSetAdvection, util::NullInterrupter>; OPENVDB_INSTANTIATE_CLASS LevelSetAdvection, util::NullInterrupter>; diff --git a/openvdb/openvdb/tools/LevelSetFilter.h b/openvdb/openvdb/tools/LevelSetFilter.h index bc1a425815..c197c0c590 100644 --- a/openvdb/openvdb/tools/LevelSetFilter.h +++ b/openvdb/openvdb/tools/LevelSetFilter.h @@ -44,7 +44,8 @@ class LevelSetFilter : public LevelSetTracker using MaskType = MaskT; using TreeType = typename GridType::TreeType; using ValueType = typename TreeType::ValueType; - using AlphaType = typename MaskType::ValueType; + using ComputeType = typename TreeType::ComputeType; + using AlphaType = typename MaskType::ComputeType; static_assert(std::is_floating_point::value, "LevelSetFilter requires a mask grid with floating-point values"); @@ -133,7 +134,7 @@ class LevelSetFilter : public LevelSetTracker /// @brief Offset the level set by the specified (world) distance. /// @param offset Value of the offset. /// @param mask Optional alpha mask. - void offset(ValueType offset, const MaskType* mask = nullptr) + void offset(ComputeType offset, const MaskType* mask = nullptr) { Filter f(this, mask); f.offset(offset); } @@ -206,17 +207,17 @@ class LevelSetFilter : public LevelSetTracker template struct Avg { Avg(const GridT& grid, Int32 w) : - acc(grid.tree()), width(w), frac(1/ValueType(2*w+1)) {} - inline ValueType operator()(Coord xyz) + acc(grid.tree()), width(w), frac(1/ComputeType(2*w+1)) {} + inline ComputeType operator()(Coord xyz) { - ValueType sum = zeroVal(); + ComputeType sum = zeroVal(); Int32& i = xyz[Axis], j = i + width; - for (i -= width; i <= j; ++i) sum += acc.getValue(xyz); + for (i -= width; i <= j; ++i) sum += ComputeType(acc.getValue(xyz)); return sum*frac; } typename GridT::ConstAccessor acc; const Int32 width; - const ValueType frac; + const ComputeType frac; }; template @@ -230,7 +231,7 @@ class LevelSetFilter : public LevelSetTracker void meanCurvatureImpl(const LeafRange&); void filletImpl(const LeafRange&); void laplacianImpl(const LeafRange&); - void offsetImpl(const LeafRange&, ValueType); + void offsetImpl(const LeafRange&, ComputeType); LevelSetFilter* mParent; const MaskType* mMask; @@ -354,16 +355,17 @@ LevelSetFilter::Filter::laplacian() template inline void -LevelSetFilter::Filter::offset(ValueType value) +LevelSetFilter::Filter::offset(ComputeType value) { mParent->startInterrupter("Offsetting level set"); mParent->leafs().removeAuxBuffers();// no auxiliary buffers required - const ValueType CFL = ValueType(0.5) * mParent->voxelSize(), offset = openvdb::math::Abs(value); - ValueType dist = 0.0; - while (offset-dist > ValueType(0.001)*CFL && mParent->checkInterrupter()) { - const ValueType delta = openvdb::math::Min(offset-dist, CFL); + const ComputeType CFL = ComputeType(0.5) * mParent->voxelSize(), + offset = openvdb::math::Abs(value); + ComputeType dist = 0.0; + while (offset-dist > ComputeType(0.001)*CFL && mParent->checkInterrupter()) { + const ComputeType delta = openvdb::math::Min(offset-dist, CFL); dist += delta; mTask = std::bind(&Filter::offsetImpl, @@ -386,7 +388,7 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa { mParent->checkInterrupter(); //const float CFL = 0.9f, dt = CFL * mDx * mDx / 6.0f; - const ValueType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ValueType(3.0); + const ComputeType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ComputeType(3.0); math::CurvatureStencil stencil(mParent->grid(), dx); if (mMask) { typename AlphaMaskT::FloatType a, b; @@ -397,7 +399,8 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.meanCurvatureNormGrad(); + const ComputeType phi0 = ComputeType(*iter), + phi1 = phi0 + dt*stencil.meanCurvatureNormGrad(); buffer[iter.pos()] = b * phi0 + a * phi1; } } @@ -407,7 +410,7 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { stencil.moveTo(iter); - buffer[iter.pos()] = *iter + dt*stencil.meanCurvatureNormGrad(); + buffer[iter.pos()] = ComputeType(*iter) + dt*stencil.meanCurvatureNormGrad(); } } } @@ -472,7 +475,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& { mParent->checkInterrupter(); //const float CFL = 0.9f, half_dt = CFL * mDx * mDx / 12.0f; - const ValueType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ValueType(6.0); + const ComputeType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ComputeType(6.0); math::GradStencil stencil(mParent->grid(), dx); if (mMask) { typename AlphaMaskT::FloatType a, b; @@ -483,7 +486,8 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.laplacian(); + const ComputeType phi0 = ComputeType(*iter), + phi1 = phi0 + dt*stencil.laplacian(); buffer[iter.pos()] = b * phi0 + a * phi1; } } @@ -493,7 +497,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { stencil.moveTo(iter); - buffer[iter.pos()] = *iter + dt*stencil.laplacian(); + buffer[iter.pos()] = ComputeType(*iter) + dt*stencil.laplacian(); } } } @@ -503,7 +507,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& template inline void LevelSetFilter::Filter::offsetImpl( - const LeafRange& range, ValueType offset) + const LeafRange& range, ComputeType offset) { mParent->checkInterrupter(); if (mMask) { @@ -512,13 +516,14 @@ LevelSetFilter::Filter::offsetImpl( mParent->maxMask(), mParent->isMaskInverted()); for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) { - if (alpha(iter.getCoord(), a, b)) iter.setValue(*iter + a*offset); + if (alpha(iter.getCoord(), a, b)) + iter.setValue(ComputeType(*iter) + a*offset); } } } else { for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) { - iter.setValue(*iter + offset); + iter.setValue(ComputeType(*iter) + offset); } } } @@ -540,7 +545,7 @@ LevelSetFilter::Filter::medianImpl(const LeafRange& ra for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - buffer[iter.pos()] = b * (*iter) + a * stencil.median(); + buffer[iter.pos()] = b * ComputeType(*iter) + a * stencil.median(); } } } @@ -571,7 +576,7 @@ LevelSetFilter::Filter::boxImpl(const LeafRange& range ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { const Coord xyz = iter.getCoord(); - if (alpha(xyz, a, b)) buffer[iter.pos()] = b * (*iter)+ a * avg(xyz); + if (alpha(xyz, a, b)) buffer[iter.pos()] = b * ComputeType(*iter)+ a * avg(xyz); } } } else { @@ -596,6 +601,7 @@ LevelSetFilter::Filter::boxImpl(const LeafRange& range #include #endif +OPENVDB_INSTANTIATE_CLASS LevelSetFilter; OPENVDB_INSTANTIATE_CLASS LevelSetFilter; OPENVDB_INSTANTIATE_CLASS LevelSetFilter; diff --git a/openvdb/openvdb/tools/LevelSetMeasure.h b/openvdb/openvdb/tools/LevelSetMeasure.h index 5a31ffe6fe..9e1a50e87a 100644 --- a/openvdb/openvdb/tools/LevelSetMeasure.h +++ b/openvdb/openvdb/tools/LevelSetMeasure.h @@ -105,10 +105,10 @@ class LevelSetMeasure public: using GridType = GridT; using TreeType = typename GridType::TreeType; - using ValueType = typename TreeType::ValueType; + using ComputeType = typename TreeType::ComputeType; using ManagerType = typename tree::LeafManager; - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "level set measure is supported only for scalar, floating-point grids"); /// @brief Main constructor from a grid @@ -344,7 +344,7 @@ inline void LevelSetMeasure:: MeasureArea::operator()(const LeafRange& range) const { - using Vec3T = math::Vec3; + using Vec3T = math::Vec3; // computations are performed in index space where dV = 1 mParent->checkInterrupter(); const Real invDx = 1.0/mParent->mDx; @@ -374,12 +374,12 @@ inline void LevelSetMeasure:: MeasureCurvatures::operator()(const LeafRange& range) const { - using Vec3T = math::Vec3; + using Vec3T = math::Vec3; // computations are performed in index space where dV = 1 mParent->checkInterrupter(); const Real dx = mParent->mDx, dx2=dx*dx, invDx = 1.0/dx; const DiracDelta DD(1.5);// dirac delta function is 3 voxel units wide - ValueType mean, gauss; + ComputeType mean, gauss; const size_t leafCount = mParent->mLeafs->leafCount(); for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { Real sumM = 0, sumG = 0;//reduce risk of catastrophic cancellation @@ -408,7 +408,7 @@ MeasureCurvatures::operator()(const LeafRange& range) const template inline -typename std::enable_if::value, Real>::type +typename std::enable_if::value, Real>::type doLevelSetArea(const GridT& grid, bool useWorldUnits) { LevelSetMeasure m(grid); @@ -417,7 +417,7 @@ doLevelSetArea(const GridT& grid, bool useWorldUnits) template inline -typename std::enable_if::value, Real>::type +typename std::enable_if::value, Real>::type doLevelSetArea(const GridT&, bool) { OPENVDB_THROW(TypeError, @@ -441,7 +441,7 @@ levelSetArea(const GridT& grid, bool useWorldUnits) template inline -typename std::enable_if::value, Real>::type +typename std::enable_if::value, Real>::type doLevelSetVolume(const GridT& grid, bool useWorldUnits) { LevelSetMeasure m(grid); @@ -450,7 +450,7 @@ doLevelSetVolume(const GridT& grid, bool useWorldUnits) template inline -typename std::enable_if::value, Real>::type +typename std::enable_if::value, Real>::type doLevelSetVolume(const GridT&, bool) { OPENVDB_THROW(TypeError, @@ -474,7 +474,7 @@ levelSetVolume(const GridT& grid, bool useWorldUnits) template inline -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type doLevelSetEulerCharacteristic(const GridT& grid) { LevelSetMeasure m(grid); @@ -483,7 +483,7 @@ doLevelSetEulerCharacteristic(const GridT& grid) template inline -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type doLevelSetEulerCharacteristic(const GridT&) { OPENVDB_THROW(TypeError, @@ -508,7 +508,7 @@ levelSetEulerCharacteristic(const GridT& grid) template inline -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type doLevelSetEuler(const GridT& grid) { LevelSetMeasure m(grid); @@ -518,7 +518,7 @@ doLevelSetEuler(const GridT& grid) template inline -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type doLevelSetGenus(const GridT& grid) { LevelSetMeasure m(grid); @@ -527,7 +527,7 @@ doLevelSetGenus(const GridT& grid) template inline -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type doLevelSetGenus(const GridT&) { OPENVDB_THROW(TypeError, @@ -576,6 +576,7 @@ OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) #undef _FUNCTION +OPENVDB_INSTANTIATE_CLASS LevelSetMeasure; OPENVDB_INSTANTIATE_CLASS LevelSetMeasure; OPENVDB_INSTANTIATE_CLASS LevelSetMeasure; diff --git a/openvdb/openvdb/tools/LevelSetMorph.h b/openvdb/openvdb/tools/LevelSetMorph.h index e455d07d25..1b4006e1e4 100644 --- a/openvdb/openvdb/tools/LevelSetMorph.h +++ b/openvdb/openvdb/tools/LevelSetMorph.h @@ -54,6 +54,7 @@ class LevelSetMorphing using LeafType = typename TrackerT::LeafType; using BufferType = typename TrackerT::BufferType; using ValueType = typename TrackerT::ValueType; + using ComputeType = typename TrackerT::ComputeType; /// Main constructor LevelSetMorphing(GridT& sourceGrid, const GridT& targetGrid, InterruptT* interrupt = nullptr) @@ -119,11 +120,11 @@ class LevelSetMorphing /// @brief Return the minimum value of the mask to be used for the /// derivation of a smooth alpha value. - ValueType minMask() const { return mMinMask; } + ComputeType minMask() const { return mMinMask; } /// @brief Return the maximum value of the mask to be used for the /// derivation of a smooth alpha value. - ValueType maxMask() const { return mDeltaMask + mMinMask; } + ComputeType maxMask() const { return mDeltaMask + mMinMask; } /// @brief Define the range for the (optional) scalar mask. /// @param min Minimum value of the range. @@ -132,7 +133,7 @@ class LevelSetMorphing /// respectfully zero and one, and values inside the range maps /// smoothly to 0->1 (unless of course the mask is inverted). /// @throw ValueError if @a min is not smaller than @a max. - void setMaskRange(ValueType min, ValueType max) + void setMaskRange(ComputeType min, ComputeType max) { if (!(min < max)) OPENVDB_THROW(ValueError, "Invalid mask range (expects min < max)"); mMinMask = min; @@ -150,7 +151,7 @@ class LevelSetMorphing /// final time, @a time1. If @a time0 > @a time1, perform backward advection. /// /// @return the number of CFL iterations used to advect from @a time0 to @a time1 - size_t advect(ValueType time0, ValueType time1); + size_t advect(ComputeType time0, ComputeType time1); private: @@ -159,22 +160,22 @@ class LevelSetMorphing LevelSetMorphing& operator=(const LevelSetMorphing&);// not implemented template - size_t advect1(ValueType time0, ValueType time1); + size_t advect1(ComputeType time0, ComputeType time1); template - size_t advect2(ValueType time0, ValueType time1); + size_t advect2(ComputeType time0, ComputeType time1); template - size_t advect3(ValueType time0, ValueType time1); + size_t advect3(ComputeType time0, ComputeType time1); TrackerT mTracker; const GridT *mTarget, *mMask; math::BiasedGradientScheme mSpatialScheme; math::TemporalIntegrationScheme mTemporalScheme; - ValueType mMinMask, mDeltaMask; + ComputeType mMinMask, mDeltaMask; bool mInvertMask; // This templated private class implements all the level set magic. @@ -192,7 +193,7 @@ class LevelSetMorphing virtual ~Morph() {} /// Advect the level set from its current time, time0, to its final time, time1. /// @return number of CFL iterations - size_t advect(ValueType time0, ValueType time1); + size_t advect(ComputeType time0, ComputeType time1); /// Used internally by tbb::parallel_for() void operator()(const LeafRange& r) const { @@ -214,22 +215,23 @@ class LevelSetMorphing void cook(ThreadingMode mode, size_t swapBuffer = 0); /// Sample field and return the CFT time step - typename GridT::ValueType sampleSpeed(ValueType time0, ValueType time1, Index speedBuffer); + typename GridT::ComputeType sampleSpeed(ComputeType time0, + ComputeType time1, Index speedBuffer); void sampleXformedSpeed(const LeafRange& r, Index speedBuffer); void sampleAlignedSpeed(const LeafRange& r, Index speedBuffer); // Convex combination of Phi and a forward Euler advection steps: // Phi(result) = alpha * Phi(phi) + (1-alpha) * (Phi(0) - dt * Speed(speed)*|Grad[Phi(0)]|); template - void euler(const LeafRange&, ValueType, Index, Index, Index); - inline void euler01(const LeafRange& r, ValueType t, Index s) {this->euler<0,1>(r,t,0,1,s);} - inline void euler12(const LeafRange& r, ValueType t) {this->euler<1,2>(r, t, 1, 1, 2);} - inline void euler34(const LeafRange& r, ValueType t) {this->euler<3,4>(r, t, 1, 2, 3);} - inline void euler13(const LeafRange& r, ValueType t) {this->euler<1,3>(r, t, 1, 2, 3);} + void euler(const LeafRange&, ComputeType, Index, Index, Index); + inline void euler01(const LeafRange& r, ComputeType t, Index s) {this->euler<0,1>(r,t,0,1,s);} + inline void euler12(const LeafRange& r, ComputeType t) {this->euler<1,2>(r, t, 1, 1, 2);} + inline void euler34(const LeafRange& r, ComputeType t) {this->euler<3,4>(r, t, 1, 2, 3);} + inline void euler13(const LeafRange& r, ComputeType t) {this->euler<1,3>(r, t, 1, 2, 3);} using FuncType = typename std::function; LevelSetMorphing* mParent; - ValueType mMinAbsS, mMaxAbsS; + ComputeType mMinAbsS, mMaxAbsS; const MapT* mMap; FuncType mTask; }; // end of private Morph struct @@ -238,7 +240,7 @@ class LevelSetMorphing template inline size_t -LevelSetMorphing::advect(ValueType time0, ValueType time1) +LevelSetMorphing::advect(ComputeType time0, ComputeType time1) { switch (mSpatialScheme) { case math::FIRST_BIAS: @@ -264,7 +266,7 @@ LevelSetMorphing::advect(ValueType time0, ValueType time1) template template inline size_t -LevelSetMorphing::advect1(ValueType time0, ValueType time1) +LevelSetMorphing::advect1(ComputeType time0, ComputeType time1) { switch (mTemporalScheme) { case math::TVD_RK1: @@ -284,7 +286,7 @@ template template inline size_t -LevelSetMorphing::advect2(ValueType time0, ValueType time1) +LevelSetMorphing::advect2(ComputeType time0, ComputeType time1) { const math::Transform& trans = mTracker.grid().transform(); if (trans.mapType() == math::UniformScaleMap::mapType()) { @@ -307,7 +309,7 @@ template inline size_t -LevelSetMorphing::advect3(ValueType time0, ValueType time1) +LevelSetMorphing::advect3(ComputeType time0, ComputeType time1) { Morph tmp(*this); return tmp.advect(time0, time1); @@ -324,7 +326,7 @@ LevelSetMorphing:: Morph:: Morph(LevelSetMorphing& parent) : mParent(&parent) - , mMinAbsS(ValueType(1e-6)) + , mMinAbsS(ComputeType(1e-6)) , mMap(parent.mTracker.grid().transform().template constMap().get()) , mTask(nullptr) { @@ -366,7 +368,7 @@ template :: Morph:: -advect(ValueType time0, ValueType time1) +advect(ComputeType time0, ComputeType time1) { namespace ph = std::placeholders; @@ -377,7 +379,7 @@ advect(ValueType time0, ValueType time1) while (time0 < time1 && mParent->mTracker.checkInterrupter()) { mParent->mTracker.leafs().rebuildAuxBuffers(auxBuffers); - const ValueType dt = this->sampleSpeed(time0, time1, auxBuffers); + const typename GridT::ComputeType dt = this->sampleSpeed(time0, time1, auxBuffers); if ( math::isZero(dt) ) break;//V is essentially zero so terminate OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN //switch is resolved at compile-time @@ -447,16 +449,16 @@ advect(ValueType time0, ValueType time1) template template -inline typename GridT::ValueType +inline typename GridT::ComputeType LevelSetMorphing:: Morph:: -sampleSpeed(ValueType time0, ValueType time1, Index speedBuffer) +sampleSpeed(ComputeType time0, ComputeType time1, Index speedBuffer) { namespace ph = std::placeholders; mMaxAbsS = mMinAbsS; const size_t leafCount = mParent->mTracker.leafs().leafCount(); - if (leafCount==0 || time0 >= time1) return ValueType(0); + if (leafCount==0 || time0 >= time1) return ComputeType(0); const math::Transform& xform = mParent->mTracker.grid().transform(); if (mParent->mTarget->transform() == xform && @@ -466,12 +468,12 @@ sampleSpeed(ValueType time0, ValueType time1, Index speedBuffer) mTask = std::bind(&Morph::sampleXformedSpeed, ph::_1, ph::_2, speedBuffer); } this->cook(PARALLEL_REDUCE); - if (math::isApproxEqual(mMinAbsS, mMaxAbsS)) return ValueType(0);//speed is essentially zero - static const ValueType CFL = (TemporalScheme == math::TVD_RK1 ? ValueType(0.3) : - TemporalScheme == math::TVD_RK2 ? ValueType(0.9) : - ValueType(1.0))/math::Sqrt(ValueType(3.0)); - const ValueType dt = math::Abs(time1 - time0), dx = mParent->mTracker.voxelSize(); - return math::Min(dt, ValueType(CFL*dx/mMaxAbsS)); + if (math::isApproxEqual(mMinAbsS, mMaxAbsS)) return ComputeType(0);//speed is essentially zero + static const ComputeType CFL = (TemporalScheme == math::TVD_RK1 ? ComputeType(0.3) : + TemporalScheme == math::TVD_RK2 ? ComputeType(0.9) : + ComputeType(1.0))/math::Sqrt(ComputeType(3.0)); + const ComputeType dt = math::Abs(time1 - time0), dx = mParent->mTracker.voxelSize(); + return math::Min(dt, ComputeType(CFL*dx/mMaxAbsS)); } template @@ -498,12 +500,12 @@ sampleXformedSpeed(const LeafRange& range, Index speedBuffer) ValueType& s = speed[voxelIter.pos()]; s -= target.wsSample(map.applyMap(voxelIter.getCoord().asVec3d())); if (!math::isApproxZero(s)) isZero = false; - mMaxAbsS = math::Max(mMaxAbsS, math::Abs(s)); + mMaxAbsS = math::Max(mMaxAbsS, ComputeType(math::Abs(s))); } if (isZero) speed[0] = std::numeric_limits::max();//tag first voxel } } else { - const ValueType min = mParent->mMinMask, invNorm = 1.0f/(mParent->mDeltaMask); + const ComputeType min = mParent->mMinMask, invNorm = 1.0f/(mParent->mDeltaMask); const bool invMask = mParent->isMaskInverted(); typename GridT::ConstAccessor maskAcc = mParent->mMask->getAccessor(); SamplerT mask(maskAcc, mParent->mMask->transform()); @@ -512,12 +514,12 @@ sampleXformedSpeed(const LeafRange& range, Index speedBuffer) bool isZero = true; for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) { const Vec3R xyz = map.applyMap(voxelIter.getCoord().asVec3d());//world space - const ValueType a = math::SmoothUnitStep((mask.wsSample(xyz)-min)*invNorm); + const ComputeType a = math::SmoothUnitStep((mask.wsSample(xyz)-min)*invNorm); ValueType& s = speed[voxelIter.pos()]; s -= target.wsSample(xyz); - s *= invMask ? 1 - a : a; + s *= invMask ? ValueType(1 - a) : ValueType(a); if (!math::isApproxZero(s)) isZero = false; - mMaxAbsS = math::Max(mMaxAbsS, math::Abs(s)); + mMaxAbsS = math::Max(mMaxAbsS, ComputeType(math::Abs(s))); } if (isZero) speed[0] = std::numeric_limits::max();//tag first voxel } @@ -546,12 +548,12 @@ sampleAlignedSpeed(const LeafRange& range, Index speedBuffer) ValueType& s = speed[voxelIter.pos()]; s -= target.getValue(voxelIter.getCoord()); if (!math::isApproxZero(s)) isZero = false; - mMaxAbsS = math::Max(mMaxAbsS, math::Abs(s)); + mMaxAbsS = math::Max(mMaxAbsS, ComputeType(math::Abs(s))); } if (isZero) speed[0] = std::numeric_limits::max();//tag first voxel } } else { - const ValueType min = mParent->mMinMask, invNorm = 1.0f/(mParent->mDeltaMask); + const ComputeType min = mParent->mMinMask, invNorm = 1.0f/(mParent->mDeltaMask); const bool invMask = mParent->isMaskInverted(); typename GridT::ConstAccessor mask = mParent->mMask->getAccessor(); for (typename LeafRange::Iterator leafIter = range.begin(); leafIter; ++leafIter) { @@ -559,12 +561,12 @@ sampleAlignedSpeed(const LeafRange& range, Index speedBuffer) bool isZero = true; for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) { const Coord ijk = voxelIter.getCoord();//index space - const ValueType a = math::SmoothUnitStep((mask.getValue(ijk)-min)*invNorm); + const ComputeType a = math::SmoothUnitStep((mask.getValue(ijk)-min)*invNorm); ValueType& s = speed[voxelIter.pos()]; s -= target.getValue(ijk); - s *= invMask ? 1 - a : a; + s *= invMask ? ValueType(1 - a) : ValueType(a); if (!math::isApproxZero(s)) isZero = false; - mMaxAbsS = math::Max(mMaxAbsS, math::Abs(s)); + mMaxAbsS = math::Max(mMaxAbsS, ComputeType(math::Abs(s))); } if (isZero) speed[0] = std::numeric_limits::max();//tag first voxel } @@ -607,7 +609,7 @@ template inline void LevelSetMorphing:: Morph:: -euler(const LeafRange& range, ValueType dt, +euler(const LeafRange& range, ComputeType dt, Index phiBuffer, Index resultBuffer, Index speedBuffer) { using SchemeT = math::BIAS_SCHEME; @@ -615,8 +617,8 @@ euler(const LeafRange& range, ValueType dt, using VoxelIterT = typename LeafType::ValueOnCIter; using NumGrad = math::GradientNormSqrd; - static const ValueType Alpha = ValueType(Nominator)/ValueType(Denominator); - static const ValueType Beta = ValueType(1) - Alpha; + static const ComputeType Alpha = ComputeType(Nominator)/ComputeType(Denominator); + static const ComputeType Beta = ComputeType(1) - Alpha; mParent->mTracker.checkInterrupter(); const MapT& map = *mMap; @@ -631,8 +633,9 @@ euler(const LeafRange& range, ValueType dt, const Index n = voxelIter.pos(); if (math::isApproxZero(speed[n])) continue; stencil.moveTo(voxelIter); - const ValueType v = stencil.getValue() - dt * speed[n] * NumGrad::result(map, stencil); - result[n] = Nominator ? Alpha * phi[n] + Beta * v : v; + const ComputeType v = ComputeType(stencil.getValue()) - + dt * ComputeType(speed[n]) * ComputeType(NumGrad::result(map, stencil)); + result[n] = Nominator ? ValueType(Alpha * phi[n] + Beta * v) : ValueType(v); }//loop over active voxels in the leaf of the mask }//loop over leafs of the level set } @@ -649,6 +652,7 @@ euler(const LeafRange& range, ValueType dt, #include #endif +OPENVDB_INSTANTIATE_CLASS LevelSetMorphing; OPENVDB_INSTANTIATE_CLASS LevelSetMorphing; OPENVDB_INSTANTIATE_CLASS LevelSetMorphing; diff --git a/openvdb/openvdb/tools/LevelSetSphere.h b/openvdb/openvdb/tools/LevelSetSphere.h index 83dac13496..5ff6f496f7 100644 --- a/openvdb/openvdb/tools/LevelSetSphere.h +++ b/openvdb/openvdb/tools/LevelSetSphere.h @@ -90,8 +90,9 @@ class LevelSetSphere public: using TreeT = typename GridT::TreeType; using ValueT = typename GridT::ValueType; - using Vec3T = typename math::Vec3; - static_assert(std::is_floating_point::value, + using ComputeT = typename GridT::ComputeType; + using Vec3T = typename math::Vec3; + static_assert(std::is_floating_point::value, "level set grids must have scalar, floating-point value types"); /// @brief Constructor @@ -104,7 +105,7 @@ class LevelSetSphere /// @note If the radius of the sphere is smaller than /// 1.5*voxelSize, i.e. the sphere is smaller than the Nyquist /// frequency of the grid, it is ignored! - LevelSetSphere(ValueT radius, const Vec3T ¢er, InterruptT* interrupt = nullptr) + LevelSetSphere(ComputeT radius, const Vec3T ¢er, InterruptT* interrupt = nullptr) : mRadius(radius), mCenter(center), mInterrupt(interrupt) { if (mRadius<=0) OPENVDB_THROW(ValueError, "radius must be positive"); @@ -115,7 +116,7 @@ class LevelSetSphere /// @param voxelSize Size of voxels in world units /// @param halfWidth Half-width of narrow-band in voxel units /// @param threaded If true multi-threading is enabled (true by default) - typename GridT::Ptr getLevelSet(ValueT voxelSize, ValueT halfWidth, bool threaded = true) + typename GridT::Ptr getLevelSet(ComputeT voxelSize, ComputeT halfWidth, bool threaded = true) { mGrid = createLevelSet(voxelSize, halfWidth); this->rasterSphere(voxelSize, halfWidth, threaded); @@ -124,7 +125,7 @@ class LevelSetSphere } private: - void rasterSphere(ValueT dx, ValueT w, bool threaded) + void rasterSphere(ComputeT dx, ComputeT w, bool threaded) { if (!(dx>0.0f)) OPENVDB_THROW(ValueError, "voxel size must be positive"); if (!(w>1)) OPENVDB_THROW(ValueError, "half-width must be larger than one"); @@ -158,16 +159,16 @@ class LevelSetSphere // Compute signed distances to sphere using leapfrogging in k for (i = r.begin(); i != r.end(); ++i) { if (util::wasInterrupted(mInterrupt)) return; - const auto x2 = math::Pow2(ValueT(i) - c[0]); + const auto x2 = math::Pow2(ComputeT(i) - c[0]); for (j = jmin; j <= jmax; ++j) { - const auto x2y2 = math::Pow2(ValueT(j) - c[1]) + x2; + const auto x2y2 = math::Pow2(ComputeT(j) - c[1]) + x2; for (k = kmin; k <= kmax; k += m) { m = 1; // Distance in voxel units to sphere - const auto v = math::Sqrt(x2y2 + math::Pow2(ValueT(k)-c[2]))-r0; + const auto v = math::Sqrt(x2y2 + math::Pow2(ComputeT(k)-c[2]))-r0; const auto d = math::Abs(v); if (d < w) { // inside narrow band - acc.setValue(ijk, dx*v);// distance in world units + acc.setValue(ijk, ValueT(dx*v));// distance in world units } else { // outside narrow band m += math::Floor(d-w);// leapfrog } @@ -221,12 +222,12 @@ createLevelSetSphere(float radius, const openvdb::Vec3f& center, float voxelSize float halfWidth, InterruptT* interrupt, bool threaded) { // GridType::ValueType is required to be a floating-point scalar. - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "level set grids must have scalar, floating-point value types"); - using ValueT = typename GridType::ValueType; - LevelSetSphere factory(ValueT(radius), center, interrupt); - return factory.getLevelSet(ValueT(voxelSize), ValueT(halfWidth), threaded); + using ComputeT = typename GridType::ComputeType; + LevelSetSphere factory(ComputeT(radius), center, interrupt); + return factory.getLevelSet(ComputeT(voxelSize), ComputeT(halfWidth), threaded); } diff --git a/openvdb/openvdb/tools/LevelSetTracker.h b/openvdb/openvdb/tools/LevelSetTracker.h index d171cabf95..8cdec9373d 100644 --- a/openvdb/openvdb/tools/LevelSetTracker.h +++ b/openvdb/openvdb/tools/LevelSetTracker.h @@ -63,11 +63,12 @@ class LevelSetTracker using TreeType = typename GridT::TreeType; using LeafType = typename TreeType::LeafNodeType; using ValueType = typename TreeType::ValueType; + using ComputeType = typename TreeType::ComputeType; using LeafManagerType = typename tree::LeafManager; // leafs + buffers using LeafRange = typename LeafManagerType::LeafRange; using BufferType = typename LeafManagerType::BufferType; using MaskTreeType = typename TreeType::template ValueConverter::Type; - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "LevelSetTracker requires a level set grid with floating-point values"); /// Lightweight struct that stores the state of the LevelSetTracker @@ -132,7 +133,7 @@ class LevelSetTracker bool resize(Index halfWidth = static_cast(LEVEL_SET_HALF_WIDTH)); /// @brief Return the half width of the narrow band in floating-point voxel units. - ValueType getHalfWidth() const { return mGrid->background()/mDx; } + ValueType getHalfWidth() const { return ComputeType(mGrid->background())/mDx; } /// @brief Return the state of the tracker (see struct defined above) State getState() const { return mState; } @@ -232,7 +233,7 @@ class LevelSetTracker void eval(StencilT& stencil, const ValueType* phi, ValueType* result, Index n) const; LevelSetTracker& mTracker; const MaskT* mMask; - const ValueType mDt, mInvDx; + const ComputeType mDt, mInvDx; typename std::function mTask; }; // Normalizer struct @@ -247,12 +248,12 @@ class LevelSetTracker // a list of the current LeafNodes! The auxiliary buffers on the // other hand always have to be allocated locally, since some // methods need them and others don't! - GridType* mGrid; - LeafManagerType* mLeafs; - InterruptT* mInterrupter; - const ValueType mDx; - State mState; - TrimMode mTrimMode = TrimMode::kAll; + GridType* mGrid; + LeafManagerType* mLeafs; + InterruptT* mInterrupter; + const ComputeType mDx; + State mState; + TrimMode mTrimMode = TrimMode::kAll; }; // end of LevelSetTracker class template @@ -261,7 +262,7 @@ LevelSetTracker(GridT& grid, InterruptT* interrupt): mGrid(&grid), mLeafs(new LeafManagerType(grid.tree())), mInterrupter(interrupt), - mDx(static_cast(grid.voxelSize()[0])), + mDx(static_cast(grid.voxelSize()[0])), mState() { if ( !grid.hasUniformVoxels() ) { @@ -328,7 +329,8 @@ dilate(int iterations) for (int i=0; i < iterations; ++i) { MaskTreeType mask0(mGrid->tree(), false, TopologyCopy()); tools::dilateActiveValues( *mLeafs, 1, tools::NN_FACE, tools::IGNORE_TILES); - tools::changeLevelSetBackground(this->leafs(), mDx + mGrid->background()); + tools::changeLevelSetBackground(this->leafs(), + ValueType(mDx + ComputeType(mGrid->background()))); MaskTreeType mask(mGrid->tree(), false, TopologyCopy()); mask.topologyDifference(mask0); this->normalize(&mask); @@ -344,7 +346,7 @@ erode(int iterations) tools::erodeActiveValues(*mLeafs, iterations, tools::NN_FACE, tools::IGNORE_TILES); tools::pruneLevelSet(mLeafs->tree()); mLeafs->rebuildLeafArray(); - const ValueType background = mGrid->background() - ValueType(iterations) * mDx; + const ValueType background = ComputeType(mGrid->background()) - ComputeType(iterations) * mDx; tools::changeLevelSetBackground(this->leafs(), background); } @@ -518,9 +520,10 @@ Normalizer:: Normalizer(LevelSetTracker& tracker, const MaskT* mask) : mTracker(tracker) , mMask(mask) - , mDt(tracker.voxelSize()*(TemporalScheme == math::TVD_RK1 ? 0.3f : + , mDt(ComputeType(tracker.grid().voxelSize()[0]) * + (TemporalScheme == math::TVD_RK1 ? 0.3f : TemporalScheme == math::TVD_RK2 ? 0.9f : 1.0f)) - , mInvDx(1.0f/tracker.voxelSize()) + , mInvDx(1.0f/ComputeType(tracker.grid().voxelSize()[0])) , mTask(nullptr) { } @@ -631,15 +634,15 @@ Normalizer:: eval(StencilT& stencil, const ValueType* phi, ValueType* result, Index n) const { using GradientT = typename math::ISGradientNormSqrd; - static const ValueType alpha = ValueType(Nominator)/ValueType(Denominator); - static const ValueType beta = ValueType(1) - alpha; - - const ValueType normSqGradPhi = GradientT::result(stencil); - const ValueType phi0 = stencil.getValue(); - ValueType v = phi0 / ( math::Sqrt(math::Pow2(phi0) + normSqGradPhi) + - math::Tolerance::value() ); - v = phi0 - mDt * v * (math::Sqrt(normSqGradPhi) * mInvDx - 1.0f); - result[n] = Nominator ? alpha * phi[n] + beta * v : v; + static const ComputeType alpha = ComputeType(Nominator)/ComputeType(Denominator); + static const ComputeType beta = ComputeType(1) - alpha; + + const ComputeType normSqGradPhi = GradientT::result(stencil); + const ComputeType phi0 = stencil.getValue(); + ComputeType v = phi0 / ( math::Sqrt(math::Pow2(phi0) + normSqGradPhi) + + math::Tolerance::value() ); + v = phi0 - mDt * v * (math::Sqrt(normSqGradPhi) * mInvDx - ComputeType(1)); + result[n] = Nominator ? ComputeType(alpha * ComputeType(phi[n]) + beta * v) : v; } template @@ -687,6 +690,7 @@ euler(const LeafRange& range, Index phiBuffer, Index resultBuffer) #include #endif +OPENVDB_INSTANTIATE_CLASS LevelSetTracker; OPENVDB_INSTANTIATE_CLASS LevelSetTracker; OPENVDB_INSTANTIATE_CLASS LevelSetTracker; diff --git a/openvdb/openvdb/tools/LevelSetUtil.h b/openvdb/openvdb/tools/LevelSetUtil.h index 012da732ec..17b5c82283 100644 --- a/openvdb/openvdb/tools/LevelSetUtil.h +++ b/openvdb/openvdb/tools/LevelSetUtil.h @@ -461,7 +461,8 @@ struct SDFVoxelsToFogVolume { ValueType* values = node.buffer().data(); for (Index i = 0; i < LeafNodeType::SIZE; ++i) { - values[i] = values[i] > ValueType(0.0) ? ValueType(0.0) : values[i] * mWeight; + values[i] = values[i] > ValueType(0.0) ? + ValueType(0.0) : ValueType(values[i] * mWeight); if (values[i] > ValueType(0.0)) node.setValueOn(i); } diff --git a/openvdb/openvdb/tools/MeshToVolume.h b/openvdb/openvdb/tools/MeshToVolume.h index 6d85f23576..dcd656ec09 100644 --- a/openvdb/openvdb/tools/MeshToVolume.h +++ b/openvdb/openvdb/tools/MeshToVolume.h @@ -19,6 +19,7 @@ #include #include #include // for GodunovsNormSqrd +#include // for isFinite(), isNan() #include // for closestPointOnTriangleToPoint #include #include @@ -39,7 +40,6 @@ #include #include // for std::sort() -#include // for std::isfinite(), std::isnan() #include #include #include @@ -3348,7 +3348,7 @@ meshToVolume( // Note: inf interior width is all right, this value makes the converter fill // interior regions with distance values. - if (!std::isfinite(exteriorWidth) || std::isnan(interiorWidth)) { + if (!math::isFinite(exteriorWidth) || math::isNan(interiorWidth)) { std::stringstream msg; msg << "Illegal narrow band width: exterior = " << exteriorWidth << ", interior = " << interiorWidth; @@ -3358,7 +3358,7 @@ meshToVolume( const ValueType voxelSize = ValueType(transform.voxelSize()[0]); - if (!std::isfinite(voxelSize) || math::isZero(voxelSize)) { + if (!math::isFinite(voxelSize) || math::isZero(voxelSize)) { std::stringstream msg; msg << "Illegal transform, voxel size = " << voxelSize; OPENVDB_LOG_DEBUG(msg.str()); diff --git a/openvdb/openvdb/tools/RayIntersector.h b/openvdb/openvdb/tools/RayIntersector.h index c97942ad82..b60cb323d6 100644 --- a/openvdb/openvdb/tools/RayIntersector.h +++ b/openvdb/openvdb/tools/RayIntersector.h @@ -88,6 +88,7 @@ class LevelSetRayIntersector using RealType = typename RayT::RealType; using Vec3Type = typename RayT::Vec3T; using ValueT = typename GridT::ValueType; + using ComputeT = typename GridT::ComputeType; using TreeT = typename GridT::TreeType; static_assert(NodeLevel >= -1 && NodeLevel < int(TreeT::DEPTH)-1, "NodeLevel out of range"); @@ -97,7 +98,7 @@ class LevelSetRayIntersector /// @brief Constructor /// @param grid level set grid to intersect rays against. /// @param isoValue optional iso-value for the ray-intersection. - LevelSetRayIntersector(const GridT& grid, const ValueT& isoValue = zeroVal()) + LevelSetRayIntersector(const GridT& grid, const ComputeT& isoValue = zeroVal()) : mTester(grid, isoValue) { if (!grid.hasUniformVoxels() ) { @@ -112,7 +113,7 @@ class LevelSetRayIntersector } /// @brief Return the iso-value used for ray-intersections - const ValueT& getIsoValue() const { return mTester.getIsoValue(); } + const ComputeT& getIsoValue() const { return mTester.getIsoValue(); } /// @brief Return @c true if the index-space ray intersects the level set. /// @param iRay ray represented in index space. @@ -516,17 +517,18 @@ class LinearSearchImpl using RayT = math::Ray; using VecT = math::Vec3; using ValueT = typename GridT::ValueType; + using ComputeT = typename GridT::ComputeType; using AccessorT = typename GridT::ConstAccessor; using StencilT = math::BoxStencil; /// @brief Constructor from a grid. /// @throw RunTimeError if the grid is empty. /// @throw ValueError if the isoValue is not inside the narrow-band. - LinearSearchImpl(const GridT& grid, const ValueT& isoValue = zeroVal()) + LinearSearchImpl(const GridT& grid, const ComputeT& isoValue = zeroVal()) : mStencil(grid), mIsoValue(isoValue), - mMinValue(isoValue - ValueT(2 * grid.voxelSize()[0])), - mMaxValue(isoValue + ValueT(2 * grid.voxelSize()[0])) + mMinValue(isoValue - ComputeT(2 * grid.voxelSize()[0])), + mMaxValue(isoValue + ComputeT(2 * grid.voxelSize()[0])) { if ( grid.empty() ) { OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids"); @@ -539,7 +541,7 @@ class LinearSearchImpl } /// @brief Return the iso-value used for ray-intersections - const ValueT& getIsoValue() const { return mIsoValue; } + const ComputeT& getIsoValue() const { return mIsoValue; } /// @brief Return @c false if the ray misses the bbox of the grid. /// @param iRay Ray represented in index space. @@ -595,7 +597,7 @@ class LinearSearchImpl inline void init(RealT t0) { mT[0] = t0; - mV[0] = static_cast(this->interpValue(t0)); + mV[0] = static_cast(this->interpValue(t0)); } inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); } @@ -617,26 +619,28 @@ class LinearSearchImpl /// call getIndexPos, getWorldPos and getWorldPosAndNml! inline bool operator()(const Coord& ijk, RealT time) { - ValueT V; - if (mStencil.accessor().probeValue(ijk, V) &&//within narrow band - V>mMinValue && V(this->interpValue(time)); - if (math::ZeroCrossing(mV[0], mV[1])) { - mTime = this->interpTime(); - OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN - for (int n=0; Iterations>0 && n(this->interpValue(mTime)); - const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0; - mV[m] = V; - mT[m] = mTime; + ValueT V_raw; + if (mStencil.accessor().probeValue(ijk, V_raw)) {//within narrow band + ComputeT V = V_raw; + if (V>mMinValue && V(this->interpValue(time)); + if (math::ZeroCrossing(mV[0], mV[1])) { mTime = this->interpTime(); + OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN + for (int n=0; Iterations>0 && n(this->interpValue(mTime)); + const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0; + mV[m] = V; + mT[m] = mTime; + mTime = this->interpTime(); + } + OPENVDB_NO_UNREACHABLE_CODE_WARNING_END + return true; } - OPENVDB_NO_UNREACHABLE_CODE_WARNING_END - return true; + mT[0] = mT[1]; + mV[0] = mV[1]; } - mT[0] = mT[1]; - mV[0] = mV[1]; } return false; } @@ -659,9 +663,9 @@ class LinearSearchImpl RayT mRay; StencilT mStencil; RealT mTime;//time of intersection - ValueT mV[2]; + ComputeT mV[2]; RealT mT[2]; - const ValueT mIsoValue, mMinValue, mMaxValue; + const ComputeT mIsoValue, mMinValue, mMaxValue; math::CoordBBox mBBox; };// LinearSearchImpl diff --git a/openvdb/openvdb/tools/RayTracer.h b/openvdb/openvdb/tools/RayTracer.h index fc11b34161..5896f9664c 100644 --- a/openvdb/openvdb/tools/RayTracer.h +++ b/openvdb/openvdb/tools/RayTracer.h @@ -152,10 +152,10 @@ class VolumeRender using GridType = typename IntersectorT::GridType; using RayType = typename IntersectorT::RayType; - using ValueType = typename GridType::ValueType; + using ComputeType = typename GridType::ComputeType; using AccessorType = typename GridType::ConstAccessor; using SamplerType = tools::GridSampler; - static_assert(std::is_floating_point::value, + static_assert(std::is_floating_point::value, "VolumeRender requires a floating-point-valued grid"); /// @brief Constructor taking an intersector and a base camera. @@ -549,9 +549,11 @@ class MatteShader: public BaseShader ~MatteShader() override = default; Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override { + using RealT = Film::RGBA::ValueT; + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); - return Film::RGBA(v[0], v[1], v[2]); + return Film::RGBA(RealT(v[0]), RealT(v[1]), RealT(v[2])); } BaseShader* copy() const override { return new MatteShader(*this); } @@ -596,9 +598,13 @@ class NormalShader: public BaseShader ~NormalShader() override = default; Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R&) const override { + using RealT = Film::RGBA::ValueT; + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); - return Film::RGBA(v[0]*(normal[0]+1.0), v[1]*(normal[1]+1.0), v[2]*(normal[2]+1.0)); + return Film::RGBA(RealT(v[0])*(normal[0]+1.0), + RealT(v[1])*(normal[1]+1.0), + RealT(v[2])*(normal[2]+1.0)); } BaseShader* copy() const override { return new NormalShader(*this); } @@ -649,10 +655,13 @@ class PositionShader: public BaseShader ~PositionShader() override = default; Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override { + using RealT = Film::RGBA::ValueT; + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); const Vec3R rgb = (xyz - mMin) * mInvDim; - return Film::RGBA(v[0],v[1],v[2]) * Film::RGBA(rgb[0], rgb[1], rgb[2]); + return Film::RGBA(RealT(v[0]), RealT(v[1]), RealT(v[2])) + * Film::RGBA(rgb[0], rgb[1], rgb[2]); } BaseShader* copy() const override { return new PositionShader(*this); } @@ -703,12 +712,14 @@ class DiffuseShader: public BaseShader ~DiffuseShader() override = default; Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R& rayDir) const override { + using RealT = Film::RGBA::ValueT; + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); // We take the abs of the dot product corresponding to having // light sources at +/- rayDir, i.e., two-sided shading. - return Film::RGBA(v[0],v[1],v[2]) - * static_cast(math::Abs(normal.dot(rayDir))); + return Film::RGBA(RealT(v[0]), RealT(v[1]), RealT(v[2])) + * static_cast(math::Abs(normal.dot(rayDir))); } BaseShader* copy() const override { return new DiffuseShader(*this); } diff --git a/openvdb/openvdb/tools/SignedFloodFill.h b/openvdb/openvdb/tools/SignedFloodFill.h index 03ff521dd0..d2bf0f4c70 100644 --- a/openvdb/openvdb/tools/SignedFloodFill.h +++ b/openvdb/openvdb/tools/SignedFloodFill.h @@ -83,9 +83,10 @@ class SignedFloodFillOp { public: using ValueT = typename TreeOrLeafManagerT::ValueType; + using ComputeT = typename TreeOrLeafManagerT::ComputeType; using RootT = typename TreeOrLeafManagerT::RootNodeType; using LeafT = typename TreeOrLeafManagerT::LeafNodeType; - static_assert(std::is_signed::value, + static_assert(std::is_signed::value, "signed flood fill is supported only for signed value grids"); SignedFloodFillOp(const TreeOrLeafManagerT& tree, Index minLevel = 0) @@ -116,19 +117,19 @@ class SignedFloodFillOp const Index first = valueMask.findFirstOn(); if (first < LeafT::SIZE) { - bool xInside = buffer[first]<0, yInside = xInside, zInside = xInside; + bool xInside = math::isNegative(buffer[first]), yInside = xInside, zInside = xInside; for (Index x = 0; x != (1 << LeafT::LOG2DIM); ++x) { const Index x00 = x << (2 * LeafT::LOG2DIM); - if (valueMask.isOn(x00)) xInside = buffer[x00] < 0; // element(x, 0, 0) + if (valueMask.isOn(x00)) xInside = math::isNegative(buffer[x00]); // element(x, 0, 0) yInside = xInside; for (Index y = 0; y != (1 << LeafT::LOG2DIM); ++y) { const Index xy0 = x00 + (y << LeafT::LOG2DIM); - if (valueMask.isOn(xy0)) yInside = buffer[xy0] < 0; // element(x, y, 0) + if (valueMask.isOn(xy0)) yInside = math::isNegative(buffer[xy0]); // element(x, y, 0) zInside = yInside; for (Index z = 0; z != (1 << LeafT::LOG2DIM); ++z) { const Index xyz = xy0 + z; // element(x, y, z) if (valueMask.isOn(xyz)) { - zInside = buffer[xyz] < 0; + zInside = math::isNegative(buffer[xyz]); } else { buffer[xyz] = zInside ? mInside : mOutside; } @@ -136,7 +137,7 @@ class SignedFloodFillOp } } } else {// if no active voxels exist simply use the sign of the first value - leaf.fill(buffer[0] < 0 ? mInside : mOutside); + leaf.fill(math::isNegative(buffer[0]) ? mInside : mOutside); } } @@ -152,20 +153,20 @@ class SignedFloodFillOp const Index first = childMask.findFirstOn(); if (first < NodeT::NUM_VALUES) { - bool xInside = table[first].getChild()->getFirstValue()<0; + bool xInside = math::isNegative(table[first].getChild()->getFirstValue()); bool yInside = xInside, zInside = xInside; for (Index x = 0; x != (1 << NodeT::LOG2DIM); ++x) { const int x00 = x << (2 * NodeT::LOG2DIM); // offset for block(x, 0, 0) - if (childMask.isOn(x00)) xInside = table[x00].getChild()->getLastValue()<0; + if (childMask.isOn(x00)) xInside = math::isNegative(table[x00].getChild()->getLastValue()); yInside = xInside; for (Index y = 0; y != (1 << NodeT::LOG2DIM); ++y) { const Index xy0 = x00 + (y << NodeT::LOG2DIM); // offset for block(x, y, 0) - if (childMask.isOn(xy0)) yInside = table[xy0].getChild()->getLastValue()<0; + if (childMask.isOn(xy0)) yInside = math::isNegative(table[xy0].getChild()->getLastValue()); zInside = yInside; for (Index z = 0; z != (1 << NodeT::LOG2DIM); ++z) { const Index xyz = xy0 + z; // offset for block(x, y, z) if (childMask.isOn(xyz)) { - zInside = table[xyz].getChild()->getLastValue()<0; + zInside = math::isNegative(table[xyz].getChild()->getLastValue()); } else { table[xyz].setValue(zInside ? mInside : mOutside); } @@ -215,7 +216,7 @@ class SignedFloodFillOp template inline -typename std::enable_if::value, void>::type +typename std::enable_if_t::value, void> doSignedFloodFill(TreeOrLeafManagerT& tree, typename TreeOrLeafManagerT::ValueType outsideValue, typename TreeOrLeafManagerT::ValueType insideValue, @@ -231,7 +232,7 @@ doSignedFloodFill(TreeOrLeafManagerT& tree, // Dummy (no-op) implementation for unsigned types template inline -typename std::enable_if::value, void>::type +typename std::enable_if_t::value, void> doSignedFloodFill(TreeOrLeafManagerT&, const typename TreeOrLeafManagerT::ValueType&, const typename TreeOrLeafManagerT::ValueType&, diff --git a/openvdb/openvdb/tools/VolumeAdvect.h b/openvdb/openvdb/tools/VolumeAdvect.h index aa7b856134..a242b1f2ab 100644 --- a/openvdb/openvdb/tools/VolumeAdvect.h +++ b/openvdb/openvdb/tools/VolumeAdvect.h @@ -365,6 +365,7 @@ struct VolumeAdvection::Advec using TreeT = typename VolumeGridT::TreeType; using AccT = typename VolumeGridT::ConstAccessor; using ValueT = typename TreeT::ValueType; + using ComputeT = typename TreeT::ComputeType; using LeafManagerT = typename tree::LeafManager; using LeafNodeT = typename LeafManagerT::LeafNodeType; using LeafRangeT = typename LeafManagerT::LeafRange; @@ -443,12 +444,13 @@ struct VolumeAdvection::Advec const ValueT* in0 = leaf->buffer().data(); for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) { const Index i = voxelIter.pos(); - out0[i] += RealT(0.5) * ( in0[i] - out1[i] ); + out0[i] += RealT(0.5) * ( ComputeT(in0[i]) - ComputeT(out1[i]) ); } } else { for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) { const Index i = voxelIter.pos(); - out0[i] += RealT(0.5) * ( acc.getValue(voxelIter.getCoord()) - out1[i] ); + out0[i] += RealT(0.5) * + (ComputeT(acc.getValue(voxelIter.getCoord())) - ComputeT(out1[i])); }//loop over active voxels } }//loop over leaf nodes @@ -467,12 +469,13 @@ struct VolumeAdvection::Advec const ValueT* in0 = leaf->buffer().data(); for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) { const Index i = voxelIter.pos(); - out0[i] = RealT(0.5)*( RealT(3)*in0[i] - out1[i] ); + out0[i] = RealT(0.5)*( RealT(3)*ComputeT(in0[i]) - ComputeT(out1[i]) ); }//loop over active voxels } else { for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) { const Index i = voxelIter.pos(); - out0[i] = RealT(0.5)*( RealT(3)*acc.getValue(voxelIter.getCoord()) - out1[i] ); + out0[i] = RealT(0.5)*( + RealT(3)*ComputeT(acc.getValue(voxelIter.getCoord())) - ComputeT(out1[i])); }//loop over active voxels } }//loop over leaf nodes @@ -498,7 +501,7 @@ struct VolumeAdvection::Advec if (mParent->interrupt()) return; const bool doLimiter = mParent->isLimiterOn(); const bool doClamp = mParent->mLimiter == Scheme::CLAMP; - ValueT data[2][2][2], vMin, vMax; + ComputeT data[2][2][2], vMin, vMax; const math::Transform& xform = mInGrid->transform(); AccT acc = mInGrid->getAccessor(); const ValueT backg = mInGrid->background(); @@ -516,14 +519,15 @@ struct VolumeAdvection::Advec BoxSampler::getValues(data, acc, ijk); BoxSampler::extrema(data, vMin, vMax); if ( doClamp ) { - value = math::Clamp( value, vMin, vMax); - } else if (value < vMin || value > vMax ) { + value = math::Clamp( ComputeT(value), vMin, vMax); + } else if (ComputeT(value) < vMin || ComputeT(value) > vMax ) { iPos -= Vec3R(ijk[0], ijk[1], ijk[2]);//unit coordinates value = BoxSampler::trilinearInterpolation( data, iPos ); } } - if (math::isApproxEqual(value, backg, math::Delta::value())) { + if (math::isApproxEqual(ComputeT(value), ComputeT(backg), + math::Delta::value())) { value = backg; leafIter->setValueOff( voxelIter.pos() ); } @@ -553,10 +557,12 @@ struct VolumeAdvection::Advec OPENVDB_INSTANTIATE_CLASS VolumeAdvection; OPENVDB_INSTANTIATE_CLASS VolumeAdvection; +OPENVDB_INSTANTIATE HalfGrid::Ptr VolumeAdvection::advect>(const HalfGrid&, double); OPENVDB_INSTANTIATE FloatGrid::Ptr VolumeAdvection::advect>(const FloatGrid&, double); OPENVDB_INSTANTIATE DoubleGrid::Ptr VolumeAdvection::advect>(const DoubleGrid&, double); OPENVDB_INSTANTIATE Vec3SGrid::Ptr VolumeAdvection::advect>(const Vec3SGrid&, double); +OPENVDB_INSTANTIATE HalfGrid::Ptr VolumeAdvection::advect>(const HalfGrid&, double); OPENVDB_INSTANTIATE FloatGrid::Ptr VolumeAdvection::advect>(const FloatGrid&, double); OPENVDB_INSTANTIATE DoubleGrid::Ptr VolumeAdvection::advect>(const DoubleGrid&, double); OPENVDB_INSTANTIATE Vec3SGrid::Ptr VolumeAdvection::advect>(const Vec3SGrid&, double); diff --git a/openvdb/openvdb/tools/VolumeToSpheres.h b/openvdb/openvdb/tools/VolumeToSpheres.h index b5d7b95181..a0466936c0 100644 --- a/openvdb/openvdb/tools/VolumeToSpheres.h +++ b/openvdb/openvdb/tools/VolumeToSpheres.h @@ -1004,6 +1004,7 @@ ClosestSurfacePoint::searchAndReplace(std::vector& points, #include #endif +OPENVDB_INSTANTIATE_CLASS ClosestSurfacePoint; OPENVDB_INSTANTIATE_CLASS ClosestSurfacePoint; OPENVDB_INSTANTIATE_CLASS ClosestSurfacePoint; diff --git a/openvdb/openvdb/tree/InternalNode.h b/openvdb/openvdb/tree/InternalNode.h index 534fc9553d..5dfb394db8 100644 --- a/openvdb/openvdb/tree/InternalNode.h +++ b/openvdb/openvdb/tree/InternalNode.h @@ -37,6 +37,7 @@ class InternalNode using ChildNodeType = _ChildNodeType; using LeafNodeType = typename ChildNodeType::LeafNodeType; using ValueType = typename ChildNodeType::ValueType; + using ComputeType = typename ChildNodeType::ComputeType; using BuildType = typename ChildNodeType::BuildType; using UnionType = NodeUnion; using NodeMaskType = util::NodeMask; diff --git a/openvdb/openvdb/tree/LeafManager.h b/openvdb/openvdb/tree/LeafManager.h index e8d427d025..0c456a98cd 100644 --- a/openvdb/openvdb/tree/LeafManager.h +++ b/openvdb/openvdb/tree/LeafManager.h @@ -87,6 +87,7 @@ class LeafManager public: using TreeType = TreeT; using ValueType = typename TreeT::ValueType; + using ComputeType = typename TreeT::ComputeType; using RootNodeType = typename TreeT::RootNodeType; using NonConstLeafType = typename TreeType::LeafNodeType; using LeafType = typename CopyConstness::Type; diff --git a/openvdb/openvdb/tree/LeafNode.h b/openvdb/openvdb/tree/LeafNode.h index c47bac7ed6..16775fa8b6 100644 --- a/openvdb/openvdb/tree/LeafNode.h +++ b/openvdb/openvdb/tree/LeafNode.h @@ -40,6 +40,7 @@ class LeafNode public: using BuildType = T; using ValueType = T; + using ComputeType = typename ValueToComputeMap::Type; using Buffer = LeafBuffer; using LeafNodeType = LeafNode; using NodeMaskType = util::NodeMask; diff --git a/openvdb/openvdb/tree/LeafNodeBool.h b/openvdb/openvdb/tree/LeafNodeBool.h index 15145ae874..e3dc41c5ed 100644 --- a/openvdb/openvdb/tree/LeafNodeBool.h +++ b/openvdb/openvdb/tree/LeafNodeBool.h @@ -32,6 +32,7 @@ class LeafNode using LeafNodeType = LeafNode; using BuildType = bool; using ValueType = bool; + using ComputeType = typename ValueToComputeMap::Type; using Buffer = LeafBuffer; using NodeMaskType = util::NodeMask; using Ptr = SharedPtr; diff --git a/openvdb/openvdb/tree/LeafNodeMask.h b/openvdb/openvdb/tree/LeafNodeMask.h index b861685f5b..f428f21591 100644 --- a/openvdb/openvdb/tree/LeafNodeMask.h +++ b/openvdb/openvdb/tree/LeafNodeMask.h @@ -34,6 +34,7 @@ class LeafNode using LeafNodeType = LeafNode; using BuildType = ValueMask;// this is a rare case where using ValueType = bool;// value type != build type + using ComputeType = typename ValueToComputeMap::Type; using Buffer = LeafBuffer;// buffer uses the bool specialization using NodeMaskType = util::NodeMask; using Ptr = SharedPtr; diff --git a/openvdb/openvdb/tree/RootNode.h b/openvdb/openvdb/tree/RootNode.h index 8bbf2ee618..e97f52898d 100644 --- a/openvdb/openvdb/tree/RootNode.h +++ b/openvdb/openvdb/tree/RootNode.h @@ -42,6 +42,7 @@ class RootNode using ChildNodeType = ChildType; using LeafNodeType = typename ChildType::LeafNodeType; using ValueType = typename ChildType::ValueType; + using ComputeType = typename ChildType::ComputeType; using BuildType = typename ChildType::BuildType; static const Index LEVEL = 1 + ChildType::LEVEL; // level 0 = leaf diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index 9db13edcc2..c2c6ffa9f0 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -199,6 +199,7 @@ class Tree: public TreeBase using RootNodeType = _RootNodeType; using ValueType = typename RootNodeType::ValueType; + using ComputeType = typename RootNodeType::ComputeType; using BuildType = typename RootNodeType::BuildType; using LeafNodeType = typename RootNodeType::LeafNodeType; diff --git a/openvdb/openvdb/tree/ValueAccessor.h b/openvdb/openvdb/tree/ValueAccessor.h index 542ff0d1b3..8c3cdfd405 100644 --- a/openvdb/openvdb/tree/ValueAccessor.h +++ b/openvdb/openvdb/tree/ValueAccessor.h @@ -374,6 +374,7 @@ class ValueAccessorImpl final : using TreeType = _TreeType; using ValueType = typename TreeType::ValueType; + using ComputeType = typename TreeType::ComputeType; using RootNodeT = typename TreeType::RootNodeType; using LeafNodeT = typename TreeType::LeafNodeType; using NodeChainT = typename RootNodeT::NodeChainType; From e3a5881d17771c12a0be05ff2c55b22ee9fdc69e Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Tue, 16 Apr 2024 10:49:30 -0400 Subject: [PATCH 94/98] Update openvdb.h Remove HalfGrid from RealGridTypes until a consensus is reached. Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/openvdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvdb/openvdb/openvdb.h b/openvdb/openvdb/openvdb.h index ee6d885091..eec6aba555 100644 --- a/openvdb/openvdb/openvdb.h +++ b/openvdb/openvdb/openvdb.h @@ -90,7 +90,7 @@ using VectorGrid = Vec3fGrid; /// @name Lists of native Grid Types /// @{ /// The floating point Grid types which OpenVDB will register by default. -using RealGridTypes = TypeList; +using RealGridTypes = TypeList; /// The integer Grid types which OpenVDB will register by default. using IntegerGridTypes = TypeList; /// The scalar Grid types which OpenVDB will register by default. This is a From 2b0fc40b17f7a39267987a2bc72ef0c9a7d176bf Mon Sep 17 00:00:00 2001 From: ghurstunither <62885595+ghurstunither@users.noreply.github.com> Date: Tue, 16 Apr 2024 10:58:14 -0400 Subject: [PATCH 95/98] trailing spaces Fixes trailingspaces errors Signed-off-by: ghurstunither <62885595+ghurstunither@users.noreply.github.com> --- openvdb/openvdb/tools/LevelSetFilter.h | 2 +- openvdb/openvdb/tools/RayTracer.h | 8 ++++---- openvdb/openvdb/tools/VolumeAdvect.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openvdb/openvdb/tools/LevelSetFilter.h b/openvdb/openvdb/tools/LevelSetFilter.h index c197c0c590..2d3c435e7c 100644 --- a/openvdb/openvdb/tools/LevelSetFilter.h +++ b/openvdb/openvdb/tools/LevelSetFilter.h @@ -516,7 +516,7 @@ LevelSetFilter::Filter::offsetImpl( mParent->maxMask(), mParent->isMaskInverted()); for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) { - if (alpha(iter.getCoord(), a, b)) + if (alpha(iter.getCoord(), a, b)) iter.setValue(ComputeType(*iter) + a*offset); } } diff --git a/openvdb/openvdb/tools/RayTracer.h b/openvdb/openvdb/tools/RayTracer.h index 5896f9664c..486e626f3a 100644 --- a/openvdb/openvdb/tools/RayTracer.h +++ b/openvdb/openvdb/tools/RayTracer.h @@ -550,7 +550,7 @@ class MatteShader: public BaseShader Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override { using RealT = Film::RGBA::ValueT; - + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); return Film::RGBA(RealT(v[0]), RealT(v[1]), RealT(v[2])); @@ -599,7 +599,7 @@ class NormalShader: public BaseShader Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R&) const override { using RealT = Film::RGBA::ValueT; - + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); return Film::RGBA(RealT(v[0])*(normal[0]+1.0), @@ -656,7 +656,7 @@ class PositionShader: public BaseShader Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override { using RealT = Film::RGBA::ValueT; - + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); const Vec3R rgb = (xyz - mMin) * mInvDim; @@ -713,7 +713,7 @@ class DiffuseShader: public BaseShader Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R& rayDir) const override { using RealT = Film::RGBA::ValueT; - + typename GridT::ValueType v = zeroVal(); SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v); // We take the abs of the dot product corresponding to having diff --git a/openvdb/openvdb/tools/VolumeAdvect.h b/openvdb/openvdb/tools/VolumeAdvect.h index a242b1f2ab..f32c2d1433 100644 --- a/openvdb/openvdb/tools/VolumeAdvect.h +++ b/openvdb/openvdb/tools/VolumeAdvect.h @@ -474,7 +474,7 @@ struct VolumeAdvection::Advec } else { for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) { const Index i = voxelIter.pos(); - out0[i] = RealT(0.5)*( + out0[i] = RealT(0.5)*( RealT(3)*ComputeT(acc.getValue(voxelIter.getCoord())) - ComputeT(out1[i])); }//loop over active voxels } From f947b12494bdababe26525b75e89089b2a21ff0c Mon Sep 17 00:00:00 2001 From: apradhana Date: Tue, 4 Feb 2025 16:24:32 -0800 Subject: [PATCH 96/98] Rever LevelSetFilter.h to fix compilation by getting rid of HalfGrid support in LevelSetFilter. Signed-off-by: apradhana --- openvdb/openvdb/tools/LevelSetFilter.h | 54 ++++++++++++-------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/openvdb/openvdb/tools/LevelSetFilter.h b/openvdb/openvdb/tools/LevelSetFilter.h index 2d3c435e7c..bc1a425815 100644 --- a/openvdb/openvdb/tools/LevelSetFilter.h +++ b/openvdb/openvdb/tools/LevelSetFilter.h @@ -44,8 +44,7 @@ class LevelSetFilter : public LevelSetTracker using MaskType = MaskT; using TreeType = typename GridType::TreeType; using ValueType = typename TreeType::ValueType; - using ComputeType = typename TreeType::ComputeType; - using AlphaType = typename MaskType::ComputeType; + using AlphaType = typename MaskType::ValueType; static_assert(std::is_floating_point::value, "LevelSetFilter requires a mask grid with floating-point values"); @@ -134,7 +133,7 @@ class LevelSetFilter : public LevelSetTracker /// @brief Offset the level set by the specified (world) distance. /// @param offset Value of the offset. /// @param mask Optional alpha mask. - void offset(ComputeType offset, const MaskType* mask = nullptr) + void offset(ValueType offset, const MaskType* mask = nullptr) { Filter f(this, mask); f.offset(offset); } @@ -207,17 +206,17 @@ class LevelSetFilter : public LevelSetTracker template struct Avg { Avg(const GridT& grid, Int32 w) : - acc(grid.tree()), width(w), frac(1/ComputeType(2*w+1)) {} - inline ComputeType operator()(Coord xyz) + acc(grid.tree()), width(w), frac(1/ValueType(2*w+1)) {} + inline ValueType operator()(Coord xyz) { - ComputeType sum = zeroVal(); + ValueType sum = zeroVal(); Int32& i = xyz[Axis], j = i + width; - for (i -= width; i <= j; ++i) sum += ComputeType(acc.getValue(xyz)); + for (i -= width; i <= j; ++i) sum += acc.getValue(xyz); return sum*frac; } typename GridT::ConstAccessor acc; const Int32 width; - const ComputeType frac; + const ValueType frac; }; template @@ -231,7 +230,7 @@ class LevelSetFilter : public LevelSetTracker void meanCurvatureImpl(const LeafRange&); void filletImpl(const LeafRange&); void laplacianImpl(const LeafRange&); - void offsetImpl(const LeafRange&, ComputeType); + void offsetImpl(const LeafRange&, ValueType); LevelSetFilter* mParent; const MaskType* mMask; @@ -355,17 +354,16 @@ LevelSetFilter::Filter::laplacian() template inline void -LevelSetFilter::Filter::offset(ComputeType value) +LevelSetFilter::Filter::offset(ValueType value) { mParent->startInterrupter("Offsetting level set"); mParent->leafs().removeAuxBuffers();// no auxiliary buffers required - const ComputeType CFL = ComputeType(0.5) * mParent->voxelSize(), - offset = openvdb::math::Abs(value); - ComputeType dist = 0.0; - while (offset-dist > ComputeType(0.001)*CFL && mParent->checkInterrupter()) { - const ComputeType delta = openvdb::math::Min(offset-dist, CFL); + const ValueType CFL = ValueType(0.5) * mParent->voxelSize(), offset = openvdb::math::Abs(value); + ValueType dist = 0.0; + while (offset-dist > ValueType(0.001)*CFL && mParent->checkInterrupter()) { + const ValueType delta = openvdb::math::Min(offset-dist, CFL); dist += delta; mTask = std::bind(&Filter::offsetImpl, @@ -388,7 +386,7 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa { mParent->checkInterrupter(); //const float CFL = 0.9f, dt = CFL * mDx * mDx / 6.0f; - const ComputeType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ComputeType(3.0); + const ValueType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ValueType(3.0); math::CurvatureStencil stencil(mParent->grid(), dx); if (mMask) { typename AlphaMaskT::FloatType a, b; @@ -399,8 +397,7 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - const ComputeType phi0 = ComputeType(*iter), - phi1 = phi0 + dt*stencil.meanCurvatureNormGrad(); + const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.meanCurvatureNormGrad(); buffer[iter.pos()] = b * phi0 + a * phi1; } } @@ -410,7 +407,7 @@ LevelSetFilter::Filter::meanCurvatureImpl(const LeafRa ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { stencil.moveTo(iter); - buffer[iter.pos()] = ComputeType(*iter) + dt*stencil.meanCurvatureNormGrad(); + buffer[iter.pos()] = *iter + dt*stencil.meanCurvatureNormGrad(); } } } @@ -475,7 +472,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& { mParent->checkInterrupter(); //const float CFL = 0.9f, half_dt = CFL * mDx * mDx / 12.0f; - const ComputeType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ComputeType(6.0); + const ValueType dx = mParent->voxelSize(), dt = math::Pow2(dx) / ValueType(6.0); math::GradStencil stencil(mParent->grid(), dx); if (mMask) { typename AlphaMaskT::FloatType a, b; @@ -486,8 +483,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - const ComputeType phi0 = ComputeType(*iter), - phi1 = phi0 + dt*stencil.laplacian(); + const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.laplacian(); buffer[iter.pos()] = b * phi0 + a * phi1; } } @@ -497,7 +493,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { stencil.moveTo(iter); - buffer[iter.pos()] = ComputeType(*iter) + dt*stencil.laplacian(); + buffer[iter.pos()] = *iter + dt*stencil.laplacian(); } } } @@ -507,7 +503,7 @@ LevelSetFilter::Filter::laplacianImpl(const LeafRange& template inline void LevelSetFilter::Filter::offsetImpl( - const LeafRange& range, ComputeType offset) + const LeafRange& range, ValueType offset) { mParent->checkInterrupter(); if (mMask) { @@ -516,14 +512,13 @@ LevelSetFilter::Filter::offsetImpl( mParent->maxMask(), mParent->isMaskInverted()); for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) { - if (alpha(iter.getCoord(), a, b)) - iter.setValue(ComputeType(*iter) + a*offset); + if (alpha(iter.getCoord(), a, b)) iter.setValue(*iter + a*offset); } } } else { for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) { for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) { - iter.setValue(ComputeType(*iter) + offset); + iter.setValue(*iter + offset); } } } @@ -545,7 +540,7 @@ LevelSetFilter::Filter::medianImpl(const LeafRange& ra for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { if (alpha(iter.getCoord(), a, b)) { stencil.moveTo(iter); - buffer[iter.pos()] = b * ComputeType(*iter) + a * stencil.median(); + buffer[iter.pos()] = b * (*iter) + a * stencil.median(); } } } @@ -576,7 +571,7 @@ LevelSetFilter::Filter::boxImpl(const LeafRange& range ValueType* buffer = leafIter.buffer(1).data(); for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) { const Coord xyz = iter.getCoord(); - if (alpha(xyz, a, b)) buffer[iter.pos()] = b * ComputeType(*iter)+ a * avg(xyz); + if (alpha(xyz, a, b)) buffer[iter.pos()] = b * (*iter)+ a * avg(xyz); } } } else { @@ -601,7 +596,6 @@ LevelSetFilter::Filter::boxImpl(const LeafRange& range #include #endif -OPENVDB_INSTANTIATE_CLASS LevelSetFilter; OPENVDB_INSTANTIATE_CLASS LevelSetFilter; OPENVDB_INSTANTIATE_CLASS LevelSetFilter; From 5ae5f8cfa2ea5a1fd894b878b2a5f3feee81569b Mon Sep 17 00:00:00 2001 From: apradhana Date: Tue, 4 Feb 2025 17:37:29 -0800 Subject: [PATCH 97/98] Bug fix: TestGrid.cc compiles based on the current half grid specs. Signed-off-by: apradhana --- openvdb/openvdb/unittest/TestGrid.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/openvdb/openvdb/unittest/TestGrid.cc b/openvdb/openvdb/unittest/TestGrid.cc index 27c76ec0f6..f96ff63ea2 100644 --- a/openvdb/openvdb/unittest/TestGrid.cc +++ b/openvdb/openvdb/unittest/TestGrid.cc @@ -29,6 +29,7 @@ class ProxyTree: public openvdb::TreeBase public: using ValueType = int; using BuildType = int; + using ComputeType = int; using LeafNodeType = void; using ValueAllCIter = void; using ValueAllIter = void; From eb88c8436b4619704cfd6ce0a434232aeb831dde Mon Sep 17 00:00:00 2001 From: apradhana Date: Tue, 4 Feb 2025 21:40:26 -0800 Subject: [PATCH 98/98] Bug fix: address implicit conversion. Signed-off-by: apradhana --- openvdb/openvdb/math/Math.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvdb/openvdb/math/Math.h b/openvdb/openvdb/math/Math.h index 7bc29a3e33..578ebc2c3b 100644 --- a/openvdb/openvdb/math/Math.h +++ b/openvdb/openvdb/math/Math.h @@ -147,7 +147,7 @@ template<> inline std::string negative(const std::string& val) { return val; } //@{ /// Tolerance for floating-point comparison template struct Tolerance { static T value() { return zeroVal(); } }; -template<> struct Tolerance { static math::half value() { return 0.00097656; } }; +template<> struct Tolerance { static math::half value() { return static_cast(0.00097656f); } }; template<> struct Tolerance { static float value() { return 1e-8f; } }; template<> struct Tolerance { static double value() { return 1e-15; } }; //@} @@ -155,7 +155,7 @@ template<> struct Tolerance { static double value() { return 1e-15; //@{ /// Delta for small floating-point offsets template struct Delta { static T value() { return zeroVal(); } }; -template<> struct Delta { static math::half value() { return 0.00390625; } }; +template<> struct Delta { static math::half value() { return static_cast(0.00390625f); } }; template<> struct Delta { static float value() { return 1e-5f; } }; template<> struct Delta { static double value() { return 1e-9; } }; //@}