36#include "RNA_prototypes.hh"
41# include <openvdb/openvdb.h>
42# include <openvdb/tools/Interpolation.h>
43# include <openvdb/tools/Morphology.h>
44# include <openvdb/tools/Prune.h>
45# include <openvdb/tools/ValueTransformer.h>
82 walk(user_data, ob, md, &
ptr, prop);
104 uiTemplateID(layout, C,
ptr,
"texture",
"texture.new",
nullptr,
nullptr);
130 openvdb::Mat4s new_matrix{m.
base_ptr()};
134template<
typename Gr
idType>
struct DisplaceOp {
136 typename GridType::ConstAccessor accessor;
137 const openvdb::Mat4s index_to_texture;
140 const double strength;
141 const openvdb::Vec3d texture_mid_level;
143 void operator()(
const typename GridType::ValueOnIter &iter)
const
145 const openvdb::Coord coord = iter.getCoord();
146 const openvdb::Vec3d displace_vector = this->compute_displace_vector(coord);
149 const openvdb::Vec3d sample_coord = coord.asVec3d() - displace_vector;
150 const auto new_value = openvdb::tools::BoxSampler::sample(this->accessor, sample_coord);
151 iter.setValue(new_value);
154 openvdb::Vec3d compute_displace_vector(
const openvdb::Coord &coord)
const
156 if (this->texture !=
nullptr) {
157 const openvdb::Vec3f texture_pos = coord.asVec3s() * this->index_to_texture;
158 const openvdb::Vec3d texture_value = this->evaluate_texture(texture_pos);
159 const openvdb::Vec3d displacement = (texture_value - this->texture_mid_level) *
163 return openvdb::Vec3d{0, 0, 0};
166 openvdb::Vec3d evaluate_texture(
const openvdb::Vec3f &
pos)
const
170 return {texture_result.
trgba[0], texture_result.
trgba[1], texture_result.
trgba[2]};
174static float get_max_voxel_side_length(
const openvdb::GridBase &grid)
176 const openvdb::Vec3d voxel_size = grid.voxelSize();
177 const float max_voxel_side_length = std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
178 return max_voxel_side_length;
181struct DisplaceGridOp {
183 openvdb::GridBase &base_grid;
190 if constexpr (blender::
191 is_same_any_v<GridType, openvdb::points::PointDataGrid, openvdb::MaskGrid>)
197 this->displace_grid<GridType>();
201 template<
typename Gr
idType>
void displace_grid()
203 GridType &grid =
static_cast<GridType &
>(base_grid);
206 typename GridType::Ptr temp_grid = grid.deepCopy();
210 const float max_voxel_side_length = get_max_voxel_side_length(grid);
212 max_voxel_side_length / 2.0f;
213 openvdb::tools::dilateActiveValues(temp_grid->tree(),
214 int(std::ceil(sample_radius)),
215 openvdb::tools::NN_FACE_EDGE,
216 openvdb::tools::EXPAND_TILES);
218 const openvdb::Mat4s index_to_texture = this->get_index_to_texture_transform();
221 DisplaceOp<GridType> displace_op{grid.getConstAccessor(),
224 vdmd.
strength / max_voxel_side_length,
229 openvdb::tools::foreach (temp_grid->beginValueOn(),
237 typename GridType::ValueType prune_tolerance{0};
238 openvdb::tools::deactivate(*temp_grid, temp_grid->background(), prune_tolerance);
239 openvdb::tools::prune(temp_grid->tree());
243 grid.merge(*temp_grid);
246 openvdb::Mat4s get_index_to_texture_transform()
const
248 const openvdb::Mat4s index_to_object{
249 base_grid.transform().baseMap()->getAffineMap()->getMat4()};
253 return index_to_object;
256 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->object_to_world());
257 return index_to_object * object_to_world;
261 return index_to_object;
263 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->object_to_world());
264 const openvdb::Mat4s world_to_texture = matrix_to_openvdb(
266 return index_to_object * object_to_world * world_to_texture;
284 for (
int grid_index = 0; grid_index < grid_amount; grid_index++) {
288 blender::bke::VolumeTreeAccessToken tree_token;
289 openvdb::GridBase &grid = volume_grid->grid_for_write(tree_token);
292 DisplaceGridOp displace_grid_op{grid, *vdmd, *ctx};
293 BKE_volume_grid_type_operation(grid_type, displace_grid_op);
307 if (input_volume !=
nullptr) {
314 N_(
"Volume Displace"),
315 "VolumeDisplaceModifierData",
317 &RNA_VolumeDisplaceModifier,
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
void(*)(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop) TexWalkFunc
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_texture_get_value(struct Tex *texture, const float *tex_co, struct TexResult *texres, bool use_color_management)
bool BKE_texture_dependsOnTime(const struct Tex *texture)
int BKE_volume_num_grids(const Volume *volume)
bool BKE_volume_load(const Volume *volume, const Main *bmain)
blender::bke::VolumeGridData * BKE_volume_grid_get_for_write(Volume *volume, int grid_index)
MINLINE void copy_v3_fl(float r[3], float f)
void DEG_add_generic_id_relation(DepsNodeHandle *node_handle, ID *id, const char *description)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
Main * DEG_get_bmain(const Depsgraph *graph)
struct VolumeDisplaceModifierData VolumeDisplaceModifierData
@ eModifierType_VolumeDisplace
@ MOD_VOLUME_DISPLACE_MAP_GLOBAL
@ MOD_VOLUME_DISPLACE_MAP_LOCAL
@ MOD_VOLUME_DISPLACE_MAP_OBJECT
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
ModifierTypeInfo modifierType_VolumeDisplace
static bool depends_on_time(Scene *, ModifierData *md)
static void displace_volume(ModifierData *md, const ModifierEvalContext *ctx, Volume *volume)
static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
static void panel_draw(const bContext *C, Panel *panel)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter=UI_TEMPLATE_ID_FILTER_ALL, bool live_icon=false, const char *text=nullptr)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
local_group_size(16, 16) .push_constant(Type texture
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
float texture_mid_level[3]
float texture_sample_radius
struct Object * texture_map_object
const T * base_ptr() const
Volume * get_volume_for_write()