OpenVDB: openvdb/points/PointRasterizeSDF.h Source File

OpenVDB 12.1.1

Loading...
Searching...
No Matches
PointRasterizeSDF.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3//
4/// @author Nick Avramoussis
5///
6/// @file PointRasterizeSDF.h
7///
8/// @brief Various transfer schemes for rasterizing point positions and radius
9/// data to signed distance fields with optional closest point attribute
10/// transfers. All methods support arbitrary target linear transformations,
11/// fixed or varying point radius, filtering of point data and arbitrary types
12/// for attribute transferring.
13///
14/// @details There are currently three main transfer implementations:
15///
16/// - Rasterize Spheres
17///
18/// Performs trivial narrow band stamping of spheres for each point. This
19/// is an extremely fast and efficient way to produce both a valid
20/// symmetrical narrow band level set and transfer attributes using closest
21/// point lookups.
22///
23/// - Rasterize Smooth Spheres
24///
25/// Calculates an averaged position of influence per voxel as described in:
26/// [Animating Sand as a Fluid - Zhu Bridson 2005].
27///
28/// This technique produces smoother, more blended connections between
29/// points which is ideal for generating a more artistically pleasant
30/// surface directly from point distributions. It aims to avoid typical
31/// post filtering operations used to smooth surface volumes. Note however
32/// that this method can be prone to temporal instabilities (that is, given
33/// a sequence of frames, consecutive frames may not generate surfaces that
34/// transition as smoothly) due to changes in point distributions resulting
35/// in more abrupt surface changes. It may also not necessarily produce a
36/// *symmetrical* narrow band level set; the exterior band may be smaller
37/// than desired depending on the search radius - the surface can be rebuilt
38/// or resized if necessary. The same closet point algorithm is used to
39/// transfer attributes.
40///
41/// - Rasterize Ellipsoids.
42///
43/// Rasterizes anisotropic ellipses for each point by analyzing point
44/// neighborhood distributions, as described in:
45/// [Reconstructing Surfaces of Particle-Based Fluids Using Anisotropic
46/// Kernel - Yu Turk 2010].
47///
48/// This method uses the rotation and affine matrix attributes built from
49/// the points::pca() method which model these elliptical distributions
50/// using principal component analysis. The ellipses create a much tighter,
51/// more fitted surface that better represents the convex hull of the point
52/// set. This technique also allows point to smoothly blend from their
53/// computed ellipse back to a canonical sphere, as well as allowing
54/// isolated points to be rasterized with their own radius scale. Although
55/// the rasterization step of this pipeline is relatively fast, it is still
56/// the slowest of all three methods and depends on the somewhat expensive
57/// points::pca() method. Still, this technique can be far superior at
58/// producing fluid surfaces where thin sheets (waterfalls) or sharp edges
59/// (wave breaks) are desirable.
60///
61///
62/// In general, it is recommended to consider post rebuilding/renormalizing
63/// the generated surface using either tools::levelSetRebuild() or
64/// tools::LevelSetTracker::normalize() tools::LevelSetTracker::resize().
65///
66/// @note These methods use the framework provided in PointTransfer.h
67
68#ifndef OPENVDB_POINTS_RASTERIZE_SDF_HAS_BEEN_INCLUDED
69#define OPENVDB_POINTS_RASTERIZE_SDF_HAS_BEEN_INCLUDED
70
71#include "PointDataGrid.h"
72#include "PointTransfer.h"
73#include "PointStatistics.h"
74
75#include <openvdb/openvdb.h>
76#include <openvdb/Types.h>
77#include <openvdb/tools/Prune.h>
78#include <openvdb/tools/ValueTransformer.h>
79#include <openvdb/thread/Threading.h>
80#include <openvdb/util/NullInterrupter.h>
81#include <openvdb/util/Assert.h>
82
83#include <unordered_map>
84
85#include <tbb/task_group.h>
86#include <tbb/parallel_reduce.h>
87
88namespace openvdb {
89 OPENVDB_USE_VERSION_NAMESPACE
90namespace OPENVDB_VERSION_NAME {
91namespace points {
92
93/// @brief Perform point rasterzation to produce a signed distance field.
94/// @param point the point data grid to rasterize
95/// @param settings one of the available transfer setting schemes found below
96/// in this file.
97/// @return A vector of grids. The signed distance field is guaranteed to be
98/// first and at the type specified by SdfT. Successive grids are the closest
99/// point attribute grids. These grids are guaranteed to have a topology
100/// and transform equal to the surface.
101///
102/// @code
103/// points::PointDataGrid g = ...;
104///
105/// // default settings for sphere stamping with a world space radius of 1
106/// SphereSettings<> spheres;
107/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, spheres)[0]);
108///
109/// // custom linear transform of target sdf, world space radius of 5
110/// spheres.transform = math::Transform::createLinearTransform(0.3);
111/// spheres.radiusScale = 5;
112/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, spheres)[0]);
113///
114/// // smooth sphere rasterization with variable double precision radius
115/// // attribute "pscale" scaled by 2
116/// SmoothSphereSettings<TypeList<>, double> smooth;
117/// smooth.radius = "pscale";
118/// smooth.radiusScale = 2;
119/// smooth.searchRadius = 3;
120/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, smooth)[0]);
121///
122/// // anisotropic/ellipsoid rasterization with attribute transferring.
123/// // requires pca attributes to be initialized using points::pca() first
124/// PcaSettings settings;
125/// PcaAttributes attribs;
126/// points::pca(g, settings, attribs);
127///
128/// EllipsoidSettings<TypeList<int32_t, Vec3f>> ellips;
129/// s.pca = attribs;
130/// s.attributes.emplace_back("id");
131/// s.attributes.emplace_back("v");
132/// GridPtrVec grids = points::rasterizeSdf(g, s);
133/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(grids[0]);
134/// Int32Grid::Ptr id = StaticPtrCast<Int32Grid>(grids[1]);
135/// Vec3fGrid::Ptr vel = StaticPtrCast<Vec3fGrid>(grids[2]);
136/// @endcode
137template <typename PointDataGridT,
138 typename SdfT = typename PointDataGridT::template ValueConverter<float>::Type,
139 typename SettingsT>
140 GridPtrVec
141 rasterizeSdf(const PointDataGridT& points, const SettingsT& settings);
142
143//
144
145/// @brief Generic settings for narrow band spherical stamping with a uniform
146/// or varying radius and optionally with closest point attribute transfer of
147/// arbitrary attributes. See the struct member documentation for detailed
148/// behavior.
149/// @note There exists other more complex kernels that derive from this struct,
150/// but on its own it represents the settings needed to perform basic narrow
151/// band sphere stamping. Parameters are interpreted in the same way across
152/// derived classes.
153template <typename AttributeTs = TypeList<>,
154 typename RadiusAttributeT = float,
155 typename FilterT = NullFilter>
156 struct SphereSettings
157{
158 using AttributeTypes = AttributeTs;
159 using RadiusAttributeType = RadiusAttributeT;
160 using FilterType = FilterT;
161
162 /// @param radius the attribute containing the world space radius
163 /// @details if the radius parameter is an empty string then the
164 /// `radiusScale` parameter is used as a uniform world space radius to
165 /// generate a fixed surface mask. Otherwise, a point attribute
166 /// representing the world space radius of each point of type
167 /// `RadiusAttributeT` is expected to exist and radii are scaled by the
168 /// `radiusScale` parameter.
169 std::string radius = "";
170
171 /// @param radiusScale the scale applied to every world space radius value
172 /// @note If no `radius` attribute is provided, this is used as the
173 /// uniform world space radius for every point. Most surfacing operations
174 /// will perform faster if they are able to assume a uniform radius (so
175 /// use this value instead of setting the `radius` parameter if radii are
176 /// uniform).
177 /// @note Type of the scale is always double precision (the Promote exists
178 /// as this could be a vector scale - see EllipsoidSettings).
179 using RadiusScaleT = typename PromoteType<RadiusAttributeT>::Highest;
180 RadiusScaleT radiusScale = RadiusScaleT(1.0);
181
182 /// @param halfband the half band width of the generated surface.
183 Real halfband = LEVEL_SET_HALF_WIDTH;
184
185 /// @param transform the target transform for the surface. Most surfacing
186 /// operations impose linear restrictions on the target transform.
187 math::Transform::Ptr transform = nullptr;
188
189 /// @param attributes list of attributes to transfer
190 /// @details if the attributes vector is empty, only the surface is built.
191 /// Otherwise, every voxel's closest point is used to transfer each
192 /// attribute in the attributes parameter to a new grid of matching
193 /// topology. The built surface is always the first grid returned from
194 /// the surfacing operation, followed by attribute grids in the order
195 /// that they appear in this vector.
196 ///
197 /// The `AttributeTs` template parameter should be a `TypeList` of the
198 /// required or possible attributes types. Example:
199 /// @code
200 /// // compile support for int, double and Vec3f attribute transferring
201 /// using SupportedTypes = TypeList<int, double, Vec3f>;
202 /// SphereSettings<SupportedTypes> s;
203 ///
204 /// // Produce 4 additional grids from the "v", "Cd", "id" and "density"
205 /// // attributes. Their attribute value types must be available in the
206 /// // provided TypeList
207 /// s.attributes = {"v", "Cd", "id", "density"};
208 /// @endcode
209 ///
210 /// A runtime error will be thrown if no equivalent type for a given
211 /// attribute is found in the `AttributeTs` TypeList.
212 ///
213 /// @note The destination types of these grids is equal to the
214 /// `ValueConverter` result of the attribute type applied to the
215 /// PointDataGridT.
216 std::vector<std::string> attributes;
217
218 /// @param filter a filter to apply to points. Only points that evaluate
219 /// to true using this filter are rasterized, regardless of any other
220 /// filtering derived schemes may use.
221 const FilterT* filter = nullptr;
222
223 /// @param interrupter optional interrupter
224 util::NullInterrupter* interrupter = nullptr;
225};
226
227/// @brief Smoothed point distribution based sphere stamping with a uniform radius
228/// or varying radius and optionally with closest point attribute transfer of
229/// arbitrary attributes. See the struct member documentation for detailed
230/// behavior.
231/// @note Protected inheritance prevents accidental struct slicing
232template <typename AttributeTs = TypeList<>,
233 typename RadiusAttributeT = float,
234 typename FilterT = NullFilter>
235 struct SmoothSphereSettings
236 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
237{
238 using BaseT = SphereSettings<AttributeTs, RadiusAttributeT, FilterT>;
239 using AttributeTypes = typename BaseT::AttributeTypes;
240 using RadiusAttributeType = typename BaseT::RadiusAttributeType;
241 using FilterType = typename BaseT::FilterType;
242
243 using BaseT::radius;
244 /// @note See also the searchRadius parameter for SmoothSpehere
245 /// rasterization.
246 using BaseT::radiusScale;
247 /// @warning The width of the exterior half band *may* be smaller than the
248 /// specified half band if the search radius is less than the equivalent
249 /// world space halfband distance.
250 using BaseT::halfband;
251 using BaseT::transform;
252 using BaseT::attributes;
253 using BaseT::filter;
254 using BaseT::interrupter;
255
256 /// @param searchRadius the maximum search distance of every point
257 /// @details The search radius is each points points maximum contribution
258 /// to the target level set. It should always have a value equal to or
259 /// larger than the point radius. Both this and the `radiusScale`
260 /// parameters are given in world space units and are applied to every
261 /// point to generate a surface mask.
262 /// @warning If this value is less than the sum of the maximum particle
263 /// radius and the half band width, the exterior half band width may be
264 /// smaller than desired. In these cases, consider running a levelset
265 /// renormalize or a levelset rebuild.
266 Real searchRadius = 1.0;
267};
268
269/// @brief Anisotropic point rasterization based on the principal component
270/// analysis of point neighbours. See the struct member documentation for
271/// detailed behavior.
272/// @details This rasterization technique is typically used with the
273/// accompanying PCA tools in PrincipalComponentAnalysis.h which initializes
274/// the required attributes. These attributes define the rotational and
275/// affine transformations which can be used to construct ellipsoids for each
276/// point. Typically (for our intended surfacing) these transformations are
277/// built by analysing each points neighbourhood distributions and
278/// constructing tight ellipsoids that orient themselves to follow these
279/// point distributions.
280/// @note Protected inheritance prevents accidental struct slicing
281template <typename AttributeTs = TypeList<>,
282 typename RadiusAttributeT = Vec3f,
283 typename FilterT = NullFilter>
284 struct EllipsoidSettings
285 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
286{
287 using BaseT = SphereSettings<AttributeTs, RadiusAttributeT, FilterT>;
288 using AttributeTypes = typename BaseT::AttributeTypes;
289 using RadiusAttributeType = typename BaseT::RadiusAttributeType;
290 using FilterType = typename BaseT::FilterType;
291
292 using BaseT::halfband;
293 using BaseT::transform;
294 using BaseT::attributes;
295 using BaseT::filter;
296 using BaseT::interrupter;
297
298 /// @note For ellipsoid rasterization, the radius attribute and scale
299 /// need to be Vec3f types (RadiusAttributeT defaults to this). This
300 /// represents each ellipsoids stretch and squash coefficients.
301 using BaseT::radius;
302 using BaseT::radiusScale;
303
304 /// @param rotation the attribute containing each points orthogonal
305 /// rotation matrix.
306 /// @details This attribute must exist and represents the rotation of
307 /// each points ellipse. Must be a Mat3s type.
308 std::string rotation = "rotation";
309
310 /// @param pws An optional attribute which represents the world space
311 /// position of a point.
312 /// @details This can be useful to override the position of a point in
313 /// index space. If it exists, it must be a Vec3d type.
314 std::string pws = "";
315};
316
317} // namespace points
318} // namespace OPENVDB_VERSION_NAME
319} // namespace openvdb
320
321#include "impl/PointRasterizeSDFImpl.h"
322#include "impl/PointRasterizeEllipsoidsSDFImpl.h"
323
324#endif //OPENVDB_POINTS_RASTERIZE_SDF_HAS_BEEN_INCLUDED
Assert.h
NullInterrupter.h
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
PointRasterizeEllipsoidsSDFImpl.h
PointRasterizeSDFImpl.h
PointStatistics.h
Functions to perform multi threaded reductions and analysis of arbitrary point attribute types....
PointTransfer.h
Framework methods for rasterizing PointDataGrid data to Trees.
Prune.h
Defined various multi-threaded utility functions for trees.
ValueTransformer.h
openvdb::v12_1::math::Transform::Ptr
SharedPtr< Transform > Ptr
Definition Transform.h:42
openvdb::v12_1::points::rasterizeSdf
GridPtrVec rasterizeSdf(const PointDataGridT &points, const SettingsT &settings)
Perform point rasterzation to produce a signed distance field.
Definition PointRasterizeSDFImpl.h:1525
openvdb::v12_1::LEVEL_SET_HALF_WIDTH
static const Real LEVEL_SET_HALF_WIDTH
Definition Types.h:532
openvdb::v12_1::GridPtrVec
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
openvdb::v12_1::Real
double Real
Definition Types.h:60
openvdb
Definition Exceptions.h:13
Types.h
openvdb.h
openvdb::v12_1::PromoteType::Highest
typename TypeT< 64ul >::type Highest
Definition Types.h:442
openvdb::v12_1::points::EllipsoidSettings
Anisotropic point rasterization based on the principal component analysis of point neighbours....
Definition PointRasterizeSDF.h:286
openvdb::v12_1::points::EllipsoidSettings::rotation
std::string rotation
Definition PointRasterizeSDF.h:308
openvdb::v12_1::points::EllipsoidSettings::AttributeTypes
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:288
openvdb::v12_1::points::EllipsoidSettings::RadiusAttributeType
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:289
openvdb::v12_1::points::EllipsoidSettings::BaseT
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:287
openvdb::v12_1::points::EllipsoidSettings::pws
std::string pws
Definition PointRasterizeSDF.h:314
openvdb::v12_1::points::EllipsoidSettings::FilterType
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:290
openvdb::v12_1::points::SmoothSphereSettings
Smoothed point distribution based sphere stamping with a uniform radius or varying radius and optiona...
Definition PointRasterizeSDF.h:237
openvdb::v12_1::points::SmoothSphereSettings::AttributeTypes
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:239
openvdb::v12_1::points::SmoothSphereSettings::RadiusAttributeType
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:240
openvdb::v12_1::points::SmoothSphereSettings::BaseT
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:238
openvdb::v12_1::points::SmoothSphereSettings::searchRadius
Real searchRadius
Definition PointRasterizeSDF.h:266
openvdb::v12_1::points::SmoothSphereSettings::FilterType
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:241
openvdb::v12_1::points::SphereSettings
Generic settings for narrow band spherical stamping with a uniform or varying radius and optionally w...
Definition PointRasterizeSDF.h:157
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::attributes
std::vector< std::string > attributes
Definition PointRasterizeSDF.h:216
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::filter
const FilterT * filter
Definition PointRasterizeSDF.h:221
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::transform
math::Transform::Ptr transform
Definition PointRasterizeSDF.h:187
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::halfband
Real halfband
Definition PointRasterizeSDF.h:183
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::radiusScale
RadiusScaleT radiusScale
Definition PointRasterizeSDF.h:180
openvdb::v12_1::points::SphereSettings::RadiusAttributeType
RadiusAttributeT RadiusAttributeType
Definition PointRasterizeSDF.h:159
openvdb::v12_1::points::SphereSettings::RadiusScaleT
typename PromoteType< RadiusAttributeT >::Highest RadiusScaleT
Definition PointRasterizeSDF.h:179
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::interrupter
util::NullInterrupter * interrupter
Definition PointRasterizeSDF.h:224
openvdb::v12_1::points::SphereSettings::FilterType
FilterT FilterType
Definition PointRasterizeSDF.h:160
openvdb::v12_1::points::SphereSettings::AttributeTypes
AttributeTs AttributeTypes
Definition PointRasterizeSDF.h:158
openvdb::v12_1::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::radius
std::string radius
Definition PointRasterizeSDF.h:169
openvdb::v12_1::util::NullInterrupter
Base class for interrupters.
Definition NullInterrupter.h:26
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218