55 # include <openvdb/openvdb.h>
56 # include <openvdb/tools/Interpolation.h>
57 # include <openvdb/tools/Morphology.h>
58 # include <openvdb/tools/Prune.h>
59 # include <openvdb/tools/ValueTransformer.h>
94 walk(userData, ob, md,
"texture");
116 uiTemplateID(layout,
C,
ptr,
"texture",
"texture.new",
nullptr,
nullptr, 0, ICON_NONE,
nullptr);
117 uiItemR(layout,
ptr,
"texture_map_mode", 0,
"Texture Mapping", ICON_NONE);
120 uiItemR(layout,
ptr,
"texture_map_object", 0,
"Object", ICON_NONE);
123 uiItemR(layout,
ptr,
"strength", 0,
nullptr, ICON_NONE);
124 uiItemR(layout,
ptr,
"texture_sample_radius", 0,
"Sample Radius", ICON_NONE);
125 uiItemR(layout,
ptr,
"texture_mid_level", 0,
"Mid Level", ICON_NONE);
137 static openvdb::Mat4s matrix_to_openvdb(
const float m[4][4])
142 openvdb::Mat4s new_matrix{
reinterpret_cast<const float *
>(m)};
146 template<
typename Gr
idType>
struct DisplaceOp {
148 typename GridType::ConstAccessor accessor;
149 const openvdb::Mat4s index_to_texture;
152 const double strength;
155 void operator()(
const typename GridType::ValueOnIter &iter)
const
157 const openvdb::Coord coord = iter.getCoord();
158 const openvdb::Vec3d displace_vector = this->compute_displace_vector(coord);
161 const openvdb::Vec3d sample_coord = coord.asVec3d() - displace_vector;
163 iter.setValue(new_value);
166 openvdb::Vec3d compute_displace_vector(
const openvdb::Coord &coord)
const
168 if (this->texture !=
nullptr) {
169 const openvdb::Vec3f texture_pos = coord.asVec3s() * this->index_to_texture;
170 const openvdb::Vec3d texture_value = this->evaluate_texture(texture_pos);
171 const openvdb::Vec3d displacement = (texture_value - this->texture_mid_level) *
182 nullptr, this->texture,
const_cast<float *
>(
pos.asV()), &texture_result,
false);
183 return {texture_result.
tr, texture_result.
tg, texture_result.
tb};
187 static float get_max_voxel_side_length(
const openvdb::GridBase &grid)
190 const float max_voxel_side_length =
std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
191 return max_voxel_side_length;
194 struct DisplaceGridOp {
196 openvdb::GridBase &base_grid;
203 if constexpr (std::is_same_v<GridType, openvdb::points::PointDataGrid> ||
204 std::is_same_v<GridType, openvdb::StringGrid> ||
205 std::is_same_v<GridType, openvdb::MaskGrid>) {
210 this->displace_grid<GridType>();
214 template<
typename Gr
idType>
void displace_grid()
216 GridType &grid =
static_cast<GridType &
>(base_grid);
219 typename GridType::Ptr temp_grid = grid.deepCopy();
223 const float max_voxel_side_length = get_max_voxel_side_length(grid);
225 max_voxel_side_length / 2.0f;
226 openvdb::tools::dilateActiveValues(temp_grid->tree(),
227 static_cast<int>(
std::ceil(sample_radius)),
228 openvdb::tools::NN_FACE_EDGE,
229 openvdb::tools::EXPAND_TILES);
231 const openvdb::Mat4s index_to_texture = this->get_index_to_texture_transform();
234 DisplaceOp<GridType> displace_op{grid.getConstAccessor(),
237 vdmd.
strength / max_voxel_side_length,
250 openvdb::tools::deactivate(*temp_grid, temp_grid->background(), prune_tolerance);
251 openvdb::tools::prune(temp_grid->tree());
255 grid.merge(*temp_grid);
258 openvdb::Mat4s get_index_to_texture_transform()
const
260 const openvdb::Mat4s index_to_object{
261 base_grid.transform().baseMap()->getAffineMap()->getMat4()};
265 return index_to_object;
268 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->
obmat);
269 return index_to_object * object_to_world;
273 return index_to_object;
275 const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.
object->
obmat);
277 return index_to_object * object_to_world * world_to_texture;
295 for (
int grid_index = 0; grid_index < grid_amount; grid_index++) {
299 openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid,
false);
302 DisplaceGridOp displace_grid_op{*grid, *vdmd, *ctx};
303 BKE_volume_grid_type_operation(grid_type, displace_grid_op);
316 "VolumeDisplaceModifierData",
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, const 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)
ModifierTypeInfo modifierType_VolumeDisplace
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static Volume * modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Volume *volume)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
static bool dependsOnTime(ModifierData *md)
static void panel_draw(const bContext *C, Panel *panel)
StructRNA RNA_VolumeDisplaceModifier
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, const bool live_icon, const char *text)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
VecMat::Vec3< double > Vec3d
static void sample(SocketReader *reader, int x, int y, float color[4])
struct Depsgraph * depsgraph
struct DepsNodeHandle * node
float texture_mid_level[3]
float texture_sample_radius
struct Object * texture_map_object
__forceinline const avxi abs(const avxi &a)
ccl_device_inline float3 ceil(const float3 &a)