21 # include <openvdb/openvdb.h>
22 # include <openvdb/tools/Dense.h>
29 template<
typename Gr
idType,
typename VoxelType>
30 static void extract_dense_voxels(
const openvdb::GridBase &grid,
31 const openvdb::CoordBBox bbox,
35 openvdb::tools::Dense<VoxelType, openvdb::tools::LayoutXYZ> dense(bbox, r_voxels);
36 openvdb::tools::copyToDense(
static_cast<const GridType &
>(grid), dense);
39 static void extract_dense_float_voxels(
const VolumeGridType grid_type,
40 const openvdb::GridBase &grid,
41 const openvdb::CoordBBox &bbox,
46 return extract_dense_voxels<openvdb::BoolGrid, float>(grid, bbox, r_voxels);
48 return extract_dense_voxels<openvdb::FloatGrid, float>(grid, bbox, r_voxels);
50 return extract_dense_voxels<openvdb::DoubleGrid, float>(grid, bbox, r_voxels);
52 return extract_dense_voxels<openvdb::Int32Grid, float>(grid, bbox, r_voxels);
54 return extract_dense_voxels<openvdb::Int64Grid, float>(grid, bbox, r_voxels);
56 return extract_dense_voxels<openvdb::MaskGrid, float>(grid, bbox, r_voxels);
58 return extract_dense_voxels<openvdb::Vec3fGrid, openvdb::Vec3f>(
61 return extract_dense_voxels<openvdb::Vec3dGrid, openvdb::Vec3f>(
64 return extract_dense_voxels<openvdb::Vec3IGrid, openvdb::Vec3f>(
73 static void create_texture_to_object_matrix(
const openvdb::Mat4d &grid_transform,
74 const openvdb::CoordBBox &bbox,
75 float r_texture_to_object[4][4])
77 float index_to_object[4][4];
78 memcpy(index_to_object, openvdb::Mat4s(grid_transform).asPointer(),
sizeof(index_to_object));
80 float texture_to_index[4][4];
86 mul_m4_m4m4(r_texture_to_object, index_to_object, texture_to_index);
97 openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
99 const openvdb::CoordBBox bbox = grid->evalActiveVoxelBoundingBox();
106 static_cast<int64_t>(resolution[1]) *
107 static_cast<int64_t>(resolution[2]);
110 float *voxels =
static_cast<float *
>(
MEM_malloc_arrayN(num_voxels, elem_size, __func__));
111 if (voxels ==
nullptr) {
115 extract_dense_float_voxels(grid_type, *grid, bbox, voxels);
116 create_texture_to_object_matrix(grid->transform().baseMap()->getAffineMap()->getMat4(),
120 r_dense_grid->
voxels = voxels;
131 if (dense_grid->
voxels !=
nullptr) {
141 template<
typename Gr
idType>
145 using TreeType =
typename GridType::TreeType;
146 using Depth2Type =
typename TreeType::RootNodeType::ChildNodeType::ChildNodeType;
147 using NodeCIter =
typename TreeType::NodeCIter;
150 const int depth = coarse ? 2 : 3;
152 NodeCIter iter = grid.tree().cbeginNode();
153 iter.setMaxDepth(depth);
155 for (; iter; ++iter) {
156 if (iter.getDepth() != depth) {
160 openvdb::CoordBBox box;
163 const Depth2Type *
node =
nullptr;
166 node->evalActiveBoundingBox(box,
false);
174 if (!iter.getBoundingBox(box)) {
180 box.max() = box.max().offsetBy(1);
188 struct GetBoundingBoxesOp {
189 const openvdb::GridBase &grid;
194 return get_bounding_boxes(
static_cast<const GridType &
>(grid), coarse);
199 const openvdb::GridBase &grid,
202 GetBoundingBoxesOp op{grid, coarse};
203 return BKE_volume_grid_type_operation(grid_type, op);
223 const openvdb::CoordBBox &box = boxes[i];
226 std::array<openvdb::Coord, 8> corners;
227 box.getCornerPoints(corners.data());
229 for (
int j = 0; j < 8; j++) {
230 openvdb::Coord corner_i = corners[j];
232 r_verts[8 * i + j] =
blender::float3(corner_d[0], corner_d[1], corner_d[2]);
244 const int box_edges[12][2] = {
259 int vert_offset = r_verts.
size();
260 int edge_offset = r_edges.size();
262 const int vert_amount = 8 * boxes.
size();
263 const int edge_amount = 12 * boxes.
size();
266 r_edges.resize(r_edges.size() + edge_amount);
269 for (
int i = 0; i < boxes.
size(); i++) {
270 for (
int j = 0; j < 12; j++) {
271 r_edges[edge_offset + j] = {vert_offset + box_edges[j][0], vert_offset + box_edges[j][1]};
283 const int box_tris[12][3] = {
298 int vert_offset = r_verts.
size();
299 int tri_offset = r_tris.size();
301 const int vert_amount = 8 * boxes.
size();
302 const int tri_amount = 12 * boxes.
size();
305 r_tris.resize(r_tris.size() + tri_amount);
308 for (
int i = 0; i < boxes.
size(); i++) {
309 for (
int j = 0; j < 12; j++) {
310 r_tris[tri_offset + j] = {vert_offset + box_tris[j][0],
311 vert_offset + box_tris[j][1],
312 vert_offset + box_tris[j][2]};
327 cb(cb_userdata,
nullptr,
nullptr, 0, 0);
332 openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
336 openvdb::CoordBBox box;
339 if (grid->baseTree().evalLeafBoundingBox(box)) {
340 boxes_to_edge_mesh({box}, grid->transform(),
verts, edges);
343 (
float(*)[3])
verts.data(),
344 (
int(*)[2])edges.
data(),
359 boxes_to_center_points(boxes, grid->transform(),
verts);
362 boxes_to_edge_mesh(boxes, grid->transform(),
verts, edges);
366 (
float(*)[3])
verts.data(),
367 (
int(*)[2])edges.
data(),
374 cb(cb_userdata,
nullptr,
nullptr, 0, 0);
386 for (
const std::array<int, 3> &tri : tris) {
387 offsets[tri[0]] += factor * (2 *
verts[tri[0]] -
verts[tri[1]] -
verts[tri[2]]);
388 offsets[tri[1]] += factor * (2 *
verts[tri[1]] -
verts[tri[0]] -
verts[tri[2]]);
389 offsets[tri[2]] += factor * (2 *
verts[tri[2]] -
verts[tri[0]] -
verts[tri[1]]);
392 for (
const int i :
verts.index_range()) {
393 verts[i] += offsets[i];
404 openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
410 boxes_to_cube_mesh(boxes, grid->transform(),
verts, tris);
414 const float offset_factor = 0.01f;
415 grow_triangles(
verts, tris, offset_factor);
417 cb(cb_userdata, (
float(*)[3])
verts.data(), (
int(*)[3])tris.
data(),
verts.size(), tris.
size());
420 cb(cb_userdata,
nullptr,
nullptr, 0, 0);
429 float unit[3] = {1.0f, 1.0f, 1.0f};
432 return 1.0f /
len_v3(unit);
typedef float(TangentPoint)[2]
VolumeGridType BKE_volume_grid_type(const struct VolumeGrid *grid)
@ VOLUME_GRID_VECTOR_FLOAT
@ VOLUME_GRID_VECTOR_DOUBLE
int BKE_volume_grid_channels(const struct VolumeGrid *grid)
Volume data-block rendering and viewport drawing utilities.
void(* BKE_volume_wireframe_cb)(void *userdata, const float(*verts)[3], const int(*edges)[2], int totvert, int totedge)
void(* BKE_volume_selection_surface_cb)(void *userdata, float(*verts)[3], int(*tris)[3], int totvert, int tottris)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_mat3_m4_v3(const float M[4][4], float r[3])
void size_to_mat4(float R[4][4], const float size[3])
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
@ VOLUME_WIREFRAME_POINTS
@ VOLUME_WIREFRAME_BOUNDS
@ VOLUME_WIREFRAME_COARSE
NSNotificationCenter * center
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
MutableSpan< T > as_mutable_span()
void append(const T &value)
void resize(const int64_t new_size)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
VecMat::Vec3< double > Vec3d
VecMat::Vec3< int > Vec3i
vec_base< float, 3 > float3
float texture_to_object[4][4]
bool BKE_volume_grid_dense_floats(const Volume *volume, const VolumeGrid *volume_grid, DenseFloatVolumeGrid *r_dense_grid)
void BKE_volume_dense_float_grid_clear(DenseFloatVolumeGrid *dense_grid)
void BKE_volume_grid_wireframe(const Volume *volume, const VolumeGrid *volume_grid, BKE_volume_wireframe_cb cb, void *cb_userdata)
float BKE_volume_density_scale(const Volume *volume, const float matrix[4][4])
void BKE_volume_grid_selection_surface(const Volume *volume, const VolumeGrid *volume_grid, BKE_volume_selection_surface_cb cb, void *cb_userdata)