Skip to content

Commit d3322a7

Browse files
committed
Wrapper and tests for packed VDB volumes
1 parent ade96f0 commit d3322a7

22 files changed

+87
-41
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,17 +1142,18 @@ VDB volumes have the following parameters:
11421142
| uint32\[\] | node.level | level on which each input node exists, may be 1, 2 or 3 (levels are counted from the root level = 0 down) |
11431143
| vec3i\[\] | node.origin | the node origin index (per input node) |
11441144
| OSPData\[\] | node.data | [data](#data) arrays with the node data (per input node). Nodes that are tiles are expected to have single-item arrays. Leaf-nodes with grid data expected to have compact 3D arrays in zyx layout (z changes most quickly) with the correct number of voxels for the `level`. Only `OSP_FLOAT` is supported as field `OSPDataType`. |
1145-
| OSPData\[\] | nodesPackedDense | Optionally provided instead of `node.data`, for each attribute a single array of all dense node data in a contiguous zyx layout, provided in the same order as the corresponding `node.*` parameters. This packed layout may be more performant. |
1146-
| OSPData\[\] | nodesPackedTile | Optionally provided instead of `node.data`, for each attribute a single array of all tile node data in a contiguous layout, provided in the same order as the corresponding `node.*` parameters. This packed layout may be more performant. |
1145+
| OSPData | nodesPackedDense | optionally provided instead of `node.data`, a single array of all dense node data in a contiguous zyx layout, provided in the same order as the corresponding `node.*` parameters |
1146+
| OSPData | nodesPackedTile | optionally provided instead of `node.data`, a single array of all tile node data in a contiguous layout, provided in the same order as the corresponding `node.*` parameters |
1147+
| uint32\[\] | node.format | for each input node, whether it is of format `OSP_VOLUME_FORMAT_DENSE_ZYX` (and thus stored in `nodesPackedDense`), or `OSP_VOLUME_FORMAT_TILE` (stored in `nodesPackedTile`) |
11471148
| int | filter | filter used for reconstructing the field, default is `OSP_VOLUME_FILTER_TRILINEAR`, alternatively `OSP_VOLUME_FILTER_NEAREST`, or `OSP_VOLUME_FILTER_TRICUBIC`. |
11481149
| int | gradientFilter | filter used for reconstructing the field during gradient computations, default same as `filter` |
11491150
| float | background | value that is used when sampling an undefined region outside the volume domain, default `NaN` |
11501151

11511152
Configuration parameters for VDB volumes.
11521153

1153-
The `nodesPackedDense` and `nodesPackedTile` parameters may be provided
1154-
instead of `node.data`; this packed data layout may provide better
1155-
performance.
1154+
The `nodesPackedDense` and `nodesPackedTile` together with `node.format`
1155+
parameters may be provided instead of `node.data`; this packed data
1156+
layout may provide better performance.
11561157

11571158
1. Museth, K. VDB: High-Resolution Sparse Volumes with Dynamic
11581159
Topology. ACM Transactions on Graphics 32(3), 2013. DOI:

apps/common/ospray_testing/builders/VdbVolume.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace testing {
1414

1515
struct VdbVolume : public detail::Builder
1616
{
17-
VdbVolume() = default;
17+
VdbVolume(bool packed = false) : packed(packed) {}
1818
~VdbVolume() override = default;
1919

2020
void commit() override;
@@ -25,6 +25,7 @@ struct VdbVolume : public detail::Builder
2525
private:
2626
float densityScale{1.f};
2727
float anisotropy{0.f};
28+
bool packed{false};
2829
static constexpr uint32_t domainRes = 128;
2930
};
3031

@@ -42,17 +43,17 @@ cpp::Group VdbVolume::buildGroup() const
4243
{
4344
cpp::Volume volume("vdb");
4445

45-
std::vector<uint32_t> level;
4646
std::vector<vec3i> origin;
4747
std::vector<cpp::CopiedData> data;
48+
std::vector<float> dataPacked;
4849

4950
constexpr uint32_t leafRes = 8;
5051
constexpr uint32_t N = domainRes / leafRes;
5152
constexpr size_t numLeaves = N * static_cast<size_t>(N) * N;
5253

53-
level.reserve(numLeaves);
5454
origin.reserve(numLeaves);
55-
data.reserve(numLeaves);
55+
if (!packed)
56+
data.reserve(numLeaves);
5657

5758
std::vector<float> leaf(leafRes * (size_t)leafRes * leafRes, 0.f);
5859
for (uint32_t z = 0; z < N; ++z)
@@ -80,21 +81,30 @@ cpp::Group VdbVolume::buildGroup() const
8081
leafValueRange[0].extend(vr);
8182

8283
if (leafValueRange[0].lower != 0.f || leafValueRange[0].upper != 0.f) {
83-
level.push_back(3);
8484
origin.push_back(vec3i(x * leafRes, y * leafRes, z * leafRes));
85-
data.emplace_back(
86-
cpp::CopiedData(leaf.data(), vec3ul(leafRes, leafRes, leafRes)));
85+
if (packed)
86+
std::copy(leaf.begin(), leaf.end(), std::back_inserter(dataPacked));
87+
else
88+
data.emplace_back(cpp::CopiedData(
89+
leaf.data(), vec3ul(leafRes, leafRes, leafRes)));
8790
}
8891
}
8992

90-
if (level.empty())
93+
if (origin.empty())
9194
throw std::runtime_error("vdb volume is empty.");
9295

9396
volume.setParam("filter", (int)OSP_VOLUME_FILTER_TRILINEAR);
9497
volume.setParam("gradientFilter", (int)OSP_VOLUME_FILTER_TRILINEAR);
95-
volume.setParam("node.level", cpp::CopiedData(level));
98+
volume.setParam(
99+
"node.level", cpp::CopiedData(std::vector<uint32_t>(origin.size(), 3)));
96100
volume.setParam("node.origin", cpp::CopiedData(origin));
97-
volume.setParam("node.data", cpp::CopiedData(data));
101+
if (packed) {
102+
volume.setParam("nodesPackedDense", cpp::CopiedData(dataPacked));
103+
volume.setParam("node.format",
104+
cpp::CopiedData(std::vector<OSPVolumeFormat>(
105+
origin.size(), OSP_VOLUME_FORMAT_DENSE_ZYX)));
106+
} else
107+
volume.setParam("node.data", cpp::CopiedData(data));
98108
volume.commit();
99109

100110
cpp::VolumetricModel model(volume);
@@ -145,6 +155,7 @@ cpp::World VdbVolume::buildWorld() const
145155
}
146156

147157
OSP_REGISTER_TESTING_BUILDER(VdbVolume, vdb_volume);
158+
OSP_REGISTER_TESTING_BUILDER(VdbVolume(true), vdb_volume_packed);
148159

149160
} // namespace testing
150161
} // namespace ospray

apps/ospExamples/GLFWOSPRayWindow.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static const std::vector<std::string> g_scenes = {"boxes_lit",
5252
"particle_volume",
5353
"particle_volume_isosurface",
5454
"vdb_volume",
55+
"vdb_volume_packed",
5556
"instancing"};
5657

5758
static const std::vector<std::string> g_curveVariant = {

apps/ospTestSuite/test_enums.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,14 @@ TEST(Enums, VKLFilter)
110110
ASSERT_EQ(OSP_VOLUME_FILTER_TRILINEAR, VKL_FILTER_TRILINEAR);
111111
ASSERT_EQ(OSP_VOLUME_FILTER_TRICUBIC, VKL_FILTER_TRICUBIC);
112112
}
113-
113+
114+
TEST(Enums, VKLFormat)
115+
{
116+
ASSERT_LE(sizeof(OSPVolumeFormat), sizeof(VKLFormat));
117+
ASSERT_EQ(OSP_VOLUME_FORMAT_TILE, VKL_FORMAT_TILE);
118+
ASSERT_EQ(OSP_VOLUME_FORMAT_DENSE_ZYX, VKL_FORMAT_DENSE_ZYX);
119+
}
120+
114121
TEST(Enums, VKLError)
115122
{
116123
ASSERT_LE(sizeof(OSPError), sizeof(VKLError));

apps/ospTestSuite/test_volumetric.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ INSTANTIATE_TEST_SUITE_P(TestScenesVolumes,
342342
"unstructured_volume_simple",
343343
"particle_volume",
344344
"vdb_volume",
345+
"vdb_volume_packed",
345346
"gravity_spheres_amr"),
346347
::testing::Values("scivis", "pathtracer", "ao"),
347348
::testing::Values(16)));

doc/api.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -905,18 +905,20 @@ VDB volumes have the following parameters:
905905
of voxels for the `level`. Only `OSP_FLOAT` is
906906
supported as field `OSPDataType`.
907907

908-
OSPData[] nodesPackedDense Optionally provided instead of `node.data`, for
909-
each attribute a single array of all dense node
910-
data in a contiguous zyx layout, provided in the
911-
same order as the corresponding `node.*`
912-
parameters. This packed layout may be more
913-
performant.
914-
915-
OSPData[] nodesPackedTile Optionally provided instead of `node.data`, for
916-
each attribute a single array of all tile node
917-
data in a contiguous layout, provided in the same
918-
order as the corresponding `node.*` parameters.
919-
This packed layout may be more performant.
908+
OSPData nodesPackedDense optionally provided instead of `node.data`, a
909+
single array of all dense node data in a
910+
contiguous zyx layout, provided in the same order
911+
as the corresponding `node.*` parameters
912+
913+
OSPData nodesPackedTile optionally provided instead of `node.data`, a
914+
single array of all tile node data in a
915+
contiguous layout, provided in the same order as
916+
the corresponding `node.*` parameters
917+
918+
uint32[] node.format for each input node, whether it is of format
919+
`OSP_VOLUME_FORMAT_DENSE_ZYX` (and thus stored in
920+
`nodesPackedDense`), or `OSP_VOLUME_FORMAT_TILE`
921+
(stored in `nodesPackedTile`)
920922

921923
int filter filter used for reconstructing the field, default
922924
is `OSP_VOLUME_FILTER_TRILINEAR`, alternatively
@@ -926,14 +928,14 @@ VDB volumes have the following parameters:
926928
int gradientFilter filter used for reconstructing the field during
927929
gradient computations, default same as `filter`
928930

929-
float background value that is used when sampling an undefined region
930-
outside the volume domain, default `NaN`
931+
float background value that is used when sampling an undefined
932+
region outside the volume domain, default `NaN`
931933
---------- ----------------- -------------------------------------------------
932934
: Configuration parameters for VDB volumes.
933935

934-
The `nodesPackedDense` and `nodesPackedTile` parameters may be provided
935-
instead of `node.data`; this packed data layout may provide better
936-
performance.
936+
The `nodesPackedDense` and `nodesPackedTile` together with `node.format`
937+
parameters may be provided instead of `node.data`; this packed data
938+
layout may provide better performance.
937939

938940

939941
1. Museth, K. VDB: High-Resolution Sparse Volumes with Dynamic Topology.

modules/cpu/common/World.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ void World::commit()
126126
addGeometryInstance(
127127
esClip, inst->group->sceneClippers, inst, embreeDevice, id);
128128
id++;
129-
}
130129
}
130+
}
131131

132132
if (esGeom) {
133133
rtcSetSceneFlags(esGeom, static_cast<RTCSceneFlags>(sceneFlags));

modules/cpu/volume/Volume.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ void Volume::handleParams()
191191
vklSetVec3i(vklVolume, "dimensions", dim.x, dim.y, dim.z);
192192
vklSetInt(vklVolume, "voxelType", (VKLDataType)data->type);
193193
}
194+
if (name == "nodesPackedDense" || name == "nodesPackedTile") {
195+
// packed VDB volumes: wrap attribute
196+
VKLData vklDataWrapper = vklNewData(vklDevice, 1, VKL_DATA, &vklData);
197+
vklRelease(vklData);
198+
vklData = vklDataWrapper;
199+
}
194200
vklSetData(vklVolume, name.c_str(), vklData);
195201
vklRelease(vklData);
196202
}

ospray/include/ospray/OSPEnums.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ typedef enum
349349
OSP_AMR_OCTANT
350350
} OSPAMRMethod;
351351

352-
// Filter modes that can be set on 'VDB' type OSPVolume, compatible with VKL
352+
// Filter modes for VDB and structured volumes, compatible with VKL
353353
typedef enum
354354
#if __cplusplus >= 201103L
355355
: uint32_t
@@ -360,6 +360,16 @@ typedef enum
360360
OSP_VOLUME_FILTER_TRICUBIC = 200 // tricubic interpolation
361361
} OSPVolumeFilter;
362362

363+
// VDB node data format
364+
typedef enum
365+
#if __cplusplus > 201103L
366+
: uint32_t
367+
#endif
368+
{
369+
OSP_VOLUME_FORMAT_TILE = 0, // node with no spatial variation.
370+
OSP_VOLUME_FORMAT_DENSE_ZYX // a dense grid of voxels in zyx layout
371+
} OSPVolumeFormat;
372+
363373
// OSPRay pixel filter types
364374
typedef enum
365375
#if __cplusplus >= 201103L

ospray/include/ospray/ospray_cpp/Traits.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ OSPTYPEFOR_SPECIALIZATION(OSPAMRMethod, OSP_UCHAR);
7878
OSPTYPEFOR_SPECIALIZATION(OSPSubdivisionMode, OSP_UCHAR);
7979
OSPTYPEFOR_SPECIALIZATION(OSPPixelFilterTypes, OSP_UCHAR);
8080
OSPTYPEFOR_SPECIALIZATION(OSPIntensityQuantity, OSP_UCHAR);
81+
OSPTYPEFOR_SPECIALIZATION(OSPVolumeFormat, OSP_UINT);
8182

8283
#define OSPTYPEFOR_DEFINITION(type) \
8384
constexpr OSPDataType OSPTypeFor<type>::value

0 commit comments

Comments
 (0)