Commit: 9f4e5581d18899d665d61e93ae7c6933c5a3e770 Author: Geraldine Chua Date: Sun Aug 12 23:33:52 2018 +0800 Branches: soc-2018-cycles-volumes https://developer.blender.org/rB9f4e5581d18899d665d61e93ae7c6933c5a3e770
OpenVDB import to padded sparse grids. =================================================================== M intern/cycles/render/image.cpp M intern/cycles/render/openvdb.cpp M intern/cycles/render/openvdb.h =================================================================== diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 4c987957bb4..97302095e33 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -702,19 +702,28 @@ void ImageManager::file_load_extern_vdb(Device *device, return; } + const bool use_pad = (device->info.type == DEVICE_CUDA); int sparse_size = -1; vector<int> sparse_offsets; openvdb_load_preprocess(img->filename, img->grid_name, img->isovalue, - &sparse_offsets, sparse_size); + use_pad, &sparse_offsets, sparse_size); /* Allocate space for image. */ float *pixels; { thread_scoped_lock device_lock(device_mutex); - if(sparse_size > -1) { + if(use_pad && sparse_size > -1) { + tex_img->grid_type = IMAGE_GRID_TYPE_SPARSE_PAD; + int width = sparse_size / (PADDED_TILE * PADDED_TILE * + (type == IMAGE_DATA_TYPE_FLOAT4 ? 4 : 1)); + pixels = (float*)tex_img->alloc(width, PADDED_TILE, PADDED_TILE); + } + else if(sparse_size > -1) { + tex_img->grid_type = IMAGE_GRID_TYPE_SPARSE; pixels = (float*)tex_img->alloc(sparse_size); } else { + tex_img->grid_type = IMAGE_GRID_TYPE_DEFAULT; pixels = (float*)tex_img->alloc(img->metadata.width, img->metadata.height, img->metadata.depth); @@ -728,21 +737,17 @@ void ImageManager::file_load_extern_vdb(Device *device, } /* Load image. */ - openvdb_load_image(img->filename, img->grid_name, pixels, &sparse_offsets); + openvdb_load_image(img->filename, img->grid_name, &sparse_offsets, + sparse_size, use_pad, pixels); /* Allocate space for sparse_index if it exists. */ if(sparse_size > -1) { - tex_img->grid_type = IMAGE_GRID_TYPE_SPARSE; - if(!allocate_grid_info(device, (device_memory*)tex_img, &sparse_offsets)) { /* Could be that we've run out of memory. */ file_load_failed<DeviceType>(img, type, tex_img); return; } } - else { - tex_img->grid_type = IMAGE_GRID_TYPE_DEFAULT; - } /* Set metadata and copy. */ tex_img->dense_width = img->metadata.width; diff --git a/intern/cycles/render/openvdb.cpp b/intern/cycles/render/openvdb.cpp index a3dba94c6b3..a3b6330a891 100644 --- a/intern/cycles/render/openvdb.cpp +++ b/intern/cycles/render/openvdb.cpp @@ -244,7 +244,7 @@ bool validate_and_process_grid(typename GridType::Ptr &grid, return true; } -/* Load OpenVDB grid to texture. */ +/* Load OpenVDB grid to texture. Based on util/util_sparse_grid.h */ template<typename GridType, typename T> void image_load_preprocess(openvdb::GridBase::Ptr grid_base, @@ -252,6 +252,7 @@ void image_load_preprocess(openvdb::GridBase::Ptr grid_base, const openvdb::math::Coord min_bound, const int channels, const float threshold, + const bool use_pad, vector<int> *sparse_indexes, int &sparse_size) { @@ -269,6 +270,8 @@ void image_load_preprocess(openvdb::GridBase::Ptr grid_base, } const int tile_count = coord_product(tiled_res); + + /* Initial prepass to find active tiles. */ sparse_indexes->resize(tile_count, -1); /* 0 if active, -1 if inactive. */ int voxel_count = 0; @@ -280,21 +283,51 @@ void image_load_preprocess(openvdb::GridBase::Ptr grid_base, if(gte_any(data[i], threshold)) { const math::Coord tile_start = leaf->getNodeBoundingBox().getStart(); sparse_indexes->at(get_tile_index(tile_start, tiled_res)) = voxel_count; - /* Calculate how many voxels are in this tile. */ - voxel_count += coord_product(get_tile_dim(tile_start, resolution, remainder)); + if(!use_pad) { + /* Calculate how many voxels are in this tile. */ + voxel_count += coord_product(get_tile_dim(tile_start, resolution, remainder)); + } break; } } } + if(use_pad) { + /* Second prepass to find sparse image dimensions and total number of voxels. */ + int data_width = 0/*, tile = 0*/; + const int data_height = PADDED_TILE; + const int data_depth = PADDED_TILE; + + for(int tile = 0; tile < tile_count; ++tile) { + if(sparse_indexes->at(tile) < 0) { + continue; + } + sparse_indexes->at(tile) = data_width; + int x = (tile % tiled_res.x()) * TILE_SIZE; + int2 bound_x = padded_tile_bound(sparse_indexes, x, + resolution.x(), tile); + data_width += bound_x.y - bound_x.x; + } + + voxel_count = data_width * data_height * data_depth; + } + /* Check memory savings. */ const int sparse_mem_use = tile_count * sizeof(int) + voxel_count * channels * sizeof(float); const int dense_mem_use = coord_product(resolution) * channels * sizeof(float); - VLOG(1) << grid->getName() << " memory usage: \n" - << "Dense: " << string_human_readable_size(dense_mem_use) << "\n" - << "Sparse: " << string_human_readable_size(sparse_mem_use) << "\n" - << "VDB Grid: " << string_human_readable_size(grid->memUsage()); + if(use_pad) { + VLOG(1) << grid->getName() << " memory usage:" + << "\nDense Grid: " << string_human_readable_size(dense_mem_use) + << "\nPadded Sparse Grid: " << string_human_readable_size(sparse_mem_use) + << "\nVDB Grid: " << string_human_readable_size(grid->memUsage()); + } + else { + VLOG(1) << grid->getName() << " memory usage:" + << "\nDense Grid: " << string_human_readable_size(dense_mem_use) + << "\nSparse Grid: " << string_human_readable_size(sparse_mem_use) + << "\nVDB Grid: " << string_human_readable_size(grid->memUsage()); + } if(sparse_mem_use < dense_mem_use) { sparse_size = voxel_count * channels; @@ -352,11 +385,11 @@ void image_load_dense(openvdb::GridBase::Ptr grid_base, template<typename GridType, typename T> void image_load_sparse(openvdb::GridBase::Ptr grid_base, + const vector<int> *sparse_indexes, const openvdb::math::Coord resolution, const openvdb::math::Coord min_bound, const int channels, - float *data, - vector<int> *sparse_indexes) + float *data) { using namespace openvdb; @@ -399,6 +432,77 @@ void image_load_sparse(openvdb::GridBase::Ptr grid_base, } } +template<typename GridType, typename T> +void image_load_sparse_pad(openvdb::GridBase::Ptr grid_base, + const vector<int> *sparse_indexes, + const openvdb::math::Coord resolution, + const openvdb::math::Coord min_bound, + const int channels, + const int sparse_size, + float *data) +{ + using namespace openvdb; + + typename GridType::Ptr grid = gridPtrCast<GridType>(grid_base); + if(!validate_and_process_grid<GridType, T>(grid, min_bound)) { + return; + } + + math::Coord tiled_res; + for(int i = 0; i < 3; ++i) { + tiled_res[i] = get_tile_res(resolution[i]); + } + + /* Resolution of "data" (sparse grid). */ + const int data_depth = PADDED_TILE; + const int data_height = PADDED_TILE; + const int data_width = sparse_size / (data_depth * data_height * channels); + + typename GridType::ConstAccessor accessor = grid->getConstAccessor(); + math::Coord voxel_coord; + + for (typename GridType::TreeType::LeafCIter iter = grid->tree().cbeginLeaf(); iter; ++iter) { + const typename GridType::TreeType::LeafNodeType *leaf = iter.getLeaf(); + + const math::Coord tile_start = leaf->getNodeBoundingBox().getStart(); + const int tile_index = get_tile_index(tile_start, tiled_res); + const int start_x = sparse_indexes->at(tile_index); + if(start_x < 0) { + continue; + } + + const T *leaf_tile = leaf->buffer().data(); + const int2 bound_x = padded_tile_bound(sparse_indexes, tile_start.x(), + resolution.x(), tile_index); + + for(int k = -SPARSE_PAD; k < TILE_SIZE + SPARSE_PAD; ++k) { + for(int j = -SPARSE_PAD; j < TILE_SIZE + SPARSE_PAD; ++j) { + for(int i = bound_x.x; i < bound_x.y; ++i) { + int data_index = compute_index(i - bound_x.x + start_x, + j + SPARSE_PAD, + k + SPARSE_PAD, + data_width, + data_height) * channels; + + if(i < 0 || j < 0 || k < 0 || + i >= TILE_SIZE || j >= TILE_SIZE || k >= TILE_SIZE) + { + /* Voxel is not in leaf */ + voxel_coord.setX(i + tile_start.x()); + voxel_coord.setY(j + tile_start.y()); + voxel_coord.setZ(k + tile_start.z()); + copy(data + data_index, &accessor.getValue(voxel_coord)); + } + else { + int leaf_index = compute_index(k, j, i, TILE_SIZE, TILE_SIZE); + copy(data + data_index, leaf_tile + leaf_index); + } + } + } + } + } +} + } /* namespace */ /* Initializer, must be called if OpenVDB will be used. */ @@ -436,6 +540,7 @@ int3 openvdb_get_resolution(const string& filepath) void openvdb_load_preprocess(const string& filepath, const string& grid_name, const float threshold, + const bool use_pad, vector<int> *sparse_indexes, int &sparse_size) { @@ -452,35 +557,35 @@ void openvdb_load_preprocess(const string& filepath, switch(grid_type) { case OPENVDB_GRID_BOOL: return image_load_preprocess<BoolGrid, unsigned long int>( - grid, resolution, min_bound, 1, threshold, + grid, resolution, min_bound, 1, threshold, use_pad, sparse_indexes, sparse_size); case OPENVDB_GRID_DOUBLE: return image_load_preprocess<DoubleGrid, double>( - grid, resolution, min_bound, 1, threshold, + grid, resolution, min_bound, 1, threshold, use_pad, sparse_indexes, sparse_size); case OPENVDB_GRID_FLOAT: return image_load_preprocess<FloatGrid, float>( - grid, res @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs