Surface mesh point queries: C++ API¶
Codes written in C++ may use the object-oriented C++ APIs to perform in/out and signed distance queries. In addition to language choice, the C++ API lets a code work with more than one mesh at the same time. Unlike the C API, the C++ API for in/out and signed distance queries has no initializer taking a file name: readying the mesh is a separate, prior step.
In/out Octree¶
The C++ in/out query is provided by the quest::InOutOctree
class, from the
following header. See <axom>/src/axom/quest/tests/quest_inout_octree.cpp
.
#include "axom/quest/InOutOctree.hpp"
Some type aliases are useful for the sake of brevity. The class is templated on
the dimensionality of the mesh. Currently, only meshes in 3D are supported;
here DIM
equals 3.
using Octree3D = axom::quest::InOutOctree<DIM>;
using GeometricBoundingBox = Octree3D::GeometricBoundingBox;
using SpacePt = Octree3D::SpacePt;
Instantiate the object using GeometricBoundingBox bbox
and a mesh, and
generate the index.
Octree3D octree(bbox, mesh);
octree.generateIndex();
Test a query point.
SpacePt pt = SpacePt::make_point(2., 3., 1.);
bool inside = octree.within(pt);
All cleanup happens when the index object’s destructor is called
(in this case, when the variable octree
goes out of scope).
Signed Distance¶
The C++ signed distance query is provided by the quest::SignedDistance
class,
which wraps an instance of primal::BVHTree
.
Examples from <axom>/src/axom/quest/tests/quest_signed_distance.cpp
.
Class header:
#include "axom/quest/SignedDistance.hpp"
The constructor takes several arguments:
const mint::Mesh* surfaceMesh
: A pointer to a surface mesh with triangles and/or quadrilaterals.bool isWatertight
: Indicates the mesh is a watertight mesh, a manifold. The signed distance from a point to a manifold is mathematically well-defined. When the input is not a closed surface mesh, the mesh must span the entire computational mesh domain, dividing it into two regions.bool computeSign
(defaulttrue
): Optional. Enables or disables the computation of signs in distance queries.int allocatorID
: Optional. Sets a custom Umpire allocator to use in constructing the underlying BVH; by default, this is set to a default allocator for the execution space theSignedDistance
class is instantiated in (host-side memory for CPU and OpenMP, unified memory for GPUs).
Note that the second and subsequent arguments to the constructor correspond to
quest::signed_distance_set
functions in the C API.
As with the InOutOctree
, the class is templated on the dimensionality
of the mesh, with only 3D meshes being supported. The class also accepts a
template parameter for execution space, for running signed distance queries with
OpenMP or on a GPU.
// Set execution space
constexpr int BlockSize = 256;
#if defined(__CUDACC__)
using ExecSpace = axom::CUDA_EXEC<BlockSize>;
#elif defined(__HIPCC__)
using ExecSpace = axom::HIP_EXEC<BlockSize>;
#else
using ExecSpace = axom::SEQ_EXEC;
#endif
// Create a custom allocator
constexpr size_t PoolSize = 1024 * 1024 * 1024;
umpire::ResourceManager& rm = umpire::ResourceManager::getInstance();
umpire::Allocator device_allocator =
rm.makeAllocator<umpire::strategy::QuickPool>(
"DEVICE_POOL",
rm.getAllocator(umpire::resource::Device),
PoolSize);
int device_pool_id = device_allocator.getId();
// Set SignedDistance options
constexpr bool is_watertight = true;
constexpr bool compute_signs = true;
quest::SignedDistance<3, ExecSpace> signed_distance(surface_mesh,
is_watertight,
compute_signs,
device_pool_id);
Test a query point.
axom::primal::Point< double,3 > pt =
axom::primal::Point< double,3 >::make_point(2., 3., 1.);
double signedDistance = signed_distance.computeDistance(pt);
Test a batch of query points.
const int numPoints = 20;
axom::primal::Point<double, 3>* pts =
axom::allocate<axom::primal::Point<double, 3>>(numPoints);
for (int ipt = 0; ipt < numPoints; ipt++)
{
// fill pts array
pts[ipt] = ...;
}
double signedDists = axom::allocate<double>(20);
signed_distance.computeDistances(numPts, pts, signedDists);
The object destructor takes care of all cleanup.