From e665f0f497f6ea6a4cff36e977bbac29dd762c00 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 31 Aug 2022 18:04:15 +0200 Subject: Fix T100714: Cycles volume render artifacts with negative value grids The volume bounds were not constructed correctly in this case. --- intern/cycles/scene/volume.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'intern') diff --git a/intern/cycles/scene/volume.cpp b/intern/cycles/scene/volume.cpp index 77955350305..337e1833a42 100644 --- a/intern/cycles/scene/volume.cpp +++ b/intern/cycles/scene/volume.cpp @@ -183,7 +183,7 @@ class VolumeMeshBuilder { typename GridType::ValueOnIter iter = copy->beginValueOn(); for (; iter; ++iter) { - if (iter.getValue() < ValueType(volume_clipping)) { + if (openvdb::math::Abs(iter.getValue()) < ValueType(volume_clipping)) { iter.setValueOff(); } } @@ -294,6 +294,12 @@ void VolumeMeshBuilder::create_mesh(vector &vertices, #endif } +static bool is_non_empty_leaf(const openvdb::MaskGrid::TreeType &tree, const openvdb::Coord coord) +{ + auto *leaf_node = tree.probeLeaf(coord); + return (leaf_node && !leaf_node->isEmpty()); +} + void VolumeMeshBuilder::generate_vertices_and_quads(vector &vertices_is, vector &quads) { @@ -306,6 +312,10 @@ void VolumeMeshBuilder::generate_vertices_and_quads(vector &vertices_ unordered_map used_verts; for (auto iter = tree.cbeginLeaf(); iter; ++iter) { + if (iter->isEmpty()) { + continue; + } + openvdb::CoordBBox leaf_bbox = iter->getNodeBoundingBox(); /* +1 to convert from exclusive to include bounds. */ leaf_bbox.max() = leaf_bbox.max().offsetBy(1); @@ -333,27 +343,27 @@ void VolumeMeshBuilder::generate_vertices_and_quads(vector &vertices_ static const int LEAF_DIM = openvdb::MaskGrid::TreeType::LeafNodeType::DIM; auto center = leaf_bbox.min() + openvdb::Coord(LEAF_DIM / 2); - if (!tree.probeLeaf(openvdb::Coord(center.x() - LEAF_DIM, center.y(), center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x() - LEAF_DIM, center.y(), center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x() + LEAF_DIM, center.y(), center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x() + LEAF_DIM, center.y(), center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MAX); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() - LEAF_DIM, center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y() - LEAF_DIM, center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() + LEAF_DIM, center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y() + LEAF_DIM, center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MAX); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() - LEAF_DIM))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y(), center.z() - LEAF_DIM))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() + LEAF_DIM))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y(), center.z() + LEAF_DIM))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MAX); } } -- cgit v1.2.3