Volumes: new Volume Displace modifier
This modifier uses a 3D texture to displace a volume. For now, this can only use the previously existing texture system, because we do not have a better alternative yet. Still, the results can be quite good and interesting. See D9075 for some examples. Reviewers: brecht, simonthommes Differential Revision: https://developer.blender.org/D9075
This commit is contained in:
parent
b8638b6491
commit
1f50beb9f2
Notes:
blender-bot
2023-02-14 07:39:46 +01:00
Referenced by issue #73201, New volume object type
|
@ -96,6 +96,7 @@ typedef enum ModifierType {
|
|||
eModifierType_Fluid = 56,
|
||||
eModifierType_Simulation = 57,
|
||||
eModifierType_MeshToVolume = 58,
|
||||
eModifierType_VolumeDisplace = 59,
|
||||
NUM_MODIFIER_TYPES,
|
||||
} ModifierType;
|
||||
|
||||
|
@ -2255,6 +2256,25 @@ typedef enum MeshToVolumeModifierResolutionMode {
|
|||
MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE = 1,
|
||||
} MeshToVolumeModifierResolutionMode;
|
||||
|
||||
typedef struct VolumeDisplaceModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct Tex *texture;
|
||||
struct Object *texture_map_object;
|
||||
int texture_map_mode;
|
||||
|
||||
float strength;
|
||||
float texture_mid_level[3];
|
||||
float texture_sample_radius;
|
||||
} VolumeDisplaceModifierData;
|
||||
|
||||
/* VolumeDisplaceModifierData->texture_map_mode */
|
||||
enum {
|
||||
MOD_VOLUME_DISPLACE_MAP_LOCAL = 0,
|
||||
MOD_VOLUME_DISPLACE_MAP_GLOBAL = 1,
|
||||
MOD_VOLUME_DISPLACE_MAP_OBJECT = 2,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -709,6 +709,7 @@ extern StructRNA RNA_View3DShading;
|
|||
extern StructRNA RNA_ViewLayer;
|
||||
extern StructRNA RNA_ViewLayerEEVEE;
|
||||
extern StructRNA RNA_Volume;
|
||||
extern StructRNA RNA_VolumeDisplaceModifier;
|
||||
extern StructRNA RNA_VoronoiTexture;
|
||||
extern StructRNA RNA_WalkNavigation;
|
||||
extern StructRNA RNA_WarpModifier;
|
||||
|
|
|
@ -272,6 +272,11 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
|
|||
ICON_MOD_WAVE,
|
||||
"Wave",
|
||||
"Adds a ripple-like motion to an object’s geometry"},
|
||||
{eModifierType_VolumeDisplace,
|
||||
"VOLUME_DISPLACE",
|
||||
ICON_VOLUME_DATA,
|
||||
"Volume Displace",
|
||||
"Deform volume based on noise or other vector fields"}, /* TODO: Use correct icon. */
|
||||
{0, "", 0, N_("Physics"), ""},
|
||||
{eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
|
||||
{eModifierType_Collision, "COLLISION", ICON_MOD_PHYSICS, "Collision", ""},
|
||||
|
@ -7057,6 +7062,75 @@ static void rna_def_modifier_mesh_to_volume(BlenderRNA *brna)
|
|||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
static void rna_def_modifier_volume_displace(BlenderRNA *brna)
|
||||
{
|
||||
static const EnumPropertyItem prop_texture_map_mode_items[] = {
|
||||
{MOD_VOLUME_DISPLACE_MAP_LOCAL,
|
||||
"LOCAL",
|
||||
0,
|
||||
"Local",
|
||||
"Use the local coordinate system for the texture coordinates"},
|
||||
{MOD_VOLUME_DISPLACE_MAP_GLOBAL,
|
||||
"GLOBAL",
|
||||
0,
|
||||
"Global",
|
||||
"Use the global coordinate system for the texture coordinates"},
|
||||
{MOD_VOLUME_DISPLACE_MAP_OBJECT,
|
||||
"OBJECT",
|
||||
0,
|
||||
"Object",
|
||||
"Use the linked object's local coordinate system for the texture coordinates"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "VolumeDisplaceModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "Volume Displace Modifier", "");
|
||||
RNA_def_struct_sdna(srna, "VolumeDisplaceModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_VOLUME_DATA); /* TODO: Use correct icon. */
|
||||
|
||||
RNA_define_lib_overridable(true);
|
||||
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Strength", "Strength of the displacement");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Texture", "");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture_map_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prop_texture_map_mode_items);
|
||||
RNA_def_property_ui_text(prop, "Texture Mapping Mode", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture_map_object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Object to use for texture mapping");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture_mid_level", PROP_FLOAT, PROP_XYZ);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Texture Mid Level", "Subtracted from the texture color to get a displacement vector");
|
||||
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 5);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture_sample_radius", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Texture Sample Radius",
|
||||
"Smaller values result in better performance but might cut off the volume");
|
||||
RNA_def_property_range(prop, 0.0f, FLT_MAX);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 5);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -7189,6 +7263,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
|||
rna_def_modifier_simulation(brna);
|
||||
# endif
|
||||
rna_def_modifier_mesh_to_volume(brna);
|
||||
rna_def_modifier_volume_displace(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -101,6 +101,7 @@ set(SRC
|
|||
intern/MOD_util.c
|
||||
intern/MOD_uvproject.c
|
||||
intern/MOD_uvwarp.c
|
||||
intern/MOD_volume_displace.cc
|
||||
intern/MOD_warp.c
|
||||
intern/MOD_wave.c
|
||||
intern/MOD_weighted_normal.c
|
||||
|
|
|
@ -87,6 +87,7 @@ extern ModifierTypeInfo modifierType_SurfaceDeform;
|
|||
extern ModifierTypeInfo modifierType_WeightedNormal;
|
||||
extern ModifierTypeInfo modifierType_Simulation;
|
||||
extern ModifierTypeInfo modifierType_MeshToVolume;
|
||||
extern ModifierTypeInfo modifierType_VolumeDisplace;
|
||||
|
||||
/* MOD_util.c */
|
||||
void modifier_type_init(ModifierTypeInfo *types[]);
|
||||
|
|
|
@ -344,5 +344,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
|
|||
INIT_TYPE(WeightedNormal);
|
||||
INIT_TYPE(Simulation);
|
||||
INIT_TYPE(MeshToVolume);
|
||||
INIT_TYPE(VolumeDisplace);
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_volume.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_volume_types.h"
|
||||
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "BLO_read_write.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "MOD_modifiertypes.h"
|
||||
#include "MOD_ui_common.h"
|
||||
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
# include <openvdb/tools/Interpolation.h>
|
||||
# include <openvdb/tools/Morphology.h>
|
||||
# include <openvdb/tools/Prune.h>
|
||||
# include <openvdb/tools/ValueTransformer.h>
|
||||
#endif
|
||||
|
||||
static void initData(ModifierData *md)
|
||||
{
|
||||
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
|
||||
vdmd->texture = NULL;
|
||||
vdmd->strength = 1.0f;
|
||||
copy_v3_fl(vdmd->texture_mid_level, 0.5f);
|
||||
vdmd->texture_sample_radius = 1.0f;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
{
|
||||
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
|
||||
if (vdmd->texture != NULL) {
|
||||
DEG_add_generic_id_relation(ctx->node, &vdmd->texture->id, "Volume Displace Modifier");
|
||||
}
|
||||
if (vdmd->texture_map_mode == MOD_VOLUME_DISPLACE_MAP_OBJECT) {
|
||||
if (vdmd->texture_map_object != NULL) {
|
||||
DEG_add_object_relation(
|
||||
ctx->node, vdmd->texture_map_object, DEG_OB_COMP_TRANSFORM, "Volume Displace Modifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
|
||||
{
|
||||
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
|
||||
walk(userData, ob, (ID **)&vdmd->texture, IDWALK_CB_USER);
|
||||
walk(userData, ob, (ID **)&vdmd->texture_map_object, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
|
||||
{
|
||||
walk(userData, ob, md, "texture");
|
||||
}
|
||||
|
||||
static bool dependsOnTime(ModifierData *md)
|
||||
{
|
||||
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
|
||||
if (vdmd->texture) {
|
||||
return BKE_texture_dependsOnTime(vdmd->texture);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void panel_draw(const bContext *C, Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
PointerRNA ob_ptr;
|
||||
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
|
||||
VolumeDisplaceModifierData *vdmd = static_cast<VolumeDisplaceModifierData *>(ptr->data);
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
uiTemplateID(layout, C, ptr, "texture", "texture.new", NULL, NULL, 0, ICON_NONE, NULL);
|
||||
uiItemR(layout, ptr, "texture_map_mode", 0, "Texture Mapping", ICON_NONE);
|
||||
|
||||
if (vdmd->texture_map_mode == MOD_VOLUME_DISPLACE_MAP_OBJECT) {
|
||||
uiItemR(layout, ptr, "texture_map_object", 0, "Object", ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, ptr, "texture_sample_radius", 0, "Sample Radius", ICON_NONE);
|
||||
uiItemR(layout, ptr, "texture_mid_level", 0, "Mid Level", ICON_NONE);
|
||||
|
||||
modifier_panel_end(layout, ptr);
|
||||
}
|
||||
|
||||
static void panelRegister(ARegionType *region_type)
|
||||
{
|
||||
modifier_panel_register(region_type, eModifierType_VolumeDisplace, panel_draw);
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
|
||||
static openvdb::Mat4s matrix_to_openvdb(const float m[4][4])
|
||||
{
|
||||
/* This constructor expects floats in row-major form. Therefore the matrix is transposed
|
||||
* afterwards. */
|
||||
openvdb::Mat4s new_matrix{reinterpret_cast<const float *>(m)};
|
||||
new_matrix = new_matrix.transpose();
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
template<typename GridType> struct DisplaceOp {
|
||||
/* Has to be copied for each thread. */
|
||||
typename GridType::ConstAccessor accessor;
|
||||
/* This is the transform of the grid that is being displaced. */
|
||||
openvdb::Mat4s index_to_texture;
|
||||
|
||||
Tex *texture;
|
||||
const double strength;
|
||||
const openvdb::Vec3d texture_mid_level;
|
||||
|
||||
void operator()(const typename GridType::ValueOnIter &iter) const
|
||||
{
|
||||
const openvdb::Coord coord = iter.getCoord();
|
||||
const openvdb::Vec3d displace_vector = this->compute_displace_vector(coord);
|
||||
/* Subtract vector because that makes the result more similar to advection and the mesh
|
||||
* displace modifier. */
|
||||
const openvdb::Vec3d sample_coord = coord.asVec3d() - displace_vector;
|
||||
const auto new_value = openvdb::tools::BoxSampler::sample(this->accessor, sample_coord);
|
||||
iter.setValue(new_value);
|
||||
}
|
||||
|
||||
openvdb::Vec3d compute_displace_vector(const openvdb::Coord &coord) const
|
||||
{
|
||||
if (this->texture != NULL) {
|
||||
const openvdb::Vec3f texture_pos = this->index_to_texture * coord.asVec3s();
|
||||
openvdb::Vec3d displace_vector = this->evaluate_texture(texture_pos);
|
||||
return (displace_vector - this->texture_mid_level) * this->strength;
|
||||
}
|
||||
return openvdb::Vec3d{0, 0, 0};
|
||||
}
|
||||
|
||||
openvdb::Vec3d evaluate_texture(const openvdb::Vec3f &pos) const
|
||||
{
|
||||
TexResult texture_result = {0};
|
||||
BKE_texture_get_value(
|
||||
NULL, this->texture, const_cast<float *>(pos.asV()), &texture_result, false);
|
||||
return {texture_result.tr, texture_result.tg, texture_result.tb};
|
||||
}
|
||||
};
|
||||
|
||||
static float get_max_voxel_side_length(const openvdb::GridBase &grid)
|
||||
{
|
||||
const openvdb::Mat3d matrix = grid.transform().baseMap()->getAffineMap()->getMat4().getMat3();
|
||||
const float max_voxel_side_length = std::max(
|
||||
{matrix.col(0).length(), matrix.col(1).length(), matrix.col(2).length()});
|
||||
return max_voxel_side_length;
|
||||
}
|
||||
|
||||
struct DisplaceGridOp {
|
||||
/* This is the grid that will be displaced. The output is copied back to the original grid. */
|
||||
openvdb::GridBase &base_grid;
|
||||
|
||||
VolumeDisplaceModifierData &vdmd;
|
||||
const ModifierEvalContext &ctx;
|
||||
|
||||
template<typename GridType> void operator()()
|
||||
{
|
||||
if constexpr (std::is_same_v<GridType, openvdb::points::PointDataGrid> ||
|
||||
std::is_same_v<GridType, openvdb::StringGrid> ||
|
||||
std::is_same_v<GridType, openvdb::MaskGrid>) {
|
||||
/* We don't support displacing these grid types yet. */
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this->displace_grid<GridType>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename GridType> void displace_grid()
|
||||
{
|
||||
GridType &grid = static_cast<GridType &>(base_grid);
|
||||
|
||||
/* Make a copy of the original grid to work on. This will replace the original grid. */
|
||||
typename GridType::Ptr temp_grid = grid.deepCopy();
|
||||
|
||||
/* Dilate grid, because the currently inactive cells might become active during the displace
|
||||
* operation. The quality of the approximation of the has a big impact on performance. */
|
||||
const float max_voxel_side_length = get_max_voxel_side_length(grid);
|
||||
const float sample_radius = vdmd.texture_sample_radius * std::abs(vdmd.strength) /
|
||||
max_voxel_side_length / 2.0f;
|
||||
openvdb::tools::dilateActiveValues(temp_grid->tree(),
|
||||
static_cast<int>(std::ceil(sample_radius)),
|
||||
openvdb::tools::NN_FACE_EDGE,
|
||||
openvdb::tools::EXPAND_TILES);
|
||||
|
||||
const openvdb::Mat4s index_to_texture = this->get_index_to_texture_transform();
|
||||
|
||||
/* Construct the operator that will be executed on every cell of the dilated grid. */
|
||||
DisplaceOp<GridType> displace_op{grid.getConstAccessor(),
|
||||
index_to_texture,
|
||||
vdmd.texture,
|
||||
vdmd.strength / max_voxel_side_length,
|
||||
openvdb::Vec3d{vdmd.texture_mid_level}};
|
||||
|
||||
/* Run the operator. This is multi-threaded. It is important that the operator is not shared
|
||||
* between the threads, because it contains a non-thread-safe accessor for the old grid. */
|
||||
openvdb::tools::foreach (temp_grid->beginValueOn(),
|
||||
displace_op,
|
||||
true,
|
||||
/* Disable sharing of the operator. */ false);
|
||||
|
||||
/* It is likely that we produced too many active cells. Those are removed here, to avoid
|
||||
* slowing down subsequent operations. */
|
||||
typename GridType::ValueType prune_tolerance{0};
|
||||
openvdb::tools::deactivate(*temp_grid, temp_grid->background(), prune_tolerance);
|
||||
openvdb::tools::prune(temp_grid->tree());
|
||||
|
||||
/* Overwrite the old volume grid with the new grid. */
|
||||
grid.clear();
|
||||
grid.merge(*temp_grid);
|
||||
}
|
||||
|
||||
openvdb::Mat4s get_index_to_texture_transform() const
|
||||
{
|
||||
const openvdb::Mat4s index_to_object{
|
||||
base_grid.transform().baseMap()->getAffineMap()->getMat4()};
|
||||
|
||||
switch (vdmd.texture_map_mode) {
|
||||
case MOD_VOLUME_DISPLACE_MAP_LOCAL: {
|
||||
return index_to_object;
|
||||
}
|
||||
case MOD_VOLUME_DISPLACE_MAP_GLOBAL: {
|
||||
const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
|
||||
return object_to_world * index_to_object;
|
||||
}
|
||||
case MOD_VOLUME_DISPLACE_MAP_OBJECT: {
|
||||
if (vdmd.texture_map_object == NULL) {
|
||||
return index_to_object;
|
||||
}
|
||||
const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
|
||||
const openvdb::Mat4s world_to_texture = matrix_to_openvdb(vdmd.texture_map_object->imat);
|
||||
return world_to_texture * object_to_world * index_to_object;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Volume *volume)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
|
||||
|
||||
/* Iterate over all grids and displace them one by one. */
|
||||
const int grid_amount = BKE_volume_num_grids(volume);
|
||||
for (int grid_index = 0; grid_index < grid_amount; grid_index++) {
|
||||
VolumeGrid *volume_grid = BKE_volume_grid_get(volume, grid_index);
|
||||
BLI_assert(volume_grid != NULL);
|
||||
|
||||
openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid, false);
|
||||
VolumeGridType grid_type = BKE_volume_grid_type(volume_grid);
|
||||
|
||||
DisplaceGridOp displace_grid_op{*grid, *vdmd, *ctx};
|
||||
BKE_volume_grid_type_operation(grid_type, displace_grid_op);
|
||||
}
|
||||
|
||||
return volume;
|
||||
#else
|
||||
UNUSED_VARS(md, ctx);
|
||||
BKE_modifier_set_error(md, "Compiled without OpenVDB");
|
||||
return volume;
|
||||
#endif
|
||||
}
|
||||
|
||||
ModifierTypeInfo modifierType_VolumeDisplace = {
|
||||
/* name */ "Volume Displace",
|
||||
/* structName */ "VolumeDisplaceModifierData",
|
||||
/* structSize */ sizeof(VolumeDisplaceModifierData),
|
||||
/* srna */ &RNA_VolumeDisplaceModifier,
|
||||
/* type */ eModifierTypeType_NonGeometrical,
|
||||
/* flags */ static_cast<ModifierTypeFlag>(0),
|
||||
/* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */
|
||||
|
||||
/* copyData */ BKE_modifier_copydata_generic,
|
||||
|
||||
/* deformVerts */ NULL,
|
||||
/* deformMatrices */ NULL,
|
||||
/* deformVertsEM */ NULL,
|
||||
/* deformMatricesEM */ NULL,
|
||||
/* modifyMesh */ NULL,
|
||||
/* modifyHair */ NULL,
|
||||
/* modifyPointCloud */ NULL,
|
||||
/* modifyVolume */ modifyVolume,
|
||||
|
||||
/* initData */ initData,
|
||||
/* requiredDataMask */ NULL,
|
||||
/* freeData */ NULL,
|
||||
/* isDisabled */ NULL,
|
||||
/* updateDepsgraph */ updateDepsgraph,
|
||||
/* dependsOnTime */ dependsOnTime,
|
||||
/* dependsOnNormals */ NULL,
|
||||
/* foreachIDLink */ foreachIDLink,
|
||||
/* foreachTexLink */ foreachTexLink,
|
||||
/* freeRuntimeData */ NULL,
|
||||
/* panelRegister */ panelRegister,
|
||||
/* blendWrite */ NULL,
|
||||
/* blendRead */ NULL,
|
||||
};
|
Loading…
Reference in New Issue