OpenVDB 13.0.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 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>
81#include <openvdb/util/Assert.h>
82#include <openvdb/simd/Simd.h>
83
84#include <unordered_map>
85
86#include <tbb/task_group.h>
87#include <tbb/parallel_reduce.h>
88
89namespace openvdb {
91namespace OPENVDB_VERSION_NAME {
92namespace points {
93
94/// @brief Perform point rasterzation to produce a signed distance field.
95/// @param points the point data grid to rasterize
96/// @param settings one of the available transfer setting schemes found below
97/// in this file.
98/// @return A vector of grids. The signed distance field is guaranteed to be
99/// first and at the type specified by SdfT. Successive grids are the closest
100/// point attribute grids. These grids are guaranteed to have a topology
101/// and transform equal to the surface.
102///
103/// @code
104/// points::PointDataGrid g = ...;
105///
106/// // default settings for sphere stamping with a world space radius of 1
107/// SphereSettings<> spheres;
108/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, spheres)[0]);
109///
110/// // custom linear transform of target sdf, world space radius of 5
111/// spheres.transform = math::Transform::createLinearTransform(0.3);
112/// spheres.radiusScale = 5;
113/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, spheres)[0]);
114///
115/// // smooth sphere rasterization with variable double precision radius
116/// // attribute "pscale" scaled by 2
117/// SmoothSphereSettings<TypeList<>, double> smooth;
118/// smooth.radius = "pscale";
119/// smooth.radiusScale = 2;
120/// smooth.searchRadius = 3;
121/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(points::rasterizeSdf(g, smooth)[0]);
122///
123/// // anisotropic/ellipsoid rasterization with attribute transferring.
124/// // requires pca attributes to be initialized using points::pca() first
125/// PcaSettings settings;
126/// PcaAttributes attribs;
127/// points::pca(g, settings, attribs);
128///
129/// EllipsoidSettings<TypeList<int32_t, Vec3f>> ellips;
130/// ellips.xform = attribs.xform;
131/// ellips.radius = attribs.stretch;
132/// ellips.attributes.emplace_back("id");
133/// ellips.attributes.emplace_back("v");
134/// GridPtrVec grids = points::rasterizeSdf(g, ellips);
135/// FloatGrid::Ptr sdf = StaticPtrCast<FloatGrid>(grids[0]);
136/// Int32Grid::Ptr id = StaticPtrCast<Int32Grid>(grids[1]);
137/// Vec3fGrid::Ptr vel = StaticPtrCast<Vec3fGrid>(grids[2]);
138/// @endcode
139template <typename PointDataGridT,
140 typename SdfT = typename PointDataGridT::template ValueConverter<float>::Type,
141 typename SettingsT>
143rasterizeSdf(const PointDataGridT& points, const SettingsT& settings);
144
145//
146
147/// @brief Generic settings for narrow band spherical stamping with a uniform
148/// or varying radius and optionally with closest point attribute transfer of
149/// arbitrary attributes. See the struct member documentation for detailed
150/// behavior.
151/// @note There exists other more complex kernels that derive from this struct,
152/// but on its own it represents the settings needed to perform basic narrow
153/// band sphere stamping. Parameters are interpreted in the same way across
154/// derived classes.
155template <typename AttributeTs = TypeList<>,
156 typename RadiusAttributeT = float,
157 typename FilterT = NullFilter>
159{
160 using AttributeTypes = AttributeTs;
161 using RadiusAttributeType = RadiusAttributeT;
162 using FilterType = FilterT;
163
164 /// @param radius the attribute containing the world space radius
165 /// @details if the radius parameter is an empty string then the
166 /// `radiusScale` parameter is used as a uniform world space radius to
167 /// generate a fixed surface mask. Otherwise, a point attribute
168 /// representing the world space radius of each point of type
169 /// `RadiusAttributeT` is expected to exist and radii are scaled by the
170 /// `radiusScale` parameter.
171 std::string radius = "";
172
173 /// @param radiusScale the scale applied to every world space radius value
174 /// @note If no `radius` attribute is provided, this is used as the
175 /// uniform world space radius for every point. Most surfacing operations
176 /// will perform faster if they are able to assume a uniform radius (so
177 /// use this value instead of setting the `radius` parameter if radii are
178 /// uniform).
179 /// @note Type of the scale is always double precision (the Promote exists
180 /// as this could be a vector scale - see EllipsoidSettings).
183
184 /// @param halfband the half band width of the generated surface.
186
187 /// @param transform the target transform for the surface. Most surfacing
188 /// operations impose linear restrictions on the target transform.
190
191 /// @param attributes list of attributes to transfer
192 /// @details if the attributes vector is empty, only the surface is built.
193 /// Otherwise, every voxel's closest point is used to transfer each
194 /// attribute in the attributes parameter to a new grid of matching
195 /// topology. The built surface is always the first grid returned from
196 /// the surfacing operation, followed by attribute grids in the order
197 /// that they appear in this vector.
198 ///
199 /// The `AttributeTs` template parameter should be a `TypeList` of the
200 /// required or possible attributes types. Example:
201 /// @code
202 /// // compile support for int, double and Vec3f attribute transferring
203 /// using SupportedTypes = TypeList<int, double, Vec3f>;
204 /// SphereSettings<SupportedTypes> s;
205 ///
206 /// // Produce 4 additional grids from the "v", "Cd", "id" and "density"
207 /// // attributes. Their attribute value types must be available in the
208 /// // provided TypeList
209 /// s.attributes = {"v", "Cd", "id", "density"};
210 /// @endcode
211 ///
212 /// A runtime error will be thrown if no equivalent type for a given
213 /// attribute is found in the `AttributeTs` TypeList.
214 ///
215 /// @note The destination types of these grids is equal to the
216 /// `ValueConverter` result of the attribute type applied to the
217 /// PointDataGridT.
218 std::vector<std::string> attributes;
219
220 /// @param filter a filter to apply to points. Only points that evaluate
221 /// to true using this filter are rasterized, regardless of any other
222 /// filtering derived schemes may use.
223 const FilterT* filter = nullptr;
224
225 /// @param interrupter optional interrupter
227};
228
229/// @brief Smoothed point distribution based sphere stamping with a uniform radius
230/// or varying radius and optionally with closest point attribute transfer of
231/// arbitrary attributes. See the struct member documentation for detailed
232/// behavior.
233/// @note Protected inheritance prevents accidental struct slicing
234template <typename AttributeTs = TypeList<>,
235 typename RadiusAttributeT = float,
236 typename FilterT = NullFilter>
238 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
239{
244
245 using BaseT::radius;
246 /// @note See also the searchRadius parameter for SmoothSpehere
247 /// rasterization.
248 using BaseT::radiusScale;
249 /// @warning The width of the exterior half band *may* be smaller than the
250 /// specified half band if the search radius is less than the equivalent
251 /// world space halfband distance.
252 using BaseT::halfband;
253 using BaseT::transform;
254 using BaseT::attributes;
255 using BaseT::filter;
256 using BaseT::interrupter;
257
258 /// @param searchRadius the maximum search distance of every point
259 /// @details The search radius is each points points maximum contribution
260 /// to the target level set. It should always have a value equal to or
261 /// larger than the point radius. Both this and the `radiusScale`
262 /// parameters are given in world space units and are applied to every
263 /// point to generate a surface mask.
264 /// @warning If this value is less than the sum of the maximum particle
265 /// radius and the half band width, the exterior half band width may be
266 /// smaller than desired. In these cases, consider running a levelset
267 /// renormalize or a levelset rebuild.
269};
270
271// Suppress spurious warnings on compiler emitted methods (constructors, etc)
272// due to deprecated members. Accessing said members still generates the warning.
274
275/// @brief Anisotropic point rasterization based on the principal component
276/// analysis of point neighbours. See the struct member documentation for
277/// detailed behavior.
278/// @details This rasterization technique is typically used with the
279/// accompanying PCA tools in PrincipalComponentAnalysis.h which initializes
280/// the required attributes. These attributes define the rotational and
281/// affine transformations which can be used to construct ellipsoids for each
282/// point. Typically (for our intended surfacing) these transformations are
283/// built by analysing each points neighbourhood distributions and
284/// constructing tight ellipsoids that orient themselves to follow these
285/// point distributions.
286/// @note Protected inheritance prevents accidental struct slicing
287template <typename AttributeTs = TypeList<>,
288 typename RadiusAttributeT = Vec3f,
289 typename FilterT = NullFilter>
291 : protected SphereSettings<AttributeTs, RadiusAttributeT, FilterT>
292{
297
298 using BaseT::halfband;
299 using BaseT::transform;
300 using BaseT::attributes;
301 using BaseT::filter;
302 using BaseT::interrupter;
303
304 /// @note For ellipsoid rasterization, the radius attribute and scale
305 /// need to be Vec3f types (RadiusAttributeT defaults to this). This
306 /// represents each ellipsoids stretch and squash coefficients.
307 using BaseT::radius;
308 using BaseT::radiusScale;
309
310 /// @param xform the attribute containing each points transformation
311 /// @details This attribute must exist and represents the xform of
312 /// each points ellipse. Must be a Mat3s (float) or Quatf type. Note
313 /// that if it is a matrix type, any scale represented by the matrix
314 /// is combined with the radius and radiusScale values (and is
315 /// interpreted in world space).
316 std::string xform = "xform";
317
318 /// @param pws An optional attribute which represents the world space
319 /// position of a point.
320 /// @details This can be useful to override the position of a point in
321 /// index space. If it exists, it must be a Vec3d type.
322 std::string pws = "";
323
324 /// Old style "xform" attribute which has since been renamed and ONLY
325 /// supported rotation. If set, will be prioritised and infered to only
326 /// hold a rotation. This will be removed and should not be used.
327 OPENVDB_DEPRECATED_MESSAGE("Use EllipsoidSettings::xform") std::string rotation = "";
328};
329
331
332} // namespace points
333} // namespace OPENVDB_VERSION_NAME
334} // namespace openvdb
335
336#include "impl/PointRasterizeSDFImpl.h"
337#include "impl/PointRasterizeEllipsoidsSDFImpl.h"
338
339#endif //OPENVDB_POINTS_RASTERIZE_SDF_HAS_BEEN_INCLUDED
#define OPENVDB_NO_DEPRECATION_WARNING_END
Definition Platform.h:205
#define OPENVDB_NO_DEPRECATION_WARNING_BEGIN
Bracket code with OPENVDB_NO_DEPRECATION_WARNING_BEGIN/_END, to inhibit warnings about deprecated cod...
Definition Platform.h:204
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:158
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Functions to perform multi threaded reductions and analysis of arbitrary point attribute types....
Framework methods for rasterizing PointDataGrid data to Trees.
Defined various multi-threaded utility functions for trees.
SharedPtr< Transform > Ptr
Definition Transform.h:42
Definition AttributeArray.h:42
GridPtrVec rasterizeSdf(const PointDataGridT &points, const SettingsT &settings)
Perform point rasterzation to produce a signed distance field.
static const Real LEVEL_SET_HALF_WIDTH
Definition Types.h:532
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
double Real
Definition Types.h:40
Definition Exceptions.h:13
Definition Coord.h:590
typename TypeT< 64ul >::type Highest
Definition Types.h:427
Anisotropic point rasterization based on the principal component analysis of point neighbours....
Definition PointRasterizeSDF.h:292
std::string rotation
Definition PointRasterizeSDF.h:327
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:294
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:295
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:293
std::string xform
Definition PointRasterizeSDF.h:316
std::string pws
Definition PointRasterizeSDF.h:322
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:296
Smoothed point distribution based sphere stamping with a uniform radius or varying radius and optiona...
Definition PointRasterizeSDF.h:239
typename BaseT::AttributeTypes AttributeTypes
Definition PointRasterizeSDF.h:241
typename BaseT::RadiusAttributeType RadiusAttributeType
Definition PointRasterizeSDF.h:242
SphereSettings< AttributeTs, RadiusAttributeT, FilterT > BaseT
Definition PointRasterizeSDF.h:240
Real searchRadius
Definition PointRasterizeSDF.h:268
typename BaseT::FilterType FilterType
Definition PointRasterizeSDF.h:243
Generic settings for narrow band spherical stamping with a uniform or varying radius and optionally w...
Definition PointRasterizeSDF.h:159
std::vector< std::string > attributes
Definition PointRasterizeSDF.h:218
math::Transform::Ptr transform
Definition PointRasterizeSDF.h:189
RadiusAttributeT RadiusAttributeType
Definition PointRasterizeSDF.h:161
typename PromoteType< RadiusAttributeT >::Highest RadiusScaleT
Definition PointRasterizeSDF.h:181
util::NullInterrupter * interrupter
Definition PointRasterizeSDF.h:226
FilterT FilterType
Definition PointRasterizeSDF.h:162
AttributeTs AttributeTypes
Definition PointRasterizeSDF.h:160
Base class for interrupters.
Definition NullInterrupter.h:26
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284