40 #include "RNA_prototypes.h"
45 # include <openvdb/openvdb.h>
46 # include <openvdb/tools/Interpolation.h>
47 # include <openvdb/tools/Morphology.h>
48 # include <openvdb/tools/Prune.h>
49 # include <openvdb/tools/ValueTransformer.h>
84 walk(userData, ob, md,
"texture");
106 uiTemplateID(layout,
C,
ptr,
"texture",
"texture.new",
nullptr,
nullptr, 0, ICON_NONE,
nullptr);
107 uiItemR(layout,
ptr,
"texture_map_mode", 0,
"Texture Mapping", ICON_NONE);
110 uiItemR(layout,
ptr,
"texture_map_object", 0,
"Object", ICON_NONE);
113 uiItemR(layout,
ptr,
"strength", 0,
nullptr, ICON_NONE);
114 uiItemR(layout,
ptr,
"texture_sample_radius", 0,
"Sample Radius", ICON_NONE);
115 uiItemR(layout,
ptr,
"texture_mid_level", 0,
"Mid Level", ICON_NONE);
127 static openvdb::Mat4s matrix_to_openvdb(
const float m[4][4])
132 openvdb::Mat4s new_matrix{
reinterpret_cast<const float *
>(m)};
136 template<
typename Gr
idType>
struct DisplaceOp {
138 typename GridType::ConstAccessor accessor;
139 const openvdb::Mat4s index_to_texture;
142 const double strength;
145 void operator()(
const typename GridType::ValueOnIter &iter)
const
147 const openvdb::Coord coord = iter.getCoord();
148 const openvdb::Vec3d displace_vector = this->compute_displace_vector(coord);
151 const openvdb::Vec3d sample_coord = coord.asVec3d() - displace_vector;
153 iter.setValue(new_value);
156 openvdb::Vec3d compute_displace_vector(
const openvdb::Coord &coord)
const
158 if (this->texture !=
nullptr) {
159 const openvdb::Vec3f texture_pos = coord.asVec3s() * this->index_to_texture;
160 const openvdb::Vec3d texture_value = this->evaluate_texture(texture_pos);
161 const openvdb::Vec3d displacement = (texture_value - this->texture_mid_level) *
172 nullptr, this->texture,
const_cast<float *
>(
pos.asV()), &texture_result,
false);
173 return {texture_result.
trgba[0], texture_result.
trgba[1], texture_result.
trgba[2]};
177 static float get_max_voxel_side_length(
const openvdb::GridBase &grid)
180 const float max_voxel_side_length =
std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
181 return max_voxel_side_length;
184 struct DisplaceGridOp {
186 openvdb::GridBase &base_grid;
194 is_same_any_v<GridType, openvdb::points::PointDataGrid, openvdb::MaskGrid>) {
199 this->displace_grid<GridType>();
203 template<
typename Gr
idType>
void displace_grid()
205 GridType &grid =
static_cast<GridType &
>(base_grid);
212 const float max_voxel_side_length = get_max_voxel_side_length(grid);
214 max_voxel_side_length / 2.0f;
215 openvdb::tools::dilateActiveValues(temp_grid->tree(),
216 static_cast<int>(
std::ceil(sample_radius)),
217 openvdb::tools::NN_FACE_EDGE,
218 openvdb::tools::EXPAND_TILES);
220 const openvdb::Mat4s index_to_texture = this->get_index_to_texture_transform();
223 DisplaceOp<GridType> displace_op{grid.getConstAccessor(),
226 vdmd.
strength / max_voxel_side_length,
238 typename GridType::ValueType prune_tolerance{0};
239 openvdb::tools::deactivate(*temp_grid, temp_grid->background(), prune_tolerance);
240 openvdb::tools::prune(temp_grid->tree());
244 grid.merge(*temp_grid);
247 openvdb::Mat4s get_index_to_texture_transform()
const
249 const openvdb::Mat4s index_to_object{
250 base_grid.transform().baseMap()->getAffineMap()->getMat4()};
254 return index_to_object;
257 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->
obmat);
258 return index_to_object * object_to_world;
262 return index_to_object;
264 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->
obmat);
266 return index_to_object * object_to_world * world_to_texture;
284 for (
int grid_index = 0; grid_index < grid_amount; grid_index++) {
291 DisplaceGridOp displace_grid_op{*grid, *vdmd, *ctx};
292 BKE_volume_grid_type_operation(grid_type, displace_grid_op);
306 if (input_volume !=
nullptr) {
312 N_(
"Volume Displace"),
313 "VolumeDisplaceModifierData",
315 &RNA_VolumeDisplaceModifier,
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
void(* TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname)
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_NonGeometrical
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
General operations, lookup, etc. for blender objects.
bool BKE_texture_dependsOnTime(const struct Tex *texture)
void BKE_texture_get_value(const struct Scene *scene, struct Tex *texture, const float *tex_co, struct TexResult *texres, bool use_color_management)
VolumeGridType BKE_volume_grid_type(const struct VolumeGrid *grid)
VolumeGrid * BKE_volume_grid_get_for_write(struct Volume *volume, int grid_index)
int BKE_volume_num_grids(const struct Volume *volume)
bool BKE_volume_load(const struct Volume *volume, const struct Main *bmain)
MINLINE void copy_v3_fl(float r[3], float f)
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_generic_id_relation(struct DepsNodeHandle *node_handle, struct ID *id, const char *description)
struct Main * DEG_get_bmain(const Depsgraph *graph)
@ MOD_VOLUME_DISPLACE_MAP_GLOBAL
@ MOD_VOLUME_DISPLACE_MAP_LOCAL
@ MOD_VOLUME_DISPLACE_MAP_OBJECT
struct VolumeDisplaceModifierData VolumeDisplaceModifierData
@ eModifierType_VolumeDisplace
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
ModifierTypeInfo modifierType_VolumeDisplace
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void displace_volume(ModifierData *md, const ModifierEvalContext *ctx, Volume *volume)
static void modifyGeometrySet(ModifierData *md, const ModifierEvalContext *ctx, GeometrySet *geometry_set)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
static void panel_draw(const bContext *C, Panel *panel)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiTemplateID(uiLayout *layout, const struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter, bool live_icon, const char *text)
ccl_device_inline float3 ceil(const float3 &a)
VecMat::Vec3< double > Vec3d
Volume * get_volume_for_write()
struct Depsgraph * depsgraph
struct DepsNodeHandle * node
float texture_mid_level[3]
float texture_sample_radius
struct Object * texture_map_object