OpenVDB: openvdb/points/PointRasterizeSDF.h Source File

OpenVDB 13.0.0

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 affine matrix attributes from the points::pca()
49/// method which model these elliptical distributions using principal
50/// component analysis. The ellipses create a much tighter, more fitted
51/// surface that better represents the convex hull of the point set. This
52/// technique also allows point to smoothly blend from their computed
53/// ellipse back to a canonical sphere, as well as allowing isolated points
54/// to be rasterized with their own radius. Although the rasterization step
55/// of this pipeline is relatively fast, it is still the slowest of all
56/// three methods, and depends on the somewhat expensive points::pca()
57/// method if you're not providing your own transformations. Still, this
58/// technique can be far superior at producing fluid surfaces where thin
59/// sheets (waterfalls) or sharp edges (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/// ellips.xform = attribs.xform;
130/// ellips.radius = attribs.stretch;
131/// ellips.attributes.emplace_back("id");
132/// ellips.attributes.emplace_back("v");
133/// GridPtrVec grids = points::rasterizeSdf(g, ellips);
134/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(grids[0]);
135/// Int32Grid::Ptr id = StaticPtrCast<Int32Grid>(grids[1]);
136/// Vec3fGrid::Ptr vel = StaticPtrCast<Vec3fGrid>(grids[2]);
137/// @endcode
138template <typename PointDataGridT,
139 typename SdfT = typename PointDataGridT::template ValueConverter<float>::Type,
140 typename SettingsT>
141 GridPtrVec
142 rasterizeSdf(const PointDataGridT& points, const SettingsT& settings);
143
144//
145
146/// @brief Generic settings for narrow band spherical stamping with a uniform
147/// or varying radius and optionally with closest point attribute transfer of
148/// arbitrary attributes. See the struct member documentation for detailed
149/// behavior.
150/// @note There exists other more complex kernels that derive from this struct,
151/// but on its own it represents the settings needed to perform basic narrow
152/// band sphere stamping. Parameters are interpreted in the same way across
153/// derived classes.
154template <typename AttributeTs = TypeList<>,
155 typename RadiusAttributeT = float,
156 typename FilterT = NullFilter>
157 struct SphereSettings
158{
159 using AttributeTypes = AttributeTs;
160 using RadiusAttributeType = RadiusAttributeT;
161 using FilterType = FilterT;
162
163 /// @param radius the attribute containing the world space radius
164 /// @details if the radius parameter is an empty string then the
165 /// `radiusScale` parameter is used as a uniform world space radius to
166 /// generate a fixed surface mask. Otherwise, a point attribute
167 /// representing the world space radius of each point of type
168 /// `RadiusAttributeT` is expected to exist and radii are scaled by the
169 /// `radiusScale` parameter.
170 std::string radius = "";
171
172 /// @param radiusScale the scale applied to every world space radius value
173 /// @note If no `radius` attribute is provided, this is used as the
174 /// uniform world space radius for every point. Most surfacing operations
175 /// will perform faster if they are able to assume a uniform radius (so
176 /// use this value instead of setting the `radius` parameter if radii are
177 /// uniform).
178 /// @note Type of the scale is always double precision (the Promote exists
179 /// as this could be a vector scale - see EllipsoidSettings).
180 using RadiusScaleT = typename PromoteType<RadiusAttributeT>::Highest;
181 RadiusScaleT radiusScale = RadiusScaleT(1.0);
182
183 /// @param halfband the half band width of the generated surface.
184 Real halfband = LEVEL_SET_HALF_WIDTH;
185
186 /// @param transform the target transform for the surface. Most surfacing
187 /// operations impose linear restrictions on the target transform.
188 math::Transform::Ptr transform = nullptr;
189
190 /// @param attributes list of attributes to transfer
191 /// @details if the attributes vector is empty, only the surface is built.
192 /// Otherwise, every voxel's closest point is used to transfer each
193 /// attribute in the attributes parameter to a new grid of matching
194 /// topology. The built surface is always the first grid returned from
195 /// the surfacing operation, followed by attribute grids in the order
196 /// that they appear in this vector.
197 ///
198 /// The `AttributeTs` template parameter should be a `TypeList` of the
199 /// required or possible attributes types. Example:
200 /// @code
201 /// // compile support for int, double and Vec3f attribute transferring
202 /// using SupportedTypes = TypeList<int, double, Vec3f>;
203 /// SphereSettings<SupportedTypes> s;
204 ///
205 /// // Produce 4 additional grids from the "v", "Cd", "id" and "density"
206 /// // attributes. Their attribute value types must be available in the
207 /// // provided TypeList
208 /// s.attributes = {"v", "Cd", "id", "density"};
209 /// @endcode
210 ///
211 /// A runtime error will be thrown if no equivalent type for a given
212 /// attribute is found in the `AttributeTs` TypeList.
213 ///
214 /// @note The destination types of these grids is equal to the
215 /// `ValueConverter` result of the attribute type applied to the
216 /// PointDataGridT.
217 std::vector<std::string> attributes;
218
219 /// @param filter a filter to apply to points. Only points that evaluate
220 /// to true using this filter are rasterized, regardless of any other
221 /// filtering derived schemes may use.
222 const FilterT* filter = nullptr;
223
224 /// @param interrupter optional interrupter
225 util::NullInterrupter* interrupter = nullptr;
226};
227
228/// @brief Smoothed point distribution based sphere stamping with a uniform radius
229/// or varying radius and optionally with closest point attribute transfer of
230/// arbitrary attributes. See the struct member documentation for detailed
231/// behavior.
232/// @note Protected inheritance prevents accidental struct slicing
233template <typename AttributeTs = TypeList<>,
234 typename RadiusAttributeT = float,
235 typename FilterT = NullFilter>
236 struct SmoothSphereSettings
237 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
238{
239 using BaseT = SphereSettings<AttributeTs, RadiusAttributeT, FilterT>;
240 using AttributeTypes = typename BaseT::AttributeTypes;
241 using RadiusAttributeType = typename BaseT::RadiusAttributeType;
242 using FilterType = typename BaseT::FilterType;
243
244 using BaseT::radius;
245 /// @note See also the searchRadius parameter for SmoothSpehere
246 /// rasterization.
247 using BaseT::radiusScale;
248 /// @warning The width of the exterior half band *may* be smaller than the
249 /// specified half band if the search radius is less than the equivalent
250 /// world space halfband distance.
251 using BaseT::halfband;
252 using BaseT::transform;
253 using BaseT::attributes;
254 using BaseT::filter;
255 using BaseT::interrupter;
256
257 /// @param searchRadius the maximum search distance of every point
258 /// @details The search radius is each points points maximum contribution
259 /// to the target level set. It should always have a value equal to or
260 /// larger than the point radius. Both this and the `radiusScale`
261 /// parameters are given in world space units and are applied to every
262 /// point to generate a surface mask.
263 /// @warning If this value is less than the sum of the maximum particle
264 /// radius and the half band width, the exterior half band width may be
265 /// smaller than desired. In these cases, consider running a levelset
266 /// renormalize or a levelset rebuild.
267 Real searchRadius = 1.0;
268};
269
270// Suppress spurious warnings on compiler emitted methods (constructors, etc)
271// due to deprecated members. Accessing said members still generates the warning.
272 OPENVDB_NO_DEPRECATION_WARNING_BEGIN
273
274/// @brief Anisotropic point rasterization based on the principal component
275/// analysis of point neighbours. See the struct member documentation for
276/// detailed behavior.
277/// @details This rasterization technique is typically used with the
278/// accompanying PCA tools in PrincipalComponentAnalysis.h which initializes
279/// the required attributes. These attributes define the rotational and
280/// affine transformations which can be used to construct ellipsoids for each
281/// point. Typically (for our intended surfacing) these transformations are
282/// built by analysing each points neighbourhood distributions and
283/// constructing tight ellipsoids that orient themselves to follow these
284/// point distributions.
285/// @note Protected inheritance prevents accidental struct slicing
286template <typename AttributeTs = TypeList<>,
287 typename RadiusAttributeT = Vec3f,
288 typename FilterT = NullFilter>
289 struct EllipsoidSettings
290 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
291{
292 using BaseT = SphereSettings<AttributeTs, RadiusAttributeT, FilterT>;
293 using AttributeTypes = typename BaseT::AttributeTypes;
294 using RadiusAttributeType = typename BaseT::RadiusAttributeType;
295 using FilterType = typename BaseT::FilterType;
296
297 using BaseT::halfband;
298 using BaseT::transform;
299 using BaseT::attributes;
300 using BaseT::filter;
301 using BaseT::interrupter;
302
303 /// @note For ellipsoid rasterization, the radius attribute and scale
304 /// need to be Vec3f types (RadiusAttributeT defaults to this). This
305 /// represents each ellipsoids stretch and squash coefficients.
306 using BaseT::radius;
307 using BaseT::radiusScale;
308
309 /// @param xform the attribute containing each points transformation
310 /// @details This attribute must exist and represents the xform of
311 /// each points ellipse. Must be a Mat3s (float) or Quatf type. Note
312 /// that if it is a matrix type, any scale represented by the matrix
313 /// is combined with the radius and radiusScale values (and is
314 /// interpreted in world space).
315 std::string xform = "xform";
316
317 /// @param pws An optional attribute which represents the world space
318 /// position of a point.
319 /// @details This can be useful to override the position of a point in
320 /// index space. If it exists, it must be a Vec3d type.
321 std::string pws = "";
322
323 /// Old style "xform" attribute which has since been renamed and ONLY
324 /// supported rotation. If set, will be prioritised and infered to only
325 /// hold a rotation. This will be removed and should not be used.
326 OPENVDB_DEPRECATED_MESSAGE("Use EllipsoidSettings::xform") std::string rotation = "";
327};
328
329 OPENVDB_NO_DEPRECATION_WARNING_END
330
331} // namespace points
332} // namespace OPENVDB_VERSION_NAME
333} // namespace openvdb
334
335#include "impl/PointRasterizeSDFImpl.h"
336#include "impl/PointRasterizeEllipsoidsSDFImpl.h"
337
338#endif //OPENVDB_POINTS_RASTERIZE_SDF_HAS_BEEN_INCLUDED
Assert.h
NullInterrupter.h
OPENVDB_NO_DEPRECATION_WARNING_END
#define OPENVDB_NO_DEPRECATION_WARNING_END
Definition Platform.h:218
OPENVDB_NO_DEPRECATION_WARNING_BEGIN
#define OPENVDB_NO_DEPRECATION_WARNING_BEGIN
Bracket code with OPENVDB_NO_DEPRECATION_WARNING_BEGIN/_END, to inhibit warnings about deprecated cod...
Definition Platform.h:217
OPENVDB_DEPRECATED_MESSAGE
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:171
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
PointRasterizeEllipsoidsSDFImpl.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::v13_0::math::Transform::Ptr
SharedPtr< Transform > Ptr
Definition Transform.h:42
openvdb::v13_0::points::rasterizeSdf
GridPtrVec rasterizeSdf(const PointDataGridT &points, const SettingsT &settings)
Perform point rasterzation to produce a signed distance field.
Definition PointRasterizeSDFImpl.h:1525
openvdb::v13_0::LEVEL_SET_HALF_WIDTH
static const Real LEVEL_SET_HALF_WIDTH
Definition Types.h:528
openvdb::v13_0::GridPtrVec
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
openvdb::v13_0::Real
double Real
Definition Types.h:40
openvdb
Definition Exceptions.h:13
std
Definition Coord.h:590
Types.h
openvdb.h
openvdb::v13_0::PromoteType::Highest
typename TypeT< 64ul >::type Highest
Definition Types.h:423
openvdb::v13_0::points::EllipsoidSettings
Anisotropic point rasterization based on the principal component analysis of point neighbours....
Definition PointRasterizeSDF.h:291
openvdb::v13_0::points::EllipsoidSettings::rotation
std::string rotation
Definition PointRasterizeSDF.h:326
openvdb::v13_0::points::EllipsoidSettings::AttributeTypes
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:293
openvdb::v13_0::points::EllipsoidSettings::RadiusAttributeType
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:294
openvdb::v13_0::points::EllipsoidSettings::BaseT
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:292
openvdb::v13_0::points::EllipsoidSettings::xform
std::string xform
Definition PointRasterizeSDF.h:315
openvdb::v13_0::points::EllipsoidSettings::pws
std::string pws
Definition PointRasterizeSDF.h:321
openvdb::v13_0::points::EllipsoidSettings::FilterType
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:295
openvdb::v13_0::points::SmoothSphereSettings
Smoothed point distribution based sphere stamping with a uniform radius or varying radius and optiona...
Definition PointRasterizeSDF.h:238
openvdb::v13_0::points::SmoothSphereSettings::AttributeTypes
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:240
openvdb::v13_0::points::SmoothSphereSettings::RadiusAttributeType
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:241
openvdb::v13_0::points::SmoothSphereSettings::BaseT
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:239
openvdb::v13_0::points::SmoothSphereSettings::searchRadius
Real searchRadius
Definition PointRasterizeSDF.h:267
openvdb::v13_0::points::SmoothSphereSettings::FilterType
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:242
openvdb::v13_0::points::SphereSettings
Generic settings for narrow band spherical stamping with a uniform or varying radius and optionally w...
Definition PointRasterizeSDF.h:158
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::attributes
std::vector< std::string > attributes
Definition PointRasterizeSDF.h:217
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::filter
const FilterT * filter
Definition PointRasterizeSDF.h:222
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::transform
math::Transform::Ptr transform
Definition PointRasterizeSDF.h:188
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::halfband
Real halfband
Definition PointRasterizeSDF.h:184
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::radiusScale
RadiusScaleT radiusScale
Definition PointRasterizeSDF.h:181
openvdb::v13_0::points::SphereSettings::RadiusAttributeType
RadiusAttributeT RadiusAttributeType
Definition PointRasterizeSDF.h:160
openvdb::v13_0::points::SphereSettings::RadiusScaleT
typename PromoteType< RadiusAttributeT >::Highest RadiusScaleT
Definition PointRasterizeSDF.h:180
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::interrupter
util::NullInterrupter * interrupter
Definition PointRasterizeSDF.h:225
openvdb::v13_0::points::SphereSettings::FilterType
FilterT FilterType
Definition PointRasterizeSDF.h:161
openvdb::v13_0::points::SphereSettings::AttributeTypes
AttributeTs AttributeTypes
Definition PointRasterizeSDF.h:159
openvdb::v13_0::points::SphereSettings< AttributeTs, RadiusAttributeT, FilterT >::radius
std::string radius
Definition PointRasterizeSDF.h:170
openvdb::v13_0::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