Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/CMakeLists.txt11
-rw-r--r--intern/cycles/app/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/CMakeLists.txt14
-rw-r--r--intern/cycles/blender/blender_geometry.cpp7
-rw-r--r--intern/cycles/blender/blender_object.cpp10
-rw-r--r--intern/cycles/blender/blender_sync.cpp5
-rw-r--r--intern/cycles/blender/blender_volume.cpp140
-rw-r--r--intern/cycles/render/CMakeLists.txt23
-rw-r--r--intern/cycles/render/image_vdb.cpp188
-rw-r--r--intern/cycles/render/image_vdb.h56
-rw-r--r--intern/cycles/test/CMakeLists.txt2
11 files changed, 429 insertions, 28 deletions
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 6d4d2e38e82..024a94ea437 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -350,17 +350,6 @@ if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
endif()
-if(WITH_OPENCOLORIO)
- add_definitions(-DWITH_OCIO)
- include_directories(
- SYSTEM
- ${OPENCOLORIO_INCLUDE_DIRS}
- )
- if(WIN32)
- add_definitions(-DOpenColorIO_STATIC)
- endif()
-endif()
-
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
add_subdirectory(app)
endif()
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 199ab8ce316..ef374f91a65 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -60,6 +60,7 @@ link_directories(
${TIFF_LIBPATH}
${OPENEXR_LIBPATH}
${OPENJPEG_LIBPATH}
+ ${OPENVDB_LIBPATH}
)
if(WITH_OPENCOLORIO)
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index ae191b6c0f7..496e8e9310b 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -92,6 +92,20 @@ if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()
+if(WITH_NEW_OBJECT_TYPES)
+ add_definitions(-DWITH_NEW_OBJECT_TYPES)
+endif()
+
+if(WITH_OPENVDB)
+ add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
+ list(APPEND INC_SYS
+ ${OPENVDB_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${OPENVDB_LIBRARIES}
+ )
+endif()
+
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# avoid link failure with clang 3.4 debug
diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp
index e2a4a125ca1..ac5bae4bc66 100644
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@ -38,7 +38,8 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
GeometryKey key(b_key_id.ptr.data, use_particle_hair);
BL::Material material_override = view_layer.material_override;
- Shader *default_shader = scene->default_surface;
+ Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
+ scene->default_surface;
Geometry::Type geom_type = (use_particle_hair &&
(scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
Geometry::HAIR :
@@ -124,7 +125,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
if (use_particle_hair) {
sync_hair(b_depsgraph, b_ob, geom, used_shaders);
}
- else if (object_fluid_gas_domain_find(b_ob)) {
+ else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_volume(b_ob, mesh, used_shaders);
}
@@ -164,7 +165,7 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
if (use_particle_hair) {
sync_hair_motion(b_depsgraph, b_ob, geom, motion_step);
}
- else if (object_fluid_gas_domain_find(b_ob)) {
+ else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
/* No volume motion blur support yet. */
}
else {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 334c25cafe1..48d309c259b 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -67,10 +67,16 @@ bool BlenderSync::object_is_mesh(BL::Object &b_ob)
return false;
}
- if (b_ob.type() == BL::Object::type_CURVE) {
+ BL::Object::type_enum type = b_ob.type();
+
+ if (type == BL::Object::type_VOLUME) {
+ /* Will be exported attached to mesh. */
+ return true;
+ }
+ else if (type == BL::Object::type_CURVE) {
/* Skip exporting curves without faces, overhead can be
* significant if there are many for path animation. */
- BL::Curve b_curve(b_ob.data());
+ BL::Curve b_curve(b_ob_data);
return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 4529c6a2798..3d932825ae7 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -178,6 +178,11 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
world_recalc = true;
}
}
+ /* Volume */
+ else if (b_id.is_a(&RNA_Volume)) {
+ BL::Volume b_volume(b_id);
+ geometry_map.set_recalc(b_volume);
+ }
}
BlenderViewportParameters new_viewport_parameters(b_v3d);
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 7f393fcb819..ee64796b393 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -16,12 +16,19 @@
#include "render/colorspace.h"
#include "render/image.h"
+#include "render/image_vdb.h"
#include "render/mesh.h"
#include "render/object.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
+ struct VolumeGrid *grid);
+#endif
+
CCL_NAMESPACE_BEGIN
/* TODO: verify this is not loading unnecessary attributes. */
@@ -210,19 +217,121 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
attr->data_voxel() = scene->image_manager->add_image(loader, params);
}
+}
- /* Create a matrix to transform from object space to mesh texture space.
- * This does not work with deformations but that can probably only be done
- * well with a volume grid mapping of coordinates. */
- if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
- Transform *tfm = attr->data_transform();
+class BlenderVolumeLoader : public VDBImageLoader {
+ public:
+ BlenderVolumeLoader(BL::Volume b_volume, const string &grid_name)
+ : VDBImageLoader(grid_name),
+ b_volume(b_volume),
+ b_volume_grid(PointerRNA_NULL),
+ unload(false)
+ {
+#ifdef WITH_OPENVDB
+ /* Find grid with matching name. */
+ BL::Volume::grids_iterator b_grid_iter;
+ for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
+ if (b_grid_iter->name() == grid_name) {
+ b_volume_grid = *b_grid_iter;
+ }
+ }
+#endif
+ }
- BL::Mesh b_mesh(b_ob.data());
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
+ bool load_metadata(ImageMetaData &metadata) override
+ {
+ if (!b_volume_grid) {
+ return false;
+ }
+
+ unload = !b_volume_grid.is_loaded();
+
+#ifdef WITH_OPENVDB
+ Volume *volume = (Volume *)b_volume.ptr.data;
+ VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
+ grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
+#endif
+
+ return VDBImageLoader::load_metadata(metadata);
+ }
+
+ bool load_pixels(const ImageMetaData &metadata,
+ void *pixels,
+ const size_t pixel_size,
+ const bool associate_alpha) override
+ {
+ if (!b_volume_grid) {
+ return false;
+ }
+
+ return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
+ }
- *tfm = transform_translate(-loc) * transform_scale(size);
+ bool equals(const ImageLoader &other) const override
+ {
+ /* TODO: detect multiple volume datablocks with the same filepath. */
+ const BlenderVolumeLoader &other_loader = (const BlenderVolumeLoader &)other;
+ return b_volume == other_loader.b_volume && b_volume_grid == other_loader.b_volume_grid;
+ }
+
+ void cleanup() override
+ {
+ VDBImageLoader::cleanup();
+ if (b_volume_grid && unload) {
+ b_volume_grid.unload();
+ }
+ }
+
+ BL::Volume b_volume;
+ BL::VolumeGrid b_volume_grid;
+ bool unload;
+};
+
+static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
+{
+ BL::Volume b_volume(b_ob.data());
+ b_volume.grids.load(b_data.ptr.data);
+
+ mesh->volume_isovalue = 1e-3f; /* TODO: make user setting. */
+
+ /* Find grid with matching name. */
+ BL::Volume::grids_iterator b_grid_iter;
+ for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
+ BL::VolumeGrid b_grid = *b_grid_iter;
+ ustring name = ustring(b_grid.name());
+ AttributeStandard std = ATTR_STD_NONE;
+
+ if (name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
+ std = ATTR_STD_VOLUME_DENSITY;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
+ std = ATTR_STD_VOLUME_COLOR;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
+ std = ATTR_STD_VOLUME_FLAME;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
+ std = ATTR_STD_VOLUME_HEAT;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
+ std = ATTR_STD_VOLUME_TEMPERATURE;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
+ std = ATTR_STD_VOLUME_VELOCITY;
+ }
+
+ if ((std != ATTR_STD_NONE && mesh->need_attribute(scene, std)) ||
+ mesh->need_attribute(scene, name)) {
+ Attribute *attr = (std != ATTR_STD_NONE) ?
+ mesh->attributes.add(std) :
+ mesh->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
+
+ ImageLoader *loader = new BlenderVolumeLoader(b_volume, name.string());
+ ImageParams params;
+ params.frame = b_volume.grids.frame();
+
+ attr->data_voxel() = scene->image_manager->add_image(loader, params);
+ }
}
}
@@ -246,9 +355,16 @@ void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh, const vector<Shader
mesh->clear();
mesh->used_shaders = used_shaders;
- /* Smoke domain. */
if (view_layer.use_volumes) {
- sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
+ if (b_ob.type() == BL::Object::type_VOLUME) {
+ /* Volume object. Create only attributes, bounding mesh will then
+ * be automatically generated later. */
+ sync_volume_object(b_data, b_ob, scene, mesh);
+ }
+ else {
+ /* Smoke domain. */
+ sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
+ }
}
/* Tag update. */
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 9922547a8d2..472b5a0c101 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
hair.cpp
image.cpp
image_oiio.cpp
+ image_vdb.cpp
integrator.cpp
jitter.cpp
light.cpp
@@ -63,6 +64,7 @@ set(SRC_HEADERS
hair.h
image.h
image_oiio.h
+ image_vdb.h
integrator.h
light.h
jitter.h
@@ -98,6 +100,27 @@ if(WITH_CYCLES_OSL)
SET_PROPERTY(SOURCE osl.cpp PROPERTY COMPILE_FLAGS ${RTTI_DISABLE_FLAGS})
endif()
+if(WITH_OPENCOLORIO)
+ add_definitions(-DWITH_OCIO)
+ include_directories(
+ SYSTEM
+ ${OPENCOLORIO_INCLUDE_DIRS}
+ )
+ if(WIN32)
+ add_definitions(-DOpenColorIO_STATIC)
+ endif()
+endif()
+
+if(WITH_OPENVDB)
+ add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
+ list(APPEND INC_SYS
+ ${OPENVDB_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${OPENVDB_LIBRARIES}
+ )
+endif()
+
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
diff --git a/intern/cycles/render/image_vdb.cpp b/intern/cycles/render/image_vdb.cpp
new file mode 100644
index 00000000000..500131c2d84
--- /dev/null
+++ b/intern/cycles/render/image_vdb.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "render/image_vdb.h"
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/Dense.h>
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+VDBImageLoader::VDBImageLoader(const string &grid_name) : grid_name(grid_name)
+{
+}
+
+VDBImageLoader::~VDBImageLoader()
+{
+}
+
+bool VDBImageLoader::load_metadata(ImageMetaData &metadata)
+{
+#ifdef WITH_OPENVDB
+ if (!grid) {
+ return false;
+ }
+
+ bbox = grid->evalActiveVoxelBoundingBox();
+ if (bbox.empty()) {
+ return false;
+ }
+
+ /* Set dimensions. */
+ openvdb::Coord dim = bbox.dim();
+ openvdb::Coord min = bbox.min();
+ metadata.width = dim.x();
+ metadata.height = dim.y();
+ metadata.depth = dim.z();
+
+ /* Set data type. */
+ if (grid->isType<openvdb::FloatGrid>()) {
+ metadata.channels = 1;
+ }
+ else if (grid->isType<openvdb::Vec3fGrid>()) {
+ metadata.channels = 3;
+ }
+ else if (grid->isType<openvdb::BoolGrid>()) {
+ metadata.channels = 1;
+ }
+ else if (grid->isType<openvdb::DoubleGrid>()) {
+ metadata.channels = 1;
+ }
+ else if (grid->isType<openvdb::Int32Grid>()) {
+ metadata.channels = 1;
+ }
+ else if (grid->isType<openvdb::Int64Grid>()) {
+ metadata.channels = 1;
+ }
+ else if (grid->isType<openvdb::Vec3IGrid>()) {
+ metadata.channels = 3;
+ }
+ else if (grid->isType<openvdb::Vec3dGrid>()) {
+ metadata.channels = 3;
+ }
+ else if (grid->isType<openvdb::MaskGrid>()) {
+ metadata.channels = 1;
+ }
+ else {
+ return false;
+ }
+
+ if (metadata.channels == 1) {
+ metadata.type = IMAGE_DATA_TYPE_FLOAT;
+ }
+ else {
+ metadata.type = IMAGE_DATA_TYPE_FLOAT4;
+ }
+
+ /* Set transform from object space to voxel index. */
+ openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4();
+ Transform index_to_object;
+ for (int col = 0; col < 4; col++) {
+ for (int row = 0; row < 3; row++) {
+ index_to_object[row][col] = (float)grid_matrix[col][row];
+ }
+ }
+
+ Transform texture_to_index = transform_translate(min.x(), min.y(), min.z()) *
+ transform_scale(dim.x(), dim.y(), dim.z());
+
+ metadata.transform_3d = transform_inverse(index_to_object * texture_to_index);
+ metadata.use_transform_3d = true;
+
+ return true;
+#else
+ (void)metadata;
+ return false;
+#endif
+}
+
+bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool)
+{
+#ifdef WITH_OPENVDB
+ if (grid->isType<openvdb::FloatGrid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::Vec3fGrid>()) {
+ openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
+ bbox, (openvdb::Vec3f *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::BoolGrid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::DoubleGrid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::Int32Grid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::Int64Grid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::Vec3IGrid>()) {
+ openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
+ bbox, (openvdb::Vec3f *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::Vec3dGrid>()) {
+ openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
+ bbox, (openvdb::Vec3f *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid), dense);
+ }
+ else if (grid->isType<openvdb::MaskGrid>()) {
+ openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
+ openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::MaskGrid>(grid), dense);
+ }
+
+ return true;
+#else
+ (void)pixels;
+ return false;
+#endif
+}
+
+string VDBImageLoader::name() const
+{
+ return grid_name;
+}
+
+bool VDBImageLoader::equals(const ImageLoader &other) const
+{
+#ifdef WITH_OPENVDB
+ const VDBImageLoader &other_loader = (const VDBImageLoader &)other;
+ return grid == other_loader.grid;
+#else
+ (void)other;
+ return true;
+#endif
+}
+
+void VDBImageLoader::cleanup()
+{
+#ifdef WITH_OPENVDB
+ /* Free OpenVDB grid memory as soon as we can. */
+ grid.reset();
+#endif
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image_vdb.h b/intern/cycles/render/image_vdb.h
new file mode 100644
index 00000000000..7dec63b11e6
--- /dev/null
+++ b/intern/cycles/render/image_vdb.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IMAGE_VDB__
+#define __IMAGE_VDB__
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+#endif
+
+#include "render/image.h"
+
+CCL_NAMESPACE_BEGIN
+
+class VDBImageLoader : public ImageLoader {
+ public:
+ VDBImageLoader(const string &grid_name);
+ ~VDBImageLoader();
+
+ virtual bool load_metadata(ImageMetaData &metadata) override;
+
+ virtual bool load_pixels(const ImageMetaData &metadata,
+ void *pixels,
+ const size_t pixels_size,
+ const bool associate_alpha) override;
+
+ virtual string name() const override;
+
+ virtual bool equals(const ImageLoader &other) const override;
+
+ virtual void cleanup() override;
+
+ protected:
+ string grid_name;
+#ifdef WITH_OPENVDB
+ openvdb::GridBase::ConstPtr grid;
+ openvdb::CoordBBox bbox;
+#endif
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __IMAGE_VDB__ */
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index ab7a9c75e17..6dcc7f7b3dd 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -82,6 +82,7 @@ list(APPEND ALL_CYCLES_LIBRARIES
${TIFF_LIBRARY}
${OPENIMAGEIO_LIBRARIES}
${OPENEXR_LIBRARIES}
+ ${OPENVDB_LIBRARIES}
)
include_directories(${INC})
@@ -95,6 +96,7 @@ link_directories(
${TIFF_LIBPATH}
${OPENEXR_LIBPATH}
${OPENCOLORIO_LIBPATH}
+ ${OPENVDB_LIBPATH}
)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")