diff options
Diffstat (limited to 'intern/cycles/scene/geometry.cpp')
-rw-r--r-- | intern/cycles/scene/geometry.cpp | 97 |
1 files changed, 89 insertions, 8 deletions
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index bf426fc49f6..558b0e13b0f 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -26,6 +26,7 @@ #include "scene/light.h" #include "scene/mesh.h" #include "scene/object.h" +#include "scene/pointcloud.h" #include "scene/scene.h" #include "scene/shader.h" #include "scene/shader_nodes.h" @@ -165,7 +166,8 @@ int Geometry::motion_step(float time) const bool Geometry::need_build_bvh(BVHLayout layout) const { return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX || - layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE; + layout == BVH_LAYOUT_METAL || layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE || + layout == BVH_LAYOUT_MULTI_METAL || layout == BVH_LAYOUT_MULTI_METAL_EMBREE; } bool Geometry::is_instanced() const @@ -239,6 +241,7 @@ void Geometry::compute_bvh( params->use_bvh_unaligned_nodes; bparams.num_motion_triangle_steps = params->num_bvh_time_steps; bparams.num_motion_curve_steps = params->num_bvh_time_steps; + bparams.num_motion_point_steps = params->num_bvh_time_steps; bparams.bvh_type = params->bvh_type; bparams.curve_subdivisions = params->curve_subdivisions(); @@ -722,6 +725,12 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom, else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION) offset -= hair->curve_key_offset; } + else if (geom->is_pointcloud()) { + if (element == ATTR_ELEMENT_VERTEX) + offset -= geom->prim_offset; + else if (element == ATTR_ELEMENT_VERTEX_MOTION) + offset -= geom->prim_offset; + } } else { /* attribute not found */ @@ -1005,6 +1014,8 @@ void GeometryManager::mesh_calc_offset(Scene *scene, BVHLayout bvh_layout) size_t curve_key_size = 0; size_t curve_segment_size = 0; + size_t point_size = 0; + size_t patch_size = 0; size_t face_size = 0; size_t corner_size = 0; @@ -1053,6 +1064,14 @@ void GeometryManager::mesh_calc_offset(Scene *scene, BVHLayout bvh_layout) curve_key_size += hair->get_curve_keys().size(); curve_segment_size += hair->num_segments(); } + else if (geom->is_pointcloud()) { + PointCloud *pointcloud = static_cast<PointCloud *>(geom); + + prim_offset_changed = (pointcloud->prim_offset != point_size); + + pointcloud->prim_offset = point_size; + point_size += pointcloud->num_points(); + } if (prim_offset_changed) { /* Need to rebuild BVH in OptiX, since refit only allows modified mesh data there */ @@ -1078,6 +1097,8 @@ void GeometryManager::device_update_mesh(Device *, size_t curve_size = 0; size_t curve_segment_size = 0; + size_t point_size = 0; + size_t patch_size = 0; foreach (Geometry *geom, scene->geometry) { @@ -1105,6 +1126,10 @@ void GeometryManager::device_update_mesh(Device *, curve_size += hair->num_curves(); curve_segment_size += hair->num_segments(); } + else if (geom->is_pointcloud()) { + PointCloud *pointcloud = static_cast<PointCloud *>(geom); + point_size += pointcloud->num_points(); + } } /* Fill in all the arrays. */ @@ -1200,6 +1225,26 @@ void GeometryManager::device_update_mesh(Device *, dscene->curve_segments.copy_to_device_if_modified(); } + if (point_size != 0) { + progress.set_status("Updating Mesh", "Copying Point clouds to device"); + + float4 *points = dscene->points.alloc(point_size); + uint *points_shader = dscene->points_shader.alloc(point_size); + + foreach (Geometry *geom, scene->geometry) { + if (geom->is_pointcloud()) { + PointCloud *pointcloud = static_cast<PointCloud *>(geom); + pointcloud->pack( + scene, &points[pointcloud->prim_offset], &points_shader[pointcloud->prim_offset]); + if (progress.get_cancel()) + return; + } + } + + dscene->points.copy_to_device(); + dscene->points_shader.copy_to_device(); + } + if (patch_size != 0 && dscene->patches.need_realloc()) { progress.set_status("Updating Mesh", "Copying Patches to device"); @@ -1241,13 +1286,15 @@ void GeometryManager::device_update_bvh(Device *device, scene->params.use_bvh_unaligned_nodes; bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps; bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps; + bparams.num_motion_point_steps = scene->params.num_bvh_time_steps; bparams.bvh_type = scene->params.bvh_type; bparams.curve_subdivisions = scene->params.curve_subdivisions(); VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout."; const bool can_refit = scene->bvh != nullptr && - (bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX); + (bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX || + bparams.bvh_layout == BVHLayout::BVH_LAYOUT_METAL); BVH *bvh = scene->bvh; if (!scene->bvh) { @@ -1321,6 +1368,7 @@ void GeometryManager::device_update_bvh(Device *device, enum { DEVICE_CURVE_DATA_MODIFIED = (1 << 0), DEVICE_MESH_DATA_MODIFIED = (1 << 1), + DEVICE_POINT_DATA_MODIFIED = (1 << 2), ATTR_FLOAT_MODIFIED = (1 << 2), ATTR_FLOAT2_MODIFIED = (1 << 3), @@ -1330,17 +1378,20 @@ enum { CURVE_DATA_NEED_REALLOC = (1 << 7), MESH_DATA_NEED_REALLOC = (1 << 8), + POINT_DATA_NEED_REALLOC = (1 << 9), + + ATTR_FLOAT_NEEDS_REALLOC = (1 << 10), + ATTR_FLOAT2_NEEDS_REALLOC = (1 << 11), + ATTR_FLOAT3_NEEDS_REALLOC = (1 << 12), + ATTR_FLOAT4_NEEDS_REALLOC = (1 << 13), - ATTR_FLOAT_NEEDS_REALLOC = (1 << 9), - ATTR_FLOAT2_NEEDS_REALLOC = (1 << 10), - ATTR_FLOAT3_NEEDS_REALLOC = (1 << 11), - ATTR_FLOAT4_NEEDS_REALLOC = (1 << 12), - ATTR_UCHAR4_NEEDS_REALLOC = (1 << 13), + ATTR_UCHAR4_NEEDS_REALLOC = (1 << 14), ATTRS_NEED_REALLOC = (ATTR_FLOAT_NEEDS_REALLOC | ATTR_FLOAT2_NEEDS_REALLOC | ATTR_FLOAT3_NEEDS_REALLOC | ATTR_FLOAT4_NEEDS_REALLOC | ATTR_UCHAR4_NEEDS_REALLOC), DEVICE_MESH_DATA_NEEDS_REALLOC = (MESH_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC), + DEVICE_POINT_DATA_NEEDS_REALLOC = (POINT_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC), DEVICE_CURVE_DATA_NEEDS_REALLOC = (CURVE_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC), }; @@ -1527,6 +1578,17 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro device_update_flags |= DEVICE_MESH_DATA_MODIFIED; } } + + if (geom->is_pointcloud()) { + PointCloud *pointcloud = static_cast<PointCloud *>(geom); + + if (pointcloud->need_update_rebuild) { + device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC; + } + else if (pointcloud->is_modified()) { + device_update_flags |= DEVICE_POINT_DATA_MODIFIED; + } + } } if (update_flags & (MESH_ADDED | MESH_REMOVED)) { @@ -1537,10 +1599,15 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC; } + if (update_flags & (POINT_ADDED | POINT_REMOVED)) { + device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC; + } + /* tag the device arrays for reallocation or modification */ DeviceScene *dscene = &scene->dscene; - if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC)) { + if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC | + DEVICE_POINT_DATA_NEEDS_REALLOC)) { delete scene->bvh; scene->bvh = nullptr; @@ -1568,6 +1635,11 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro dscene->curve_keys.tag_realloc(); dscene->curve_segments.tag_realloc(); } + + if (device_update_flags & DEVICE_POINT_DATA_NEEDS_REALLOC) { + dscene->points.tag_realloc(); + dscene->points_shader.tag_realloc(); + } } if ((update_flags & VISIBILITY_MODIFIED) != 0) { @@ -1628,6 +1700,11 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro dscene->curve_segments.tag_modified(); } + if (device_update_flags & DEVICE_POINT_DATA_MODIFIED) { + dscene->points.tag_modified(); + dscene->points_shader.tag_modified(); + } + need_flags_update = false; } @@ -2062,6 +2139,8 @@ void GeometryManager::device_update(Device *device, dscene->curves.clear_modified(); dscene->curve_keys.clear_modified(); dscene->curve_segments.clear_modified(); + dscene->points.clear_modified(); + dscene->points_shader.clear_modified(); dscene->patches.clear_modified(); dscene->attributes_map.clear_modified(); dscene->attributes_float.clear_modified(); @@ -2090,6 +2169,8 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc dscene->curves.free_if_need_realloc(force_free); dscene->curve_keys.free_if_need_realloc(force_free); dscene->curve_segments.free_if_need_realloc(force_free); + dscene->points.free_if_need_realloc(force_free); + dscene->points_shader.free_if_need_realloc(force_free); dscene->patches.free_if_need_realloc(force_free); dscene->attributes_map.free_if_need_realloc(force_free); dscene->attributes_float.free_if_need_realloc(force_free); |