| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright Contributors to the OpenVDB Project | ||
| 2 | // SPDX-License-Identifier: MPL-2.0 | ||
| 3 | |||
| 4 | /// @author Dan Bailey, Rick Hankins | ||
| 5 | /// | ||
| 6 | /// @file PointRasterizeFrustum.h | ||
| 7 | /// | ||
| 8 | /// @brief Volume rasterization of VDB Points using velocity and camera motion-blur | ||
| 9 | |||
| 10 | #ifndef OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_HAS_BEEN_INCLUDED | ||
| 11 | #define OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_HAS_BEEN_INCLUDED | ||
| 12 | |||
| 13 | #include <openvdb/math/Ray.h> | ||
| 14 | #include <openvdb/math/DDA.h> | ||
| 15 | #include <openvdb/util/NullInterrupter.h> | ||
| 16 | #include <openvdb/thread/Threading.h> | ||
| 17 | #include <openvdb/tools/GridTransformer.h> // for tools::resampleToMatch() | ||
| 18 | #include <openvdb/tools/Interpolation.h> | ||
| 19 | #include <openvdb/points/PointCount.h> | ||
| 20 | #include <openvdb/points/PointDataGrid.h> | ||
| 21 | |||
| 22 | namespace openvdb { | ||
| 23 | OPENVDB_USE_VERSION_NAMESPACE | ||
| 24 | namespace OPENVDB_VERSION_NAME { | ||
| 25 | namespace points { | ||
| 26 | |||
| 27 | |||
| 28 | /// @brief How to composite points into a volume. | ||
| 29 | enum class RasterMode | ||
| 30 | { | ||
| 31 | ACCUMULATE = 0, | ||
| 32 | MAXIMUM, | ||
| 33 | AVERAGE | ||
| 34 | }; | ||
| 35 | |||
| 36 | |||
| 37 | /// @brief A camera class that provides an interface for camera motion blur when rasterizing | ||
| 38 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | class RasterCamera |
| 39 | { | ||
| 40 | public: | ||
| 41 | explicit RasterCamera(const math::Transform& transform); | ||
| 42 | |||
| 43 | bool isStatic() const; | ||
| 44 | |||
| 45 | void clear(); | ||
| 46 | void appendTransform(const math::Transform&, float weight = 1.0f); | ||
| 47 | |||
| 48 | size_t size() const; | ||
| 49 | |||
| 50 | void simplify(); | ||
| 51 | |||
| 52 | bool hasWeight(Index i) const; | ||
| 53 | float weight(Index i) const; | ||
| 54 | |||
| 55 | const math::Transform& transform(Index i) const; | ||
| 56 | const math::Transform& firstTransform() const; | ||
| 57 | const math::Transform& lastTransform() const; | ||
| 58 | |||
| 59 | void setShutter(float start, float end); | ||
| 60 | float shutterStart() const; | ||
| 61 | float shutterEnd() const; | ||
| 62 | |||
| 63 | private: | ||
| 64 | std::deque<math::Transform> mTransforms; | ||
| 65 | std::deque<float> mWeights; | ||
| 66 | // default to 180 degree film shutter | ||
| 67 | float mShutterStart = -0.25f, | ||
| 68 | mShutterEnd = 0.25f; | ||
| 69 | }; // class RasterCamera | ||
| 70 | |||
| 71 | |||
| 72 | /// @brief A group of shared settings to be used in the Volume Rasterizer | ||
| 73 | /// @param scaleByVoxelVolume scale particle contributions by the volume of the receiving voxel | ||
| 74 | /// @param velocityAttribute the name of the velocity attribute | ||
| 75 | /// @param velocityMotionBlur bake the point velocities into the volume | ||
| 76 | /// @param clipToFrustum if enabled and the transform is a frustum transform, eliminate | ||
| 77 | /// points whose position does not lie within the frustum | ||
| 78 | /// @param clipBBox an optional world-space bounding box to clip the points | ||
| 79 | /// during rasterization | ||
| 80 | /// @param clipMask an optional mask, each point samples the mask using a | ||
| 81 | /// nearest-neighbor sampling and is only rasterized if active | ||
| 82 | /// @param invertMask if mask is provided, only rasterize if sample is inactive | ||
| 83 | /// @param framesPerSecond the global value for frames / second for computing motion blur | ||
| 84 | /// @param threaded if enabled, use threading to accelerate rasterization | ||
| 85 | /// @note rasterization can clip can using any combination of bounding box, mask and frustum | ||
| 86 | struct FrustumRasterizerSettings | ||
| 87 | { | ||
| 88 | FrustumRasterizerSettings() = delete; | ||
| 89 | |||
| 90 | 37 | explicit FrustumRasterizerSettings(const math::Transform& _transform) | |
| 91 |
1/2✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
|
37 | : transform(new math::Transform(_transform)) |
| 92 |
3/6✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
|
37 | , camera(_transform) { } |
| 93 | |||
| 94 | math::Transform::Ptr transform; | ||
| 95 | RasterCamera camera; | ||
| 96 | bool scaleByVoxelVolume = false, | ||
| 97 | useRadius = false, | ||
| 98 | accurateFrustumRadius = false, | ||
| 99 | accurateSphereMotionBlur = false, | ||
| 100 | velocityMotionBlur = false, | ||
| 101 | threaded = true; | ||
| 102 | float threshold = 1e-6f, | ||
| 103 | radiusScale = 1.0f, | ||
| 104 | framesPerSecond = 24.0f; | ||
| 105 | Name velocityAttribute = "v", | ||
| 106 | radiusAttribute = "pscale"; | ||
| 107 | int motionSamples = 2; | ||
| 108 | }; // struct FrustumRasterizerSettings | ||
| 109 | |||
| 110 | |||
| 111 |
4/6✓ Branch 1 taken 4 times.
✓ Branch 2 taken 48 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
|
67 | struct FrustumRasterizerMask |
| 112 | { | ||
| 113 | using AccessorT = const tree::ValueAccessor<const MaskTree>; | ||
| 114 | |||
| 115 |
36/72✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✗ Branch 59 not taken.
✓ Branch 60 taken 1 times.
✓ Branch 63 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✓ Branch 75 taken 1 times.
✗ Branch 76 not taken.
✓ Branch 79 taken 1 times.
✗ Branch 80 not taken.
✓ Branch 83 taken 1 times.
✗ Branch 84 not taken.
✓ Branch 87 taken 1 times.
✗ Branch 88 not taken.
✓ Branch 91 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 95 taken 1 times.
✗ Branch 96 not taken.
✓ Branch 99 taken 1 times.
✗ Branch 100 not taken.
✓ Branch 103 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 107 taken 1 times.
✗ Branch 108 not taken.
✓ Branch 111 taken 1 times.
✗ Branch 112 not taken.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 119 taken 1 times.
✗ Branch 120 not taken.
✓ Branch 123 taken 1 times.
✗ Branch 124 not taken.
✓ Branch 127 taken 1 times.
✗ Branch 128 not taken.
✓ Branch 131 taken 1 times.
✗ Branch 132 not taken.
✓ Branch 135 taken 1 times.
✗ Branch 136 not taken.
✓ Branch 139 taken 1 times.
✗ Branch 140 not taken.
✓ Branch 143 taken 1 times.
✗ Branch 144 not taken.
|
36 | FrustumRasterizerMask() = default; |
| 116 | |||
| 117 | explicit FrustumRasterizerMask( | ||
| 118 | const math::Transform& transform, | ||
| 119 | const MaskGrid* mask = nullptr, | ||
| 120 | const BBoxd& bbox = BBoxd(), | ||
| 121 | const bool clipToFrustum = true, | ||
| 122 | const bool invert = false); | ||
| 123 | |||
| 124 | operator bool() const; | ||
| 125 | |||
| 126 | MaskTree::ConstPtr getTreePtr() const; | ||
| 127 | |||
| 128 | bool valid(const Coord& ijk, AccessorT* acc) const; | ||
| 129 | |||
| 130 | const CoordBBox& clipBBox() const; | ||
| 131 | |||
| 132 | private: | ||
| 133 | MaskGrid::Ptr mMask; | ||
| 134 | CoordBBox mClipBBox; | ||
| 135 | bool mInvert = false; | ||
| 136 | }; // struct FrustumRasterizerMask | ||
| 137 | |||
| 138 | |||
| 139 | namespace point_rasterize_internal { | ||
| 140 | |||
| 141 | template <typename PointDataGridT> | ||
| 142 | class GridToRasterize; | ||
| 143 | |||
| 144 | } // namespace point_rasterize_internal | ||
| 145 | |||
| 146 | |||
| 147 | /// @brief Efficient rasterization of one or more VDB Points grids into a linear | ||
| 148 | /// or frustum volume with the option to bake in camera or geometry motion blur. | ||
| 149 | /// | ||
| 150 | /// @details The camera transform can be provided using a RasterCamera object to | ||
| 151 | /// offer linear camera motion blur and geometry motion blur is computed from reading | ||
| 152 | /// a velocity attribute on the points. Sub-sampled camera motion blur is planned. | ||
| 153 | /// | ||
| 154 | /// @note For maximum memory efficiency, the data can optionally be streamed from | ||
| 155 | /// disk where the input VDB point grids are collapsed as they are read. | ||
| 156 | /// | ||
| 157 | /// @note The total contribution for each point is spread across all the voxels being | ||
| 158 | /// rasterized into and weighted by the total volume represented by each voxel. In an | ||
| 159 | /// example use case where a point is moving away from a camera that is used to | ||
| 160 | /// generate a frustum volume being rasterized into, each successive voxel is larger in | ||
| 161 | /// size. | ||
| 162 | template<typename PointDataGridT> | ||
| 163 | class FrustumRasterizer | ||
| 164 | { | ||
| 165 | public: | ||
| 166 | using GridPtr = typename PointDataGridT::Ptr; | ||
| 167 | using GridConstPtr = typename PointDataGridT::ConstPtr; | ||
| 168 | using GridToRasterize = point_rasterize_internal::GridToRasterize<PointDataGridT>; | ||
| 169 | |||
| 170 | /// @brief main constructor | ||
| 171 | /// @param settings the shared settings for rasterizing, see class for more details | ||
| 172 | /// @param interrupt a pointer adhering to the util::NullInterrupter interface | ||
| 173 | explicit FrustumRasterizer( | ||
| 174 | const FrustumRasterizerSettings& settings, | ||
| 175 | const FrustumRasterizerMask& mask = FrustumRasterizerMask(), | ||
| 176 | util::NullInterrupter* interrupt = nullptr); | ||
| 177 | |||
| 178 | /// @brief Append a PointDataGrid to the rasterizer (but don't rasterize yet). | ||
| 179 | /// @param points the PointDataGrid | ||
| 180 | void addPoints(GridConstPtr& points); | ||
| 181 | |||
| 182 | /// @brief Append a PointDataGrid to the rasterizer (but don't rasterize yet). | ||
| 183 | /// @param points the non-const PointDataGrid | ||
| 184 | /// @param stream if true, will destructively collapse attributes while | ||
| 185 | /// accessing so as to minimize the memory footprint. | ||
| 186 | void addPoints(GridPtr& points, bool stream = false); | ||
| 187 | |||
| 188 | /// @brief Clear all PointDataGrids in the rasterizer. | ||
| 189 | void clear(); | ||
| 190 | |||
| 191 | /// @brief Return number of PointDataGrids in the rasterizer. | ||
| 192 | size_t size() const; | ||
| 193 | |||
| 194 | /// @brief Return memory usage of the rasterizer. | ||
| 195 | size_t memUsage() const; | ||
| 196 | |||
| 197 | template <typename FilterT = points::NullFilter> | ||
| 198 | FloatGrid::Ptr | ||
| 199 | rasterizeUniformDensity(RasterMode mode=RasterMode::MAXIMUM, | ||
| 200 | bool reduceMemory = false, float scale = 1.0f, const FilterT& filter = FilterT()); | ||
| 201 | |||
| 202 | template <typename FilterT = points::NullFilter> | ||
| 203 | FloatGrid::Ptr | ||
| 204 | rasterizeDensity(const openvdb::Name& attribute, RasterMode mode=RasterMode::MAXIMUM, | ||
| 205 | bool reduceMemory = false, float scale = 1.0f, const FilterT& filter = FilterT()); | ||
| 206 | |||
| 207 | template <typename FilterT = points::NullFilter> | ||
| 208 | GridBase::Ptr | ||
| 209 | rasterizeAttribute(const Name& attribute, RasterMode mode=RasterMode::ACCUMULATE, | ||
| 210 | bool reduceMemory = false, float scale = 1.0f, const FilterT& filter = FilterT()); | ||
| 211 | |||
| 212 | template <typename GridT, typename AttributeT, typename FilterT = points::NullFilter> | ||
| 213 | typename GridT::Ptr | ||
| 214 | rasterizeAttribute(const Name& attribute, RasterMode mode=RasterMode::ACCUMULATE, | ||
| 215 | bool reduceMemory = false, float scale = 1.0f, const FilterT& filter = FilterT()); | ||
| 216 | |||
| 217 | template <typename GridT, typename FilterT = points::NullFilter> | ||
| 218 | typename GridT::Ptr | ||
| 219 | rasterizeMask(bool reduceMemory = false, const FilterT& filter = FilterT()); | ||
| 220 | |||
| 221 | private: | ||
| 222 | template <typename AttributeT, typename GridT, typename FilterT> | ||
| 223 | void | ||
| 224 | performRasterization( | ||
| 225 | GridT& grid, RasterMode mode, const openvdb::Name& attribute, | ||
| 226 | bool reduceMemory, float scale, const FilterT& filter); | ||
| 227 | |||
| 228 | private: | ||
| 229 | FrustumRasterizerSettings mSettings; | ||
| 230 | FrustumRasterizerMask mMask; | ||
| 231 | |||
| 232 | util::NullInterrupter* mInterrupter; | ||
| 233 | std::vector<GridToRasterize> mPointGrids; | ||
| 234 | }; // class FrustumRasterizer | ||
| 235 | |||
| 236 | |||
| 237 | /// @brief A struct that stores all include/exclude attribute names as strings | ||
| 238 | /// and is internally converted into the resolved MultiGroupFilter | ||
| 239 | 1 | struct RasterGroups | |
| 240 | { | ||
| 241 | std::vector<Name> includeNames; | ||
| 242 | std::vector<Name> excludeNames; | ||
| 243 | }; // class RasterGroups | ||
| 244 | |||
| 245 | |||
| 246 | } // namespace points | ||
| 247 | } // namespace OPENVDB_VERSION_NAME | ||
| 248 | } // namespace openvdb | ||
| 249 | |||
| 250 | #include "impl/PointRasterizeFrustumImpl.h" | ||
| 251 | |||
| 252 | #endif // OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_HAS_BEEN_INCLUDED | ||
| 253 |