Blender  V3.3
MOD_mesh_to_volume.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <vector>
8 
9 #include "BKE_geometry_set.hh"
10 #include "BKE_lib_id.h"
11 #include "BKE_lib_query.h"
12 #include "BKE_mesh_runtime.h"
13 #include "BKE_mesh_wrapper.h"
14 #include "BKE_modifier.h"
15 #include "BKE_object.h"
16 #include "BKE_volume.h"
17 
18 #include "BLT_translation.h"
19 
20 #include "DNA_mesh_types.h"
21 #include "DNA_meshdata_types.h"
22 #include "DNA_object_types.h"
23 #include "DNA_screen_types.h"
24 #include "DNA_volume_types.h"
25 
26 #include "DEG_depsgraph.h"
27 
28 #include "GEO_mesh_to_volume.hh"
29 
30 #include "UI_interface.h"
31 #include "UI_resources.h"
32 
33 #include "BLO_read_write.h"
34 
35 #include "MEM_guardedalloc.h"
36 
37 #include "MOD_modifiertypes.h"
38 #include "MOD_ui_common.h"
39 
40 #include "BLI_float4x4.hh"
41 #include "BLI_index_range.hh"
42 #include "BLI_span.hh"
43 
44 #include "RNA_access.h"
45 #include "RNA_prototypes.h"
46 
47 static void initData(ModifierData *md)
48 {
49  MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
50  mvmd->object = nullptr;
52  mvmd->voxel_size = 0.1f;
53  mvmd->voxel_amount = 32;
54  mvmd->fill_volume = true;
55  mvmd->interior_band_width = 0.1f;
56  mvmd->exterior_band_width = 0.1f;
57  mvmd->density = 1.0f;
58 }
59 
61 {
62  MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
63  DEG_add_modifier_to_transform_relation(ctx->node, "Mesh to Volume Modifier");
64  if (mvmd->object) {
66  ctx->node, mvmd->object, DEG_OB_COMP_GEOMETRY, "Mesh to Volume Modifier");
68  ctx->node, mvmd->object, DEG_OB_COMP_TRANSFORM, "Mesh to Volume Modifier");
69  }
70 }
71 
72 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
73 {
74  MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
75  walk(userData, ob, (ID **)&mvmd->object, IDWALK_CB_NOP);
76 }
77 
78 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
79 {
80  uiLayout *layout = panel->layout;
81 
84 
85  uiLayoutSetPropSep(layout, true);
86 
87  uiItemR(layout, ptr, "object", 0, nullptr, ICON_NONE);
88  uiItemR(layout, ptr, "density", 0, nullptr, ICON_NONE);
89 
90  {
91  uiLayout *col = uiLayoutColumn(layout, false);
92  uiItemR(col, ptr, "use_fill_volume", 0, nullptr, ICON_NONE);
93  uiItemR(col, ptr, "exterior_band_width", 0, nullptr, ICON_NONE);
94 
95  uiLayout *subcol = uiLayoutColumn(col, false);
96  uiLayoutSetActive(subcol, !mvmd->fill_volume);
97  uiItemR(subcol, ptr, "interior_band_width", 0, nullptr, ICON_NONE);
98  }
99  {
100  uiLayout *col = uiLayoutColumn(layout, false);
101  uiItemR(col, ptr, "resolution_mode", 0, nullptr, ICON_NONE);
103  uiItemR(col, ptr, "voxel_amount", 0, nullptr, ICON_NONE);
104  }
105  else {
106  uiItemR(col, ptr, "voxel_size", 0, nullptr, ICON_NONE);
107  }
108  }
109 
110  modifier_panel_end(layout, ptr);
111 }
112 
113 static void panelRegister(ARegionType *region_type)
114 {
116 }
117 
119  const ModifierEvalContext *ctx,
120  Volume *input_volume)
121 {
122 #ifdef WITH_OPENVDB
123  using namespace blender;
124 
125  MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
126  Object *object_to_convert = mvmd->object;
127 
128  if (object_to_convert == nullptr) {
129  return input_volume;
130  }
132  if (mesh == nullptr) {
133  return input_volume;
134  }
136 
137  const float4x4 mesh_to_own_object_space_transform = float4x4(ctx->object->imat) *
138  float4x4(object_to_convert->obmat);
142  resolution.settings.voxel_amount = mvmd->voxel_amount;
143  if (resolution.settings.voxel_amount <= 0.0f) {
144  return input_volume;
145  }
146  }
147  else if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
148  resolution.settings.voxel_size = mvmd->voxel_size;
149  if (resolution.settings.voxel_size <= 0.0f) {
150  return input_volume;
151  }
152  }
153 
154  auto bounds_fn = [&](float3 &r_min, float3 &r_max) {
155  const BoundBox *bb = BKE_object_boundbox_get(mvmd->object);
156  r_min = bb->vec[0];
157  r_max = bb->vec[6];
158  };
159 
160  const float voxel_size = geometry::volume_compute_voxel_size(ctx->depsgraph,
161  bounds_fn,
162  resolution,
163  mvmd->exterior_band_width,
164  mesh_to_own_object_space_transform);
165 
166  /* Create a new volume. */
167  Volume *volume;
168  if (input_volume == nullptr) {
169  volume = static_cast<Volume *>(BKE_id_new_nomain(ID_VO, "Volume"));
170  }
171  else {
172  volume = BKE_volume_new_for_eval(input_volume);
173  }
174 
175  /* Convert mesh to grid and add to volume. */
176  geometry::volume_grid_add_from_mesh(volume,
177  "density",
178  mesh,
179  mesh_to_own_object_space_transform,
180  voxel_size,
181  mvmd->fill_volume,
182  mvmd->exterior_band_width,
183  mvmd->interior_band_width,
184  mvmd->density);
185 
186  return volume;
187 
188 #else
189  UNUSED_VARS(md);
190  BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
191  return input_volume;
192 #endif
193 }
194 
196  const ModifierEvalContext *ctx,
197  GeometrySet *geometry_set)
198 {
199  Volume *input_volume = geometry_set->get_volume_for_write();
200  Volume *result_volume = mesh_to_volume(md, ctx, input_volume);
201  if (result_volume != input_volume) {
202  geometry_set->replace_volume(result_volume);
203  }
204 }
205 
207  /* name */ N_("Mesh to Volume"),
208  /* structName */ "MeshToVolumeModifierData",
209  /* structSize */ sizeof(MeshToVolumeModifierData),
210  /* srna */ &RNA_MeshToVolumeModifier,
212  /* flags */ static_cast<ModifierTypeFlag>(0),
213  /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */
214 
215  /* copyData */ BKE_modifier_copydata_generic,
216 
217  /* deformVerts */ nullptr,
218  /* deformMatrices */ nullptr,
219  /* deformVertsEM */ nullptr,
220  /* deformMatricesEM */ nullptr,
221  /* modifyMesh */ nullptr,
222  /* modifyGeometrySet */ modifyGeometrySet,
223 
224  /* initData */ initData,
225  /* requiredDataMask */ nullptr,
226  /* freeData */ nullptr,
227  /* isDisabled */ nullptr,
228  /* updateDepsgraph */ updateDepsgraph,
229  /* dependsOnTime */ nullptr,
230  /* dependsOnNormals */ nullptr,
231  /* foreachIDLink */ foreachIDLink,
232  /* foreachTexLink */ nullptr,
233  /* freeRuntimeData */ nullptr,
234  /* panelRegister */ panelRegister,
235  /* blendWrite */ nullptr,
236  /* blendRead */ nullptr,
237 };
void * BKE_id_new_nomain(short type, const char *name)
Definition: lib_id.c:1173
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
ModifierTypeFlag
Definition: BKE_modifier.h:65
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
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.
const struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.cc:3684
Volume data-block.
struct Volume * BKE_volume_new_for_eval(const struct Volume *volume_src)
#define UNUSED_VARS(...)
#define UNUSED(x)
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
@ ID_VO
Definition: DNA_ID_enums.h:83
struct MeshToVolumeModifierData MeshToVolumeModifierData
@ eModifierType_MeshToVolume
MeshToVolumeModifierResolutionMode
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT
Object is a sort of wrapper for general info.
float float4x4[4][4]
Read Guarded memory(de)allocation.
static Volume * mesh_to_volume(ModifierData *md, const ModifierEvalContext *ctx, Volume *input_volume)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
ModifierTypeInfo modifierType_MeshToVolume
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void modifyGeometrySet(ModifierData *md, const ModifierEvalContext *ctx, GeometrySet *geometry_set)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
#define C
Definition: RandGen.cpp:25
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
uint col
float vec[8][3]
void replace_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Volume * get_volume_for_write()
Definition: DNA_ID.h:368
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
struct Object * object
Definition: BKE_modifier.h:141
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
float imat[4][4]
float obmat[4][4]
struct uiLayout * layout
void * data
Definition: RNA_types.h:38
union blender::geometry::MeshToVolumeResolution::@636 settings
MeshToVolumeModifierResolutionMode mode
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480