[Bf-blender-cvs] [9cbc8740624] mesh-to-volume-modifier: support different modes of operation
Jacques Lucke
noreply at git.blender.org
Thu Sep 24 15:32:35 CEST 2020
Commit: 9cbc8740624220f7de60248ec01ce0c05bfaba24
Author: Jacques Lucke
Date: Thu Sep 24 15:32:27 2020 +0200
Branches: mesh-to-volume-modifier
https://developer.blender.org/rB9cbc8740624220f7de60248ec01ce0c05bfaba24
support different modes of operation
===================================================================
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/rna_modifier.c
M source/blender/modifiers/intern/MOD_mesh_to_volume.cc
===================================================================
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index e8c48ef5972..69c010428c2 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2212,13 +2212,43 @@ typedef struct SimulationModifierData {
typedef struct MeshToVolumeModifierData {
ModifierData modifier;
+
+ /** This is the object that is supposed to be converted to a volume. */
struct Object *object;
+
+ /** MeshToVolumeModifierMode */
+ int mode;
+
+ /** 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_bandwidth
+ * is used. */
+ char fill_volume;
+ char _pad1[3];
+ /** Bandwidths are on object space. */
float interior_bandwidth;
float exterior_bandwidth;
char _pad[4];
} MeshToVolumeModifierData;
+/* MeshToVolumeModifierData->mode */
+typedef enum MeshToVolumeModifierMode {
+ MESH_TO_VOLUME_MODE_VOLUME = 0,
+ MESH_TO_VOLUME_MODE_SURFACE = 1,
+} MeshToVolumeModifierMode;
+
+/* 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
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index ebaab7d5c0d..94f9fd9bb49 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -7103,6 +7103,34 @@ static void rna_def_modifier_mesh_to_volume(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static EnumPropertyItem mode_items[] = {
+ {MESH_TO_VOLUME_MODE_VOLUME,
+ "VOLUME",
+ 0,
+ "Volume",
+ "Create a volume based on the volume that is enclosed by the mesh surface"},
+ {MESH_TO_VOLUME_MODE_SURFACE,
+ "SURFACE",
+ 0,
+ "Surface",
+ "Create a volume based on the mesh surface"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static EnumPropertyItem resolution_mode_items[] = {
+ {MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT,
+ "VOXEL_AMOUNT",
+ 0,
+ "Voxel Amount",
+ "Specify the desired number of voxels along one axis"},
+ {MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE,
+ "VOXEL_SIZE",
+ 0,
+ "Voxel Size",
+ "Specify the 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");
@@ -7115,12 +7143,33 @@ static void rna_def_modifier_mesh_to_volume(BlenderRNA *brna)
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, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Mode for the mesh to volume conversion");
+ RNA_def_property_update(prop, 0, "rna_Modifier_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", "The smaller this number the higher the resolution of the 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", "The desired 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_bandwidth", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Interior Bandwidth", "Width of the volume inside of the mesh");
RNA_def_property_range(prop, 0.0, FLT_MAX);
diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
index e41d1f9a291..d853d67f99c 100644
--- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
+++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
@@ -23,6 +23,7 @@
#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"
@@ -103,7 +104,11 @@ static void initData(ModifierData *md)
{
MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
mvmd->object = NULL;
+ mvmd->mode = MESH_TO_VOLUME_MODE_VOLUME;
+ 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_bandwidth = 1.0f;
mvmd->exterior_bandwidth = 1.0f;
}
@@ -133,14 +138,32 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
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, "voxel_size", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "interior_bandwidth", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "exterior_bandwidth", 0, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
+ if (mvmd->mode == MESH_TO_VOLUME_MODE_VOLUME) {
+ uiItemR(layout, ptr, "fill_volume", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "exterior_bandwidth", 0, NULL, ICON_NONE);
+ if (!mvmd->fill_volume) {
+ uiItemR(layout, ptr, "interior_bandwidth", 0, NULL, ICON_NONE);
+ }
+ }
+ else if (mvmd->mode == MESH_TO_VOLUME_MODE_SURFACE) {
+ uiItemR(layout, ptr, "exterior_bandwidth", 0, "Bandwidth", ICON_NONE);
+ }
+
+ uiItemR(layout, ptr, "resolution_mode", 0, NULL, ICON_NONE);
+ if (mvmd->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
+ uiItemR(layout, ptr, "voxel_amount", 0, NULL, ICON_NONE);
+ }
+ else {
+ uiItemR(layout, ptr, "voxel_size", 0, NULL, ICON_NONE);
+ }
modifier_panel_end(layout, ptr);
}
@@ -150,6 +173,25 @@ 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);
+ }
+ BoundBox *bb = BKE_object_boundbox_get(mvmd->object);
+
+ float3 dimensions = float3(bb->vec[6]) - float3(bb->vec[0]);
+ const float3 transformed_dimensions = transform.ref_3x3() * dimensions;
+ const float max_dimension = std::max(
+ {transformed_dimensions.x, transformed_dimensions.y, transformed_dimensions.z});
+ const float approximate_volume_side_length = max_dimension + mvmd->exterior_bandwidth * 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
@@ -165,28 +207,46 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo
}
Object *object_to_convert = mvmd->object;
- Mesh *mesh = static_cast<Mesh *>(object_to_convert->data);
- const float voxel_size = mvmd->voxel_size;
- const float exterior_bandwidth = MAX2(0.001f, mvmd->exterior_bandwidth / voxel_size);
- const float interior_bandwidth = MAX2(0.001f, mvmd->interior_bandwidth / voxel_size);
- UNUSED_VARS(voxel_size);
+ 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);
- float4x4 transform;
- scale_m4_fl(transform.values, 1.0f / voxel_size);
- mul_m4_m4_post(transform.values, ctx->object->imat);
- mul_m4_m4_post(transform.values, object_to_convert->obmat);
+ Mesh *mesh = static_cast<Mesh *>(object_to_convert->data);
+ OpenVDBMeshAdapter mesh_adapter{*mesh, mesh_to_index_space_transform};
- OpenVDBMeshAdapter mesh_adapter{*mesh, transform};
+ openvdb::FloatGrid::Ptr new_grid;
- openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
- mesh_adapter, {}, exterior_bandwidth, interior_bandwidth);
+ const float exterior_bandwidth = MAX2(0.001f, mvmd->exterior_bandwidth / voxel_size);
+ const float interior_bandwidth = MAX2(0.001f, mvmd->interior_bandwidth / voxel_size);
+ if (mvmd->mode == MESH_TO_VOLUME_MODE_VOLUME) {
+ if (mvmd->fill_volume) {
+ new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
+ mesh_adapter, {}, exterior_bandwidth, FLT_MAX);
+ }
+ else {
+ n
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list