Volumes: new Mesh to Volume modifier
This modifier can only be added to Volume objects. It takes a mesh as input and generates a "density" grid near the surface or in the enclosed volume. Ref T73201. Reviewers: brecht Differential Revision: https://developer.blender.org/D9032
This commit is contained in:
parent
e12767a035
commit
5845c06a63
Notes:
blender-bot
2023-02-14 09:34:18 +01:00
|
@ -157,4 +157,16 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume
|
|||
openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *volume,
|
||||
struct VolumeGrid *grid,
|
||||
const bool clear);
|
||||
|
||||
template<typename GridType>
|
||||
typename GridType::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *volume,
|
||||
struct VolumeGrid *grid,
|
||||
const bool clear)
|
||||
{
|
||||
openvdb::GridBase::Ptr openvdb_grid = BKE_volume_grid_openvdb_for_write(volume, grid, clear);
|
||||
BLI_assert(openvdb_grid->isType<GridType>());
|
||||
typename GridType::Ptr typed_openvdb_grid = openvdb::gridPtrCast<GridType>(openvdb_grid);
|
||||
return typed_openvdb_grid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -95,6 +95,7 @@ typedef enum ModifierType {
|
|||
eModifierType_Weld = 55,
|
||||
eModifierType_Fluid = 56,
|
||||
eModifierType_Simulation = 57,
|
||||
eModifierType_MeshToVolume = 58,
|
||||
NUM_MODIFIER_TYPES,
|
||||
} ModifierType;
|
||||
|
||||
|
@ -2208,6 +2209,39 @@ typedef struct SimulationModifierData {
|
|||
char *data_path;
|
||||
} SimulationModifierData;
|
||||
|
||||
typedef struct MeshToVolumeModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
/** This is the object that is supposed to be converted to a volume. */
|
||||
struct Object *object;
|
||||
|
||||
/** MeshToVolumeModifierResolutionMode */
|
||||
int resolution_mode;
|
||||
/** Size of a voxel in object space. */
|
||||
float voxel_size;
|
||||
/** The desired amount of voxels along one axis. The actual amount of voxels might be slightly
|
||||
* different. */
|
||||
int voxel_amount;
|
||||
|
||||
/** If true, every cell in the enclosed volume gets a density. Otherwise, the interior_band_width
|
||||
* is used. */
|
||||
char fill_volume;
|
||||
char _pad1[3];
|
||||
|
||||
/** Band widths are in object space. */
|
||||
float interior_band_width;
|
||||
float exterior_band_width;
|
||||
|
||||
float density;
|
||||
char _pad2[4];
|
||||
} MeshToVolumeModifierData;
|
||||
|
||||
/* MeshToVolumeModifierData->resolution_mode */
|
||||
typedef enum MeshToVolumeModifierResolutionMode {
|
||||
MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT = 0,
|
||||
MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE = 1,
|
||||
} MeshToVolumeModifierResolutionMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -389,6 +389,7 @@ extern StructRNA RNA_MaterialSlot;
|
|||
extern StructRNA RNA_Menu;
|
||||
extern StructRNA RNA_Mesh;
|
||||
extern StructRNA RNA_MeshCacheModifier;
|
||||
extern StructRNA RNA_MeshToVolumeModifier;
|
||||
extern StructRNA RNA_MeshColor;
|
||||
extern StructRNA RNA_MeshDeformModifier;
|
||||
extern StructRNA RNA_MeshEdge;
|
||||
|
|
|
@ -193,6 +193,11 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
|
|||
ICON_MOD_WIREFRAME,
|
||||
"Wireframe",
|
||||
"Convert faces into thickened edges"},
|
||||
{eModifierType_MeshToVolume,
|
||||
"MESH_TO_VOLUME",
|
||||
ICON_VOLUME_DATA,
|
||||
"Mesh to Volume",
|
||||
""}, /* TODO: Use correct icon. */
|
||||
{0, "", 0, N_("Deform"), ""},
|
||||
{eModifierType_Armature,
|
||||
"ARMATURE",
|
||||
|
@ -6973,6 +6978,77 @@ static void rna_def_modifier_simulation(BlenderRNA *brna)
|
|||
}
|
||||
# endif
|
||||
|
||||
static void rna_def_modifier_mesh_to_volume(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem resolution_mode_items[] = {
|
||||
{MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT,
|
||||
"VOXEL_AMOUNT",
|
||||
0,
|
||||
"Voxel Amount",
|
||||
"Desired number of voxels along one axis"},
|
||||
{MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE,
|
||||
"VOXEL_SIZE",
|
||||
0,
|
||||
"Voxel Size",
|
||||
"Desired voxel side length"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "MeshToVolumeModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "Mesh to Volume Modifier", "");
|
||||
RNA_def_struct_sdna(srna, "MeshToVolumeModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_VOLUME_DATA); /* TODO: Use correct icon. */
|
||||
|
||||
RNA_define_lib_overridable(true);
|
||||
|
||||
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Object");
|
||||
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, "resolution_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, resolution_mode_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Resolution Mode", "Mode for how the desired voxel size is specified");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "voxel_size", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Voxel Size", "Smaller values result in a higher resolution output");
|
||||
RNA_def_property_range(prop, 0.1, FLT_MAX);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "voxel_amount", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Voxel Amount", "Approximate number of voxels along one axis");
|
||||
RNA_def_property_range(prop, 0, INT_MAX);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fill_volume", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Fill Volume", "Initialize the density grid in every cell inside the enclosed volume");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "interior_band_width", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Interior Band Width", "Width of the volume inside of the mesh");
|
||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "exterior_band_width", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Exterior Band Width", "Width of the volume outside of the mesh");
|
||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Density", "Density of the new volume");
|
||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -7104,6 +7180,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
|||
# ifdef WITH_PARTICLE_NODES
|
||||
rna_def_modifier_simulation(brna);
|
||||
# endif
|
||||
rna_def_modifier_mesh_to_volume(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,7 @@ set(SRC
|
|||
intern/MOD_laplaciansmooth.c
|
||||
intern/MOD_lattice.c
|
||||
intern/MOD_mask.cc
|
||||
intern/MOD_mesh_to_volume.cc
|
||||
intern/MOD_meshcache.c
|
||||
intern/MOD_meshcache_mdd.c
|
||||
intern/MOD_meshcache_pc2.c
|
||||
|
@ -177,6 +178,20 @@ if(WITH_GMP)
|
|||
add_definitions(-DWITH_GMP)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
list(APPEND INC
|
||||
../../../intern/openvdb
|
||||
)
|
||||
list(APPEND INC_SYS
|
||||
${OPENVDB_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
bf_intern_openvdb
|
||||
${OPENVDB_LIBRARIES}
|
||||
)
|
||||
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
if(WITH_EXPERIMENTAL_FEATURES)
|
||||
add_definitions(-DWITH_PARTICLE_NODES)
|
||||
add_definitions(-DWITH_HAIR_NODES)
|
||||
|
|
|
@ -86,6 +86,7 @@ extern ModifierTypeInfo modifierType_MeshSequenceCache;
|
|||
extern ModifierTypeInfo modifierType_SurfaceDeform;
|
||||
extern ModifierTypeInfo modifierType_WeightedNormal;
|
||||
extern ModifierTypeInfo modifierType_Simulation;
|
||||
extern ModifierTypeInfo modifierType_MeshToVolume;
|
||||
|
||||
/* MOD_util.c */
|
||||
void modifier_type_init(ModifierTypeInfo *types[]);
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* 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 <vector>
|
||||
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.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_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 "BLI_float4x4.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
# include <openvdb/tools/MeshToVolume.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
namespace blender {
|
||||
/* This class follows the MeshDataAdapter interface from openvdb. */
|
||||
class OpenVDBMeshAdapter {
|
||||
private:
|
||||
Span<MVert> vertices_;
|
||||
Span<MLoop> loops_;
|
||||
Span<MLoopTri> looptris_;
|
||||
float4x4 transform_;
|
||||
|
||||
public:
|
||||
OpenVDBMeshAdapter(Mesh &mesh, float4x4 transform)
|
||||
: vertices_(mesh.mvert, mesh.totvert),
|
||||
loops_(mesh.mloop, mesh.totloop),
|
||||
transform_(transform)
|
||||
{
|
||||
const MLoopTri *looptries = BKE_mesh_runtime_looptri_ensure(&mesh);
|
||||
const int looptries_len = BKE_mesh_runtime_looptri_len(&mesh);
|
||||
looptris_ = Span(looptries, looptries_len);
|
||||
}
|
||||
|
||||
size_t polygonCount() const
|
||||
{
|
||||
return static_cast<size_t>(looptris_.size());
|
||||
}
|
||||
|
||||
size_t pointCount() const
|
||||
{
|
||||
return static_cast<size_t>(vertices_.size());
|
||||
}
|
||||
|
||||
size_t vertexCount(size_t UNUSED(polygon_index)) const
|
||||
{
|
||||
/* All polygons are triangles. */
|
||||
return 3;
|
||||
}
|
||||
|
||||
void getIndexSpacePoint(size_t polygon_index, size_t vertex_index, openvdb::Vec3d &pos) const
|
||||
{
|
||||
const MLoopTri &looptri = looptris_[polygon_index];
|
||||
const MVert &vertex = vertices_[loops_[looptri.tri[vertex_index]].v];
|
||||
const float3 transformed_co = transform_ * float3(vertex.co);
|
||||
pos = &transformed_co.x;
|
||||
}
|
||||
};
|
||||
} // namespace blender
|
||||
#endif
|
||||
|
||||
static void initData(ModifierData *md)
|
||||
{
|
||||
MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
|
||||
mvmd->object = NULL;
|
||||
mvmd->resolution_mode = MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT;
|
||||
mvmd->voxel_size = 0.1f;
|
||||
mvmd->voxel_amount = 32;
|
||||
mvmd->fill_volume = true;
|
||||
mvmd->interior_band_width = 0.1f;
|
||||
mvmd->exterior_band_width = 0.1f;
|
||||
mvmd->density = 1.0f;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
{
|
||||
MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
|
||||
DEG_add_modifier_to_transform_relation(ctx->node, "Mesh to Volume Modifier");
|
||||
if (mvmd->object) {
|
||||
DEG_add_object_relation(
|
||||
ctx->node, mvmd->object, DEG_OB_COMP_GEOMETRY, "Mesh to Volume Modifier");
|
||||
DEG_add_object_relation(
|
||||
ctx->node, mvmd->object, DEG_OB_COMP_TRANSFORM, "Mesh to Volume Modifier");
|
||||
}
|
||||
}
|
||||
|
||||
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
|
||||
{
|
||||
MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
|
||||
walk(userData, ob, &mvmd->object, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
PointerRNA ob_ptr;
|
||||
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
|
||||
MeshToVolumeModifierData *mvmd = static_cast<MeshToVolumeModifierData *>(ptr->data);
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, ptr, "density", 0, NULL, ICON_NONE);
|
||||
|
||||
{
|
||||
uiLayout *col = uiLayoutColumn(layout, false);
|
||||
uiItemR(col, ptr, "fill_volume", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "exterior_band_width", 0, NULL, ICON_NONE);
|
||||
|
||||
uiLayout *subcol = uiLayoutColumn(col, false);
|
||||
uiLayoutSetEnabled(subcol, !mvmd->fill_volume);
|
||||
uiItemR(subcol, ptr, "interior_band_width", 0, NULL, ICON_NONE);
|
||||
}
|
||||
{
|
||||
uiLayout *col = uiLayoutColumn(layout, false);
|
||||
uiItemR(col, ptr, "resolution_mode", 0, NULL, ICON_NONE);
|
||||
if (mvmd->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
|
||||
uiItemR(col, ptr, "voxel_amount", 0, NULL, ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemR(col, ptr, "voxel_size", 0, NULL, ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
modifier_panel_end(layout, ptr);
|
||||
}
|
||||
|
||||
static void panelRegister(ARegionType *region_type)
|
||||
{
|
||||
modifier_panel_register(region_type, eModifierType_MeshToVolume, panel_draw);
|
||||
}
|
||||
|
||||
static float compute_voxel_size(const MeshToVolumeModifierData *mvmd,
|
||||
const blender::float4x4 &transform)
|
||||
{
|
||||
using namespace blender;
|
||||
if (mvmd->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
|
||||
return MAX2(0.0001, mvmd->voxel_size);
|
||||
}
|
||||
|
||||
/* Compute the voxel size based on the desired number of voxels and the approximated bounding box
|
||||
* of the volume. */
|
||||
const BoundBox *bb = BKE_object_boundbox_get(mvmd->object);
|
||||
const float3 x_axis = float3(bb->vec[4]) - float3(bb->vec[0]);
|
||||
const float3 y_axis = float3(bb->vec[3]) - float3(bb->vec[0]);
|
||||
const float3 z_axis = float3(bb->vec[1]) - float3(bb->vec[0]);
|
||||
const float max_dimension = std::max({(transform.ref_3x3() * x_axis).length(),
|
||||
(transform.ref_3x3() * y_axis).length(),
|
||||
(transform.ref_3x3() * z_axis).length()});
|
||||
const float approximate_volume_side_length = max_dimension + mvmd->exterior_band_width * 2.0f;
|
||||
const float voxel_size = approximate_volume_side_length / MAX2(1, mvmd->voxel_amount);
|
||||
return voxel_size;
|
||||
}
|
||||
|
||||
static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Volume *input_volume)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
using namespace blender;
|
||||
|
||||
MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
|
||||
Object *object_to_convert = mvmd->object;
|
||||
|
||||
if (object_to_convert == NULL) {
|
||||
return input_volume;
|
||||
}
|
||||
Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(object_to_convert, false);
|
||||
if (mesh == NULL) {
|
||||
return input_volume;
|
||||
}
|
||||
|
||||
const float4x4 mesh_to_own_object_space_transform = float4x4(ctx->object->imat) *
|
||||
float4x4(object_to_convert->obmat);
|
||||
const float voxel_size = compute_voxel_size(mvmd, mesh_to_own_object_space_transform);
|
||||
|
||||
float4x4 mesh_to_index_space_transform;
|
||||
scale_m4_fl(mesh_to_index_space_transform.values, 1.0f / voxel_size);
|
||||
mul_m4_m4_post(mesh_to_index_space_transform.values, mesh_to_own_object_space_transform.values);
|
||||
/* Better align generated grid with the source mesh. */
|
||||
add_v3_fl(mesh_to_index_space_transform.values[3], -0.5f);
|
||||
|
||||
OpenVDBMeshAdapter mesh_adapter{*mesh, mesh_to_index_space_transform};
|
||||
|
||||
/* Convert the bandwidths from object in index space. */
|
||||
const float exterior_band_width = MAX2(0.001f, mvmd->exterior_band_width / voxel_size);
|
||||
const float interior_band_width = MAX2(0.001f, mvmd->interior_band_width / voxel_size);
|
||||
|
||||
openvdb::FloatGrid::Ptr new_grid;
|
||||
if (mvmd->fill_volume) {
|
||||
/* Setting the interior bandwidth to FLT_MAX, will make it fill the entire volume. */
|
||||
new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
|
||||
mesh_adapter, {}, exterior_band_width, FLT_MAX);
|
||||
}
|
||||
else {
|
||||
new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
|
||||
mesh_adapter, {}, exterior_band_width, interior_band_width);
|
||||
}
|
||||
|
||||
/* Create a new volume object and add the density grid. */
|
||||
Volume *volume = BKE_volume_new_for_eval(input_volume);
|
||||
VolumeGrid *c_density_grid = BKE_volume_grid_add(volume, "density", VOLUME_GRID_FLOAT);
|
||||
openvdb::FloatGrid::Ptr density_grid = BKE_volume_grid_openvdb_for_write<openvdb::FloatGrid>(
|
||||
volume, c_density_grid, false);
|
||||
|
||||
/* Merge the generated grid into the density grid. Should be cheap because density_grid has just
|
||||
* been created as well. */
|
||||
density_grid->merge(*new_grid);
|
||||
|
||||
/* Change transform so that the index space is correctly transformed to object space. */
|
||||
density_grid->transform().postScale(voxel_size);
|
||||
|
||||
/* Give each grid cell a fixed density for now. */
|
||||
openvdb::tools::foreach (
|
||||
density_grid->beginValueOn(),
|
||||
[&](const openvdb::FloatGrid::ValueOnIter &iter) { iter.setValue(mvmd->density); });
|
||||
|
||||
return volume;
|
||||
|
||||
#else
|
||||
UNUSED_VARS(md, ctx);
|
||||
UNUSED_VARS(compute_voxel_size);
|
||||
BKE_modifier_set_error(md, "Compiled without OpenVDB");
|
||||
return input_volume;
|
||||
#endif
|
||||
}
|
||||
|
||||
ModifierTypeInfo modifierType_MeshToVolume = {
|
||||
/* name */ "Mesh to Volume",
|
||||
/* structName */ "MeshToVolumeModifierData",
|
||||
/* structSize */ sizeof(MeshToVolumeModifierData),
|
||||
/* srna */ &RNA_MeshToVolumeModifier,
|
||||
/* type */ eModifierTypeType_Constructive,
|
||||
/* 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 */ NULL,
|
||||
/* dependsOnNormals */ NULL,
|
||||
/* foreachObjectLink */ foreachObjectLink,
|
||||
/* foreachIDLink */ NULL,
|
||||
/* foreachTexLink */ NULL,
|
||||
/* freeRuntimeData */ NULL,
|
||||
/* panelRegister */ panelRegister,
|
||||
/* blendWrite */ NULL,
|
||||
/* blendRead */ NULL,
|
||||
};
|
|
@ -343,5 +343,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
|
|||
INIT_TYPE(SurfaceDeform);
|
||||
INIT_TYPE(WeightedNormal);
|
||||
INIT_TYPE(Simulation);
|
||||
INIT_TYPE(MeshToVolume);
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue