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 |