Files
workinf_Blender_Wasm/blender-5.2.0/intern/cycles/scene/volume.h
2026-08-12 04:47:48 -04:00

107 lines
3.2 KiB
C++

/* SPDX-FileCopyrightText: 2020-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#include "graph/node.h"
#include "scene/mesh.h"
#ifdef WITH_OPENVDB
# include <openvdb/openvdb.h>
#endif
CCL_NAMESPACE_BEGIN
class Object;
class Octree;
class Volume : public Mesh {
public:
NODE_DECLARE
Volume();
NODE_SOCKET_API(float, step_size)
NODE_SOCKET_API(bool, object_space)
NODE_SOCKET_API(float, velocity_scale)
/* Merge attributes for efficiency, call right after creating them. */
void merge_grids(const Scene *scene);
void clear(bool preserve_shaders = false) override;
};
class VolumeManager {
public:
VolumeManager();
~VolumeManager();
void device_update(Device *, DeviceScene *, const Scene *, Progress &);
void device_free(DeviceScene *);
/* Tag volume octree for update when scene changes. */
void tag_update();
void tag_update(const Shader *shader);
void tag_update(const set<Object *> &objects, const uint32_t flag);
void tag_update(const set<Geometry *> &geometry);
void tag_update_indices();
void tag_update_algorithm();
/* Check whether the shader is a homogeneous volume. */
static bool is_homogeneous_volume(const Object *, const Shader *);
bool need_update_step_size;
private:
/* Initialize octrees from the volumes in the scene. */
void initialize_octree(const Scene *, Progress &);
/* Build octrees based on the volume density. */
void build_octree(Device *, Progress &);
/* Update the object and shader index of octree root nodes. */
void update_root_indices(DeviceScene *, const Scene *) const;
/* Converting the octrees into an array for uploading to the kernel. */
void flatten_octree(DeviceScene *, const Scene *) const;
/* Count all the nodes of the octrees. */
void update_num_octree_nodes();
int num_octree_nodes() const;
int num_octree_roots() const;
/* When running Blender with environment variable `CYCLES_VOLUME_OCTREE_DUMP`, an octree
* visualization is written to `filename`, which is a Python script that can be run inside
* Blender. */
std::string visualize_octree(const char *filename) const;
/* Step size for ray marching. */
void update_step_size(const Scene *, DeviceScene *, Progress &progress);
/* One octree per object per shader. */
std::map<std::pair<const Object *, const Shader *>, std::shared_ptr<Octree>> object_octrees_;
/* TODO(weizhen): replace booleans with enum `update_flags`? */
bool update_root_indices_ = false;
bool need_rebuild_;
bool update_visualization_ = false;
bool algorithm_modified_ = true;
int num_octree_nodes_;
int num_octree_roots_;
#ifdef WITH_OPENVDB
/* Create SDF grid for mesh volumes, to determine whether a certain point is in the
* interior of the mesh. This reduces evaluation time needed for heterogeneous volume. */
openvdb::BoolGrid::ConstPtr mesh_to_sdf_grid(const Mesh *mesh,
const Shader *shader,
const float half_width);
openvdb::BoolGrid::ConstPtr get_vdb(const Geometry *, const Shader *) const;
std::map<std::pair<const Geometry *, const Shader *>, openvdb::BoolGrid::ConstPtr> vdb_map_;
#endif
};
CCL_NAMESPACE_END