Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/mesh_volume.cpp
| Show All 9 Lines | |||||
| * Unless required by applicable law or agreed to in writing, software | * Unless required by applicable law or agreed to in writing, software | ||||
| * distributed under the License is distributed on an "AS IS" BASIS, | * distributed under the License is distributed on an "AS IS" BASIS, | ||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| #include "render/attribute.h" | #include "render/attribute.h" | ||||
| #include "render/mesh.h" | |||||
| #include "render/scene.h" | #include "render/scene.h" | ||||
| #include "render/volume.h" | |||||
| #include "util/util_foreach.h" | #include "util/util_foreach.h" | ||||
| #include "util/util_hash.h" | #include "util/util_hash.h" | ||||
| #include "util/util_logging.h" | #include "util/util_logging.h" | ||||
| #include "util/util_progress.h" | #include "util/util_progress.h" | ||||
| #include "util/util_types.h" | #include "util/util_types.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| ▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | |||||
| /* ************************************************************************** */ | /* ************************************************************************** */ | ||||
| struct VoxelAttributeGrid { | struct VoxelAttributeGrid { | ||||
| float *data; | float *data; | ||||
| int channels; | int channels; | ||||
| }; | }; | ||||
| void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress) | void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) | ||||
| { | { | ||||
| string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str()); | string msg = string_printf("Computing Volume Mesh %s", volume->name.c_str()); | ||||
| progress.set_status("Updating Mesh", msg); | progress.set_status("Updating Mesh", msg); | ||||
| vector<VoxelAttributeGrid> voxel_grids; | vector<VoxelAttributeGrid> voxel_grids; | ||||
| /* Compute volume parameters. */ | /* Compute volume parameters. */ | ||||
| VolumeParams volume_params; | VolumeParams volume_params; | ||||
| volume_params.resolution = make_int3(0, 0, 0); | volume_params.resolution = make_int3(0, 0, 0); | ||||
| Transform transform = transform_identity(); | Transform transform = transform_identity(); | ||||
| foreach (Attribute &attr, mesh->attributes.attributes) { | foreach (Attribute &attr, volume->attributes.attributes) { | ||||
| if (attr.element != ATTR_ELEMENT_VOXEL) { | if (attr.element != ATTR_ELEMENT_VOXEL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ImageHandle &handle = attr.data_voxel(); | ImageHandle &handle = attr.data_voxel(); | ||||
| device_texture *image_memory = handle.image_memory(); | device_texture *image_memory = handle.image_memory(); | ||||
| int3 resolution = make_int3( | int3 resolution = make_int3( | ||||
| image_memory->data_width, image_memory->data_height, image_memory->data_depth); | image_memory->data_width, image_memory->data_height, image_memory->data_depth); | ||||
| Show All 21 Lines | void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) | ||||
| if (voxel_grids.empty()) { | if (voxel_grids.empty()) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Compute padding. */ | /* Compute padding. */ | ||||
| Shader *volume_shader = NULL; | Shader *volume_shader = NULL; | ||||
| int pad_size = 0; | int pad_size = 0; | ||||
| foreach (Shader *shader, mesh->used_shaders) { | foreach (Shader *shader, volume->used_shaders) { | ||||
| if (!shader->has_volume) { | if (!shader->has_volume) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| volume_shader = shader; | volume_shader = shader; | ||||
| if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) { | if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) { | ||||
| pad_size = max(1, pad_size); | pad_size = max(1, pad_size); | ||||
| Show All 19 Lines | void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) | ||||
| start_point = transform_point(&itfm, start_point); | start_point = transform_point(&itfm, start_point); | ||||
| cell_size = transform_direction(&itfm, cell_size); | cell_size = transform_direction(&itfm, cell_size); | ||||
| /* Slightly offset vertex coordinates to avoid overlapping faces with other | /* Slightly offset vertex coordinates to avoid overlapping faces with other | ||||
| * volumes or meshes. The proper solution would be to improve intersection in | * volumes or meshes. The proper solution would be to improve intersection in | ||||
| * the kernel to support robust handling of multiple overlapping faces or use | * the kernel to support robust handling of multiple overlapping faces or use | ||||
| * an all-hit intersection similar to shadows. */ | * an all-hit intersection similar to shadows. */ | ||||
| const float3 face_overlap_avoidance = cell_size * 0.1f * | const float3 face_overlap_avoidance = cell_size * 0.1f * | ||||
| hash_uint_to_float(hash_string(mesh->name.c_str())); | hash_uint_to_float(hash_string(volume->name.c_str())); | ||||
| volume_params.start_point = start_point + face_overlap_avoidance; | volume_params.start_point = start_point + face_overlap_avoidance; | ||||
| volume_params.cell_size = cell_size; | volume_params.cell_size = cell_size; | ||||
| volume_params.pad_size = pad_size; | volume_params.pad_size = pad_size; | ||||
| /* Build bounding mesh around non-empty volume cells. */ | /* Build bounding mesh around non-empty volume cells. */ | ||||
| VolumeMeshBuilder builder(&volume_params); | VolumeMeshBuilder builder(&volume_params); | ||||
| const float clipping = mesh->volume_clipping; | const float clipping = volume->clipping; | ||||
| for (int z = 0; z < resolution.z; ++z) { | for (int z = 0; z < resolution.z; ++z) { | ||||
| for (int y = 0; y < resolution.y; ++y) { | for (int y = 0; y < resolution.y; ++y) { | ||||
| for (int x = 0; x < resolution.x; ++x) { | for (int x = 0; x < resolution.x; ++x) { | ||||
| int64_t voxel_index = compute_voxel_index(resolution, x, y, z); | int64_t voxel_index = compute_voxel_index(resolution, x, y, z); | ||||
| for (size_t i = 0; i < voxel_grids.size(); ++i) { | for (size_t i = 0; i < voxel_grids.size(); ++i) { | ||||
| const VoxelAttributeGrid &voxel_grid = voxel_grids[i]; | const VoxelAttributeGrid &voxel_grid = voxel_grids[i]; | ||||
| Show All 11 Lines | void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) | ||||
| } | } | ||||
| /* Create mesh. */ | /* Create mesh. */ | ||||
| vector<float3> vertices; | vector<float3> vertices; | ||||
| vector<int> indices; | vector<int> indices; | ||||
| vector<float3> face_normals; | vector<float3> face_normals; | ||||
| builder.create_mesh(vertices, indices, face_normals); | builder.create_mesh(vertices, indices, face_normals); | ||||
| mesh->clear(true); | volume->clear(); | ||||
| mesh->reserve_mesh(vertices.size(), indices.size() / 3); | volume->reserve_mesh(vertices.size(), indices.size() / 3); | ||||
| mesh->used_shaders.push_back(volume_shader); | volume->used_shaders.push_back(volume_shader); | ||||
| for (size_t i = 0; i < vertices.size(); ++i) { | for (size_t i = 0; i < vertices.size(); ++i) { | ||||
| mesh->add_vertex(vertices[i]); | volume->add_vertex(vertices[i]); | ||||
| } | } | ||||
| for (size_t i = 0; i < indices.size(); i += 3) { | for (size_t i = 0; i < indices.size(); i += 3) { | ||||
| mesh->add_triangle(indices[i], indices[i + 1], indices[i + 2], 0, false); | volume->add_triangle(indices[i], indices[i + 1], indices[i + 2], 0, false); | ||||
| } | } | ||||
| Attribute *attr_fN = mesh->attributes.add(ATTR_STD_FACE_NORMAL); | Attribute *attr_fN = volume->attributes.add(ATTR_STD_FACE_NORMAL); | ||||
| float3 *fN = attr_fN->data_float3(); | float3 *fN = attr_fN->data_float3(); | ||||
| for (size_t i = 0; i < face_normals.size(); ++i) { | for (size_t i = 0; i < face_normals.size(); ++i) { | ||||
| fN[i] = face_normals[i]; | fN[i] = face_normals[i]; | ||||
| } | } | ||||
| /* Print stats. */ | /* Print stats. */ | ||||
| VLOG(1) << "Memory usage volume mesh: " | VLOG(1) << "Memory usage volume mesh: " | ||||
| Show All 11 Lines | |||||