From 31c2e4b3e9e943d5567a6c2ac6f460af9d8fcdfb Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Wed, 4 Feb 2026 15:02:15 +0200 Subject: [PATCH 01/15] Add copy, move, and clone support to RaycastingScene #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 150 +++++++++++++++++++++- cpp/open3d/t/geometry/RaycastingScene.h | 14 ++ 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 4f4c496ac51..0e26a7f6706 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -361,12 +361,17 @@ struct RaycastingScene::Impl { RTCDevice device_; // Vector for storing some information about the added geometry. std::vector geometry_ptrs_; + // (num_vertices, num_triangles) per geometry, for copy support. + std::vector> geometry_sizes_; core::Device tensor_device_; // cpu or sycl bool devprop_join_commit; virtual ~Impl() = default; + /// Returns a deep copy of this implementation (new device and scene). + virtual std::unique_ptr Clone() const = 0; + void CommitScene() { if (!scene_committed_) { if (devprop_join_commit) { @@ -818,6 +823,73 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { void CopyArray(int* src, uint32_t* dst, size_t num_elements) override { queue_.memcpy(dst, src, num_elements * sizeof(uint32_t)).wait(); } + + std::unique_ptr Clone() const override { + auto copy = std::make_unique(); + const_cast(copy.get())->InitializeDevice(); + copy->tensor_device_ = tensor_device_; + rtcSetDeviceErrorFunction(copy->device_, ErrorFunction, NULL); + copy->scene_ = rtcNewScene(copy->device_); + rtcSetSceneFlags(copy->scene_, + RTC_SCENE_FLAG_ROBUST | + RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS); + copy->devprop_join_commit = rtcGetDeviceProperty( + copy->device_, RTC_DEVICE_PROPERTY_JOIN_COMMIT_SUPPORTED); + copy->scene_committed_ = false; + copy->geometry_sizes_ = geometry_sizes_; + + const SYCLImpl* src = this; + SYCLImpl* dst = copy.get(); + + std::vector host_vb; + std::vector host_ib; + for (size_t geom_id = 0; geom_id < geometry_ptrs_.size(); ++geom_id) { + const size_t num_vertices = geometry_sizes_[geom_id].first; + const size_t num_triangles = geometry_sizes_[geom_id].second; + const size_t vb_bytes = 3 * sizeof(float) * num_vertices; + const size_t ib_bytes = 3 * sizeof(uint32_t) * num_triangles; + + RTCGeometry src_geom = rtcGetGeometry(scene_, geom_id); + const void* vb_src = rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_VERTEX, 0); + const void* ib_src = rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_INDEX, 0); + + RTCGeometry geom = + rtcNewGeometry(dst->device_, RTC_GEOMETRY_TYPE_TRIANGLE); + void* vertex_buffer = rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, + 3 * sizeof(float), num_vertices); + void* index_buffer = rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, + 3 * sizeof(uint32_t), num_triangles); + + host_vb.resize(num_vertices * 3); + host_ib.resize(num_triangles * 3); + auto event1 = src->queue_.memcpy(host_vb.data(), vb_src, vb_bytes); + auto event2 = src->queue_.memcpy(host_ib.data(), ib_src, ib_bytes); + + sycl::event::wait({event1, event2}); + + auto event3 = + dst->queue_.memcpy(vertex_buffer, host_vb.data(), vb_bytes); + auto event4 = + dst->queue_.memcpy(index_buffer, host_ib.data(), ib_bytes); + + sycl::event::wait({event3, event4}); + + rtcSetGeometryEnableFilterFunctionFromArguments(geom, true); + rtcCommitGeometry(geom); + rtcAttachGeometry(dst->scene_, geom); + rtcReleaseGeometry(geom); + + GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, + (const void*)vertex_buffer, + (const void*)index_buffer}; + dst->geometry_ptrs_.push_back(geometry_ptr); + } + return copy; + } }; #endif @@ -1186,6 +1258,57 @@ struct RaycastingScene::CPUImpl : public RaycastingScene::Impl { void CopyArray(int* src, uint32_t* dst, size_t num_elements) override { std::copy(src, src + num_elements, dst); } + + std::unique_ptr Clone() const override { + auto copy = std::make_unique(); + copy->device_ = rtcNewDevice(NULL); + rtcSetDeviceErrorFunction(copy->device_, ErrorFunction, NULL); + copy->scene_ = rtcNewScene(copy->device_); + rtcSetSceneFlags(copy->scene_, + RTC_SCENE_FLAG_ROBUST | + RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS); + copy->devprop_join_commit = rtcGetDeviceProperty( + copy->device_, RTC_DEVICE_PROPERTY_JOIN_COMMIT_SUPPORTED); + copy->scene_committed_ = false; + copy->tensor_device_ = tensor_device_; + copy->geometry_sizes_ = geometry_sizes_; + + for (size_t geom_id = 0; geom_id < geometry_ptrs_.size(); ++geom_id) { + const size_t num_vertices = geometry_sizes_[geom_id].first; + const size_t num_triangles = geometry_sizes_[geom_id].second; + + RTCGeometry src_geom = rtcGetGeometry(scene_, geom_id); + const float* vb_src = (const float*)rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_VERTEX, 0); + const uint32_t* ib_src = (const uint32_t*)rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_INDEX, 0); + + RTCGeometry geom = + rtcNewGeometry(copy->device_, RTC_GEOMETRY_TYPE_TRIANGLE); + float* vertex_buffer = (float*)rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, + 3 * sizeof(float), num_vertices); + uint32_t* index_buffer = (uint32_t*)rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, + 3 * sizeof(uint32_t), num_triangles); + + std::memcpy(vertex_buffer, vb_src, + 3 * sizeof(float) * num_vertices); + std::memcpy(index_buffer, ib_src, + 3 * sizeof(uint32_t) * num_triangles); + + rtcSetGeometryEnableFilterFunctionFromArguments(geom, true); + rtcCommitGeometry(geom); + rtcAttachGeometry(copy->scene_, geom); + rtcReleaseGeometry(geom); + + GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, + (const void*)vertex_buffer, + (const void*)index_buffer}; + copy->geometry_ptrs_.push_back(geometry_ptr); + } + return copy; + } }; RaycastingScene::RaycastingScene(int64_t nthreads, const core::Device& device) { @@ -1224,8 +1347,30 @@ RaycastingScene::RaycastingScene(int64_t nthreads, const core::Device& device) { } RaycastingScene::~RaycastingScene() { - rtcReleaseScene(impl_->scene_); - rtcReleaseDevice(impl_->device_); + if (impl_) { + rtcReleaseScene(impl_->scene_); + rtcReleaseDevice(impl_->device_); + } +} + +RaycastingScene::RaycastingScene(const RaycastingScene& other) + : impl_(other.impl_->Clone()) {} + +RaycastingScene& RaycastingScene::operator=(const RaycastingScene& other) { + if (this != &other) { + impl_ = other.impl_->Clone(); + } + return *this; +} + +RaycastingScene::RaycastingScene(RaycastingScene&& other) noexcept + : impl_(std::move(other.impl_)) {} + +RaycastingScene& RaycastingScene::operator=(RaycastingScene&& other) noexcept { + if (this != &other) { + impl_ = std::move(other.impl_); + } + return *this; } uint32_t RaycastingScene::AddTriangles(const core::Tensor& vertex_positions, @@ -1298,6 +1443,7 @@ uint32_t RaycastingScene::AddTriangles(const core::Tensor& vertex_positions, (const void*)vertex_buffer, (const void*)index_buffer}; impl_->geometry_ptrs_.push_back(geometry_ptr); + impl_->geometry_sizes_.push_back({num_vertices, num_triangles}); return geom_id; } diff --git a/cpp/open3d/t/geometry/RaycastingScene.h b/cpp/open3d/t/geometry/RaycastingScene.h index 3f0ff7e3d5e..8a2e4acf61c 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.h +++ b/cpp/open3d/t/geometry/RaycastingScene.h @@ -35,6 +35,20 @@ class RaycastingScene { ~RaycastingScene(); + /// \brief Copy constructor. + /// Creates a new object as a copy of an existing one. + RaycastingScene(const RaycastingScene &other); + + /// \brief Copy assignment operator. + /// Assigns the contents of an existing object to this object. + RaycastingScene &operator=(const RaycastingScene &other); + + /// \brief Move constructor. + RaycastingScene(RaycastingScene &&other) noexcept; + + /// \brief Move assignment operator. + RaycastingScene &operator=(RaycastingScene &&other) noexcept; + /// \brief Add a triangle mesh to the scene. /// \param vertex_positions Vertices as Tensor of dim {N,3} and dtype float. /// \param triangle_indices Triangles as Tensor of dim {M,3} and dtype From 1b7aada097a3a660c10dcca64c3650043af1a2e7 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 5 Feb 2026 17:44:28 +0200 Subject: [PATCH 02/15] add RaycastingScene copy semantics tests #7014 --- cpp/pybind/t/geometry/raycasting_scene.cpp | 17 ++ .../test/t/geometry/test_raycasting_scene.py | 168 ++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/cpp/pybind/t/geometry/raycasting_scene.cpp b/cpp/pybind/t/geometry/raycasting_scene.cpp index 0d924fc749b..03a6c8f7bf4 100644 --- a/cpp/pybind/t/geometry/raycasting_scene.cpp +++ b/cpp/pybind/t/geometry/raycasting_scene.cpp @@ -67,6 +67,23 @@ Create a RaycastingScene. device (open3d.core.Device): The device to use. Currently CPU and SYCL devices are supported. )doc"); + raycasting_scene.def(py::init(), "other"_a, R"doc( +Create a RaycastingScene as a copy of another scene (copy constructor). + +Args: + other (open3d.t.geometry.RaycastingScene): The scene to copy. +)doc"); + + raycasting_scene.def("__copy__", + [](const RaycastingScene& self) { + return RaycastingScene(self); + }); + raycasting_scene.def("__deepcopy__", + [](const RaycastingScene& self, + py::dict /* memo */) { + return RaycastingScene(self); + }); + raycasting_scene.def( "add_triangles", py::overload_cast( diff --git a/python/test/t/geometry/test_raycasting_scene.py b/python/test/t/geometry/test_raycasting_scene.py index 2164f96d6fe..2af2a53f454 100755 --- a/python/test/t/geometry/test_raycasting_scene.py +++ b/python/test/t/geometry/test_raycasting_scene.py @@ -460,3 +460,171 @@ def test_sphere_wrong_occupancy(): # we should get the same result with more samples occupancy_3samples = scene.compute_occupancy(query_points, nsamples=3) np.testing.assert_equal(occupancy_3samples.numpy(), expected) + + +# --- Tests for copy constructor and copy semantics. --- +# These require Open3D built from source with the copy constructor binding. +# INVALID_ID is a property (no parentheses). Use .item() for scalar comparison. + + +def _raycasting_scene_copy_available(): + """True if RaycastingScene(scene) copy constructor is available (built from source).""" + try: + scene = o3d.t.geometry.RaycastingScene(device=o3d.core.Device("CPU:0")) + o3d.t.geometry.RaycastingScene(scene) + return True + except TypeError: + return False + + +@pytest.mark.parametrize("device", + list_devices(enable_cuda=False, enable_sycl=True)) +def test_copy_constructor_empty_scene(device): + if not _raycasting_scene_copy_available(): + pytest.skip( + "RaycastingScene copy constructor not available " + "(requires Open3D built from source with copy support)" + ) + scene = o3d.t.geometry.RaycastingScene(device=device) + scene_copy = o3d.t.geometry.RaycastingScene(scene) + rays = o3d.core.Tensor([[0, 0, 1, 0, 0, -1]], + dtype=o3d.core.float32, + device=device) + ans_orig = scene.cast_rays(rays) + ans_copy = scene_copy.cast_rays(rays) + invalid_id = o3d.t.geometry.RaycastingScene.INVALID_ID + assert ans_orig["geometry_ids"][0].cpu().item() == invalid_id + assert ans_copy["geometry_ids"][0].cpu().item() == invalid_id + assert np.isinf(ans_orig["t_hit"][0].item()) + assert np.isinf(ans_copy["t_hit"][0].item()) + + +@pytest.mark.parametrize("device", + list_devices(enable_cuda=False, enable_sycl=True)) +def test_copy_constructor_scene_with_geometry(device): + """Copy of a scene with geometry yields same cast_rays and compute_* results (tests clone).""" + if not _raycasting_scene_copy_available(): + pytest.skip( + "RaycastingScene copy constructor not available " + "(requires Open3D built from source with copy support)" + ) + vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], + dtype=o3d.core.float32, + device=device) + triangles = o3d.core.Tensor([[0, 1, 2]], + dtype=o3d.core.uint32, + device=device) + scene = o3d.t.geometry.RaycastingScene(device=device) + scene.add_triangles(vertices, triangles) + + scene_copy = o3d.t.geometry.RaycastingScene(scene) + + rays = o3d.core.Tensor( + [[0.2, 0.1, 1, 0, 0, -1], [10, 10, 10, 1, 0, 0]], + dtype=o3d.core.float32, + device=device, + ) + ans_orig = scene.cast_rays(rays) + ans_copy = scene_copy.cast_rays(rays) + + np.testing.assert_allclose(ans_orig["t_hit"].numpy(), + ans_copy["t_hit"].numpy()) + np.testing.assert_array_equal(ans_orig["geometry_ids"].numpy(), + ans_copy["geometry_ids"].numpy()) + + query = o3d.core.Tensor([[0.2, 0.1, 1], [10, 10, 10]], + dtype=o3d.core.float32, + device=device) + closest_orig = scene.compute_closest_points(query) + closest_copy = scene_copy.compute_closest_points(query) + np.testing.assert_allclose(closest_orig["points"].numpy(), + closest_copy["points"].numpy()) + np.testing.assert_array_equal(closest_orig["geometry_ids"].numpy(), + closest_copy["geometry_ids"].numpy()) + + dist_orig = scene.compute_distance(query) + dist_copy = scene_copy.compute_distance(query) + np.testing.assert_allclose(dist_orig.numpy(), dist_copy.numpy()) + + +@pytest.mark.parametrize("device", + list_devices(enable_cuda=False, enable_sycl=True)) +def test_copy_independence(device): + """Copy is independent: adding geometry to one does not affect the other.""" + if not _raycasting_scene_copy_available(): + pytest.skip( + "RaycastingScene copy constructor not available " + "(requires Open3D built from source with copy support)" + ) + vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], + dtype=o3d.core.float32, + device=device) + triangles = o3d.core.Tensor([[0, 1, 2]], + dtype=o3d.core.uint32, + device=device) + scene = o3d.t.geometry.RaycastingScene(device=device) + scene.add_triangles(vertices, triangles) + scene_copy = o3d.t.geometry.RaycastingScene(scene) + + # Add another triangle only to the copy + v2 = o3d.core.Tensor([[0, 0, 1], [1, 0, 1], [0, 1, 1]], + dtype=o3d.core.float32, + device=device) + t2 = o3d.core.Tensor([[0, 1, 2]], dtype=o3d.core.uint32, device=device) + scene_copy.add_triangles(v2, t2) + + invalid_id = o3d.t.geometry.RaycastingScene.INVALID_ID + # Ray hitting first triangle: both should hit + rays_one = o3d.core.Tensor( + [[0.2, 0.1, 0.5, 0, 0, -1]], + dtype=o3d.core.float32, + device=device, + ) + ans_orig = scene.cast_rays(rays_one) + ans_copy = scene_copy.cast_rays(rays_one) + assert ans_orig["geometry_ids"][0].cpu().item() != invalid_id + assert ans_copy["geometry_ids"][0].cpu().item() != invalid_id + + # Ray that would hit second triangle (only in copy): miss in original, hit in copy + rays_two = o3d.core.Tensor( + [[0.2, 0.1, 0.5, 0, 0, 1]], + dtype=o3d.core.float32, + device=device, + ) + ans_orig2 = scene.cast_rays(rays_two) + ans_copy2 = scene_copy.cast_rays(rays_two) + assert ans_orig2["geometry_ids"][0].cpu().item() == invalid_id + assert ans_copy2["geometry_ids"][0].cpu().item() != invalid_id + + +@pytest.mark.parametrize("device", + list_devices(enable_cuda=False, enable_sycl=True)) +def test_copy_module_copy(device): + """copy.copy(scene) works and produces an independent copy.""" + if not _raycasting_scene_copy_available(): + pytest.skip( + "RaycastingScene copy constructor not available " + "(requires Open3D built from source with copy support)" + ) + import copy as copy_module + vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], + dtype=o3d.core.float32, + device=device) + triangles = o3d.core.Tensor([[0, 1, 2]], + dtype=o3d.core.uint32, + device=device) + scene = o3d.t.geometry.RaycastingScene(device=device) + scene.add_triangles(vertices, triangles) + scene_copy = copy_module.copy(scene) + + rays = o3d.core.Tensor( + [[0.2, 0.1, 1, 0, 0, -1]], + dtype=o3d.core.float32, + device=device, + ) + ans_orig = scene.cast_rays(rays) + ans_copy = scene_copy.cast_rays(rays) + np.testing.assert_allclose(ans_orig["t_hit"].numpy(), + ans_copy["t_hit"].numpy()) + assert ans_orig["geometry_ids"][0].cpu().item() == ans_copy[ + "geometry_ids"][0].cpu().item() From 0b2f3f56195c6d0f529bf21789506095e56f22a9 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Mon, 9 Feb 2026 23:35:37 +0200 Subject: [PATCH 03/15] cleanup tests and simplify SYCL implementation #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 2 +- cpp/pybind/t/geometry/raycasting_scene.cpp | 4 -- .../test/t/geometry/test_raycasting_scene.py | 37 ++----------------- 3 files changed, 4 insertions(+), 39 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 0e26a7f6706..b1c3bd641eb 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -826,7 +826,7 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { std::unique_ptr Clone() const override { auto copy = std::make_unique(); - const_cast(copy.get())->InitializeDevice(); + copy->InitializeDevice(); copy->tensor_device_ = tensor_device_; rtcSetDeviceErrorFunction(copy->device_, ErrorFunction, NULL); copy->scene_ = rtcNewScene(copy->device_); diff --git a/cpp/pybind/t/geometry/raycasting_scene.cpp b/cpp/pybind/t/geometry/raycasting_scene.cpp index 03a6c8f7bf4..46743497c3b 100644 --- a/cpp/pybind/t/geometry/raycasting_scene.cpp +++ b/cpp/pybind/t/geometry/raycasting_scene.cpp @@ -74,10 +74,6 @@ Create a RaycastingScene as a copy of another scene (copy constructor). other (open3d.t.geometry.RaycastingScene): The scene to copy. )doc"); - raycasting_scene.def("__copy__", - [](const RaycastingScene& self) { - return RaycastingScene(self); - }); raycasting_scene.def("__deepcopy__", [](const RaycastingScene& self, py::dict /* memo */) { diff --git a/python/test/t/geometry/test_raycasting_scene.py b/python/test/t/geometry/test_raycasting_scene.py index 2af2a53f454..eaac4b7a66b 100755 --- a/python/test/t/geometry/test_raycasting_scene.py +++ b/python/test/t/geometry/test_raycasting_scene.py @@ -463,28 +463,12 @@ def test_sphere_wrong_occupancy(): # --- Tests for copy constructor and copy semantics. --- -# These require Open3D built from source with the copy constructor binding. # INVALID_ID is a property (no parentheses). Use .item() for scalar comparison. -def _raycasting_scene_copy_available(): - """True if RaycastingScene(scene) copy constructor is available (built from source).""" - try: - scene = o3d.t.geometry.RaycastingScene(device=o3d.core.Device("CPU:0")) - o3d.t.geometry.RaycastingScene(scene) - return True - except TypeError: - return False - - @pytest.mark.parametrize("device", list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_constructor_empty_scene(device): - if not _raycasting_scene_copy_available(): - pytest.skip( - "RaycastingScene copy constructor not available " - "(requires Open3D built from source with copy support)" - ) scene = o3d.t.geometry.RaycastingScene(device=device) scene_copy = o3d.t.geometry.RaycastingScene(scene) rays = o3d.core.Tensor([[0, 0, 1, 0, 0, -1]], @@ -503,11 +487,6 @@ def test_copy_constructor_empty_scene(device): list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_constructor_scene_with_geometry(device): """Copy of a scene with geometry yields same cast_rays and compute_* results (tests clone).""" - if not _raycasting_scene_copy_available(): - pytest.skip( - "RaycastingScene copy constructor not available " - "(requires Open3D built from source with copy support)" - ) vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], dtype=o3d.core.float32, device=device) @@ -551,11 +530,6 @@ def test_copy_constructor_scene_with_geometry(device): list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_independence(device): """Copy is independent: adding geometry to one does not affect the other.""" - if not _raycasting_scene_copy_available(): - pytest.skip( - "RaycastingScene copy constructor not available " - "(requires Open3D built from source with copy support)" - ) vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], dtype=o3d.core.float32, device=device) @@ -599,13 +573,8 @@ def test_copy_independence(device): @pytest.mark.parametrize("device", list_devices(enable_cuda=False, enable_sycl=True)) -def test_copy_module_copy(device): - """copy.copy(scene) works and produces an independent copy.""" - if not _raycasting_scene_copy_available(): - pytest.skip( - "RaycastingScene copy constructor not available " - "(requires Open3D built from source with copy support)" - ) +def test_copy_module_deepcopy(device): + """copy.deepcopy(scene) works and produces an independent copy.""" import copy as copy_module vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], dtype=o3d.core.float32, @@ -615,7 +584,7 @@ def test_copy_module_copy(device): device=device) scene = o3d.t.geometry.RaycastingScene(device=device) scene.add_triangles(vertices, triangles) - scene_copy = copy_module.copy(scene) + scene_copy = copy_module.deepcopy(scene) rays = o3d.core.Tensor( [[0.2, 0.1, 1, 0, 0, -1]], From d7c86dc09a45a8a1caeb163f2dac95bab8437fad Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Wed, 11 Feb 2026 00:24:00 +0200 Subject: [PATCH 04/15] Fix whitespace and formatting issues #7014 --- cpp/pybind/t/geometry/raycasting_scene.cpp | 3 +-- python/test/t/geometry/test_raycasting_scene.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/pybind/t/geometry/raycasting_scene.cpp b/cpp/pybind/t/geometry/raycasting_scene.cpp index 46743497c3b..85c3ebd73a1 100644 --- a/cpp/pybind/t/geometry/raycasting_scene.cpp +++ b/cpp/pybind/t/geometry/raycasting_scene.cpp @@ -75,8 +75,7 @@ Create a RaycastingScene as a copy of another scene (copy constructor). )doc"); raycasting_scene.def("__deepcopy__", - [](const RaycastingScene& self, - py::dict /* memo */) { + [](const RaycastingScene& self, py::dict /* memo */) { return RaycastingScene(self); }); diff --git a/python/test/t/geometry/test_raycasting_scene.py b/python/test/t/geometry/test_raycasting_scene.py index eaac4b7a66b..e62d9bf996e 100755 --- a/python/test/t/geometry/test_raycasting_scene.py +++ b/python/test/t/geometry/test_raycasting_scene.py @@ -595,5 +595,5 @@ def test_copy_module_deepcopy(device): ans_copy = scene_copy.cast_rays(rays) np.testing.assert_allclose(ans_orig["t_hit"].numpy(), ans_copy["t_hit"].numpy()) - assert ans_orig["geometry_ids"][0].cpu().item() == ans_copy[ - "geometry_ids"][0].cpu().item() + assert ans_orig["geometry_ids"][0].cpu().item( + ) == ans_copy["geometry_ids"][0].cpu().item() From 5a39c44f3825213607d7462eb62e12081998f6e8 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Wed, 11 Feb 2026 00:26:17 +0200 Subject: [PATCH 05/15] CHANGELOG: document RaycastingScene copy/move and deepcopy #7014 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2af40328b26..6b879786133 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ## Main +- Added copy and move semantics for `t::geometry::RaycastingScene` in C++ and Python: copy/move constructors and assignments are now supported. Python `copy.deepcopy()` is supported for `RaycastingScene`. (issue #7014)(PR #7437) - Upgrade stdgpu third-party library to commit d7c07d0. - Fix performance for non-contiguous NumPy array conversion in pybind vector converters. This change removes restrictive `py::array::c_style` flags and adds a runtime contiguity check, improving Pandas-to-Open3D conversion speed by up to ~50×. (issue #5250)(PR #7343). - Corrected documentation for Link Open3D in C++ projects (broken links). From 6cd3097e3f55945bacb6928f3358aab136495d93 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Wed, 11 Feb 2026 00:35:42 +0200 Subject: [PATCH 06/15] Fix C-style pointer casts in RaycastingScene (Codacy) #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index b1c3bd641eb..72628cca13f 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -1278,19 +1278,21 @@ struct RaycastingScene::CPUImpl : public RaycastingScene::Impl { const size_t num_triangles = geometry_sizes_[geom_id].second; RTCGeometry src_geom = rtcGetGeometry(scene_, geom_id); - const float* vb_src = (const float*)rtcGetGeometryBufferData( - src_geom, RTC_BUFFER_TYPE_VERTEX, 0); - const uint32_t* ib_src = (const uint32_t*)rtcGetGeometryBufferData( - src_geom, RTC_BUFFER_TYPE_INDEX, 0); + const float* vb_src = reinterpret_cast( + rtcGetGeometryBufferData(src_geom, RTC_BUFFER_TYPE_VERTEX, + 0)); + const uint32_t* ib_src = reinterpret_cast( + rtcGetGeometryBufferData(src_geom, RTC_BUFFER_TYPE_INDEX, + 0)); RTCGeometry geom = rtcNewGeometry(copy->device_, RTC_GEOMETRY_TYPE_TRIANGLE); - float* vertex_buffer = (float*)rtcSetNewGeometryBuffer( + float* vertex_buffer = reinterpret_cast(rtcSetNewGeometryBuffer( geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, - 3 * sizeof(float), num_vertices); - uint32_t* index_buffer = (uint32_t*)rtcSetNewGeometryBuffer( + 3 * sizeof(float), num_vertices)); + uint32_t* index_buffer = reinterpret_cast(rtcSetNewGeometryBuffer( geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, - 3 * sizeof(uint32_t), num_triangles); + 3 * sizeof(uint32_t), num_triangles)); std::memcpy(vertex_buffer, vb_src, 3 * sizeof(float) * num_vertices); From 786ad7037be6054c4ff9a8eea06e3a137ef41aee Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Wed, 11 Feb 2026 02:27:41 +0200 Subject: [PATCH 07/15] Remove unused INVALID_ID comment #7014 --- python/test/t/geometry/test_raycasting_scene.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/test/t/geometry/test_raycasting_scene.py b/python/test/t/geometry/test_raycasting_scene.py index e62d9bf996e..877028dc06a 100755 --- a/python/test/t/geometry/test_raycasting_scene.py +++ b/python/test/t/geometry/test_raycasting_scene.py @@ -463,7 +463,6 @@ def test_sphere_wrong_occupancy(): # --- Tests for copy constructor and copy semantics. --- -# INVALID_ID is a property (no parentheses). Use .item() for scalar comparison. @pytest.mark.parametrize("device", From 034601bf3386faa010b32201579f1a34f6fa0272 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 13:56:21 +0200 Subject: [PATCH 08/15] Style fixes #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 72628cca13f..5ecf127f012 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -1278,21 +1278,23 @@ struct RaycastingScene::CPUImpl : public RaycastingScene::Impl { const size_t num_triangles = geometry_sizes_[geom_id].second; RTCGeometry src_geom = rtcGetGeometry(scene_, geom_id); - const float* vb_src = reinterpret_cast( - rtcGetGeometryBufferData(src_geom, RTC_BUFFER_TYPE_VERTEX, - 0)); - const uint32_t* ib_src = reinterpret_cast( - rtcGetGeometryBufferData(src_geom, RTC_BUFFER_TYPE_INDEX, - 0)); + const float* vb_src = + reinterpret_cast(rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_VERTEX, 0)); + const uint32_t* ib_src = + reinterpret_cast(rtcGetGeometryBufferData( + src_geom, RTC_BUFFER_TYPE_INDEX, 0)); RTCGeometry geom = rtcNewGeometry(copy->device_, RTC_GEOMETRY_TYPE_TRIANGLE); - float* vertex_buffer = reinterpret_cast(rtcSetNewGeometryBuffer( - geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, - 3 * sizeof(float), num_vertices)); - uint32_t* index_buffer = reinterpret_cast(rtcSetNewGeometryBuffer( - geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, - 3 * sizeof(uint32_t), num_triangles)); + float* vertex_buffer = + reinterpret_cast(rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, + 3 * sizeof(float), num_vertices)); + uint32_t* index_buffer = + reinterpret_cast(rtcSetNewGeometryBuffer( + geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, + 3 * sizeof(uint32_t), num_triangles)); std::memcpy(vertex_buffer, vb_src, 3 * sizeof(float) * num_vertices); From 7d78b3269d3f71b1f16321d6249544a96c8b6219 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 15:04:00 +0200 Subject: [PATCH 09/15] Fix SYCL memcpy pointer cast in RaycastingScene Clone #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 5ecf127f012..c8aafc48d9f 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -866,8 +866,12 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { host_vb.resize(num_vertices * 3); host_ib.resize(num_triangles * 3); - auto event1 = src->queue_.memcpy(host_vb.data(), vb_src, vb_bytes); - auto event2 = src->queue_.memcpy(host_ib.data(), ib_src, ib_bytes); + auto event1 = src->queue_.memcpy( + static_cast(host_vb.data()), + const_cast(vb_src), vb_bytes); + auto event2 = src->queue_.memcpy( + static_cast(host_ib.data()), + const_cast(ib_src), ib_bytes); sycl::event::wait({event1, event2}); From 8dc6accdb6fd5ed0505496242a7699860f7cbcf5 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 15:09:20 +0200 Subject: [PATCH 10/15] Style fix #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index c8aafc48d9f..7043e09cf0f 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -866,12 +866,12 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { host_vb.resize(num_vertices * 3); host_ib.resize(num_triangles * 3); - auto event1 = src->queue_.memcpy( - static_cast(host_vb.data()), - const_cast(vb_src), vb_bytes); - auto event2 = src->queue_.memcpy( - static_cast(host_ib.data()), - const_cast(ib_src), ib_bytes); + auto event1 = + src->queue_.memcpy(static_cast(host_vb.data()), + const_cast(vb_src), vb_bytes); + auto event2 = + src->queue_.memcpy(static_cast(host_ib.data()), + const_cast(ib_src), ib_bytes); sycl::event::wait({event1, event2}); From 1884c40b2fb23bda00be5163ed7f9f6c021df22b Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 16:13:19 +0200 Subject: [PATCH 11/15] Fix SYCL Clone: use sycl::malloc_host for USM-compatible memcpy #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 26 +++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 7043e09cf0f..9786b9d8106 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -841,8 +841,6 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { const SYCLImpl* src = this; SYCLImpl* dst = copy.get(); - std::vector host_vb; - std::vector host_ib; for (size_t geom_id = 0; geom_id < geometry_ptrs_.size(); ++geom_id) { const size_t num_vertices = geometry_sizes_[geom_id].first; const size_t num_triangles = geometry_sizes_[geom_id].second; @@ -864,24 +862,24 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(uint32_t), num_triangles); - host_vb.resize(num_vertices * 3); - host_ib.resize(num_triangles * 3); - auto event1 = - src->queue_.memcpy(static_cast(host_vb.data()), - const_cast(vb_src), vb_bytes); - auto event2 = - src->queue_.memcpy(static_cast(host_ib.data()), - const_cast(ib_src), ib_bytes); + float* host_vb = + sycl::malloc_host(num_vertices * 3, src->queue_); + uint32_t* host_ib = + sycl::malloc_host(num_triangles * 3, src->queue_); + + auto event1 = src->queue_.memcpy(host_vb, vb_src, vb_bytes); + auto event2 = src->queue_.memcpy(host_ib, ib_src, ib_bytes); sycl::event::wait({event1, event2}); - auto event3 = - dst->queue_.memcpy(vertex_buffer, host_vb.data(), vb_bytes); - auto event4 = - dst->queue_.memcpy(index_buffer, host_ib.data(), ib_bytes); + auto event3 = dst->queue_.memcpy(vertex_buffer, host_vb, vb_bytes); + auto event4 = dst->queue_.memcpy(index_buffer, host_ib, ib_bytes); sycl::event::wait({event3, event4}); + sycl::free(host_vb, src->queue_); + sycl::free(host_ib, src->queue_); + rtcSetGeometryEnableFilterFunctionFromArguments(geom, true); rtcCommitGeometry(geom); rtcAttachGeometry(dst->scene_, geom); From 605f12cb93a3cab88984e65d87705a8b5b6f883f Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 17:04:37 +0200 Subject: [PATCH 12/15] Fix SYCL Clone: use std::memcpy for Embree USM shared buffers #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 9786b9d8106..9b7ce29413b 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -862,23 +862,8 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(uint32_t), num_triangles); - float* host_vb = - sycl::malloc_host(num_vertices * 3, src->queue_); - uint32_t* host_ib = - sycl::malloc_host(num_triangles * 3, src->queue_); - - auto event1 = src->queue_.memcpy(host_vb, vb_src, vb_bytes); - auto event2 = src->queue_.memcpy(host_ib, ib_src, ib_bytes); - - sycl::event::wait({event1, event2}); - - auto event3 = dst->queue_.memcpy(vertex_buffer, host_vb, vb_bytes); - auto event4 = dst->queue_.memcpy(index_buffer, host_ib, ib_bytes); - - sycl::event::wait({event3, event4}); - - sycl::free(host_vb, src->queue_); - sycl::free(host_ib, src->queue_); + std::memcpy(vertex_buffer, vb_src, vb_bytes); + std::memcpy(index_buffer, ib_src, ib_bytes); rtcSetGeometryEnableFilterFunctionFromArguments(geom, true); rtcCommitGeometry(geom); From 72f5868d2958e247e6612c7cbc8abc8691b2d533 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Thu, 26 Feb 2026 17:37:31 +0200 Subject: [PATCH 13/15] Refactor copy tests: extract common scene setup helper #7014 --- .../test/t/geometry/test_raycasting_scene.py | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/python/test/t/geometry/test_raycasting_scene.py b/python/test/t/geometry/test_raycasting_scene.py index 877028dc06a..b864b12da26 100755 --- a/python/test/t/geometry/test_raycasting_scene.py +++ b/python/test/t/geometry/test_raycasting_scene.py @@ -465,6 +465,19 @@ def test_sphere_wrong_occupancy(): # --- Tests for copy constructor and copy semantics. --- +def _make_scene_with_triangle(device): + """Create a RaycastingScene with a single triangle for copy tests.""" + vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], + dtype=o3d.core.float32, + device=device) + triangles = o3d.core.Tensor([[0, 1, 2]], + dtype=o3d.core.uint32, + device=device) + scene = o3d.t.geometry.RaycastingScene(device=device) + scene.add_triangles(vertices, triangles) + return scene + + @pytest.mark.parametrize("device", list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_constructor_empty_scene(device): @@ -486,15 +499,7 @@ def test_copy_constructor_empty_scene(device): list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_constructor_scene_with_geometry(device): """Copy of a scene with geometry yields same cast_rays and compute_* results (tests clone).""" - vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], - dtype=o3d.core.float32, - device=device) - triangles = o3d.core.Tensor([[0, 1, 2]], - dtype=o3d.core.uint32, - device=device) - scene = o3d.t.geometry.RaycastingScene(device=device) - scene.add_triangles(vertices, triangles) - + scene = _make_scene_with_triangle(device) scene_copy = o3d.t.geometry.RaycastingScene(scene) rays = o3d.core.Tensor( @@ -529,14 +534,7 @@ def test_copy_constructor_scene_with_geometry(device): list_devices(enable_cuda=False, enable_sycl=True)) def test_copy_independence(device): """Copy is independent: adding geometry to one does not affect the other.""" - vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], - dtype=o3d.core.float32, - device=device) - triangles = o3d.core.Tensor([[0, 1, 2]], - dtype=o3d.core.uint32, - device=device) - scene = o3d.t.geometry.RaycastingScene(device=device) - scene.add_triangles(vertices, triangles) + scene = _make_scene_with_triangle(device) scene_copy = o3d.t.geometry.RaycastingScene(scene) # Add another triangle only to the copy @@ -575,14 +573,7 @@ def test_copy_independence(device): def test_copy_module_deepcopy(device): """copy.deepcopy(scene) works and produces an independent copy.""" import copy as copy_module - vertices = o3d.core.Tensor([[0, 0, 0], [1, 0, 0], [1, 1, 0]], - dtype=o3d.core.float32, - device=device) - triangles = o3d.core.Tensor([[0, 1, 2]], - dtype=o3d.core.uint32, - device=device) - scene = o3d.t.geometry.RaycastingScene(device=device) - scene.add_triangles(vertices, triangles) + scene = _make_scene_with_triangle(device) scene_copy = copy_module.deepcopy(scene) rays = o3d.core.Tensor( From 06c7c6f0cc3703b89f8432b302ba37d8cc4e55f3 Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Sun, 12 Apr 2026 15:12:54 +0300 Subject: [PATCH 14/15] Fix static analysis in RaycastingScene #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 10bae1bebe7..7ce23324ac1 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -838,7 +838,6 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { copy->scene_committed_ = false; copy->geometry_sizes_ = geometry_sizes_; - const SYCLImpl* src = this; SYCLImpl* dst = copy.get(); for (size_t geom_id = 0; geom_id < geometry_ptrs_.size(); ++geom_id) { @@ -870,9 +869,10 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { rtcAttachGeometry(dst->scene_, geom); rtcReleaseGeometry(geom); - GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, - (const void*)vertex_buffer, - (const void*)index_buffer}; + GeometryPtr geometry_ptr = { + RTC_GEOMETRY_TYPE_TRIANGLE, + static_cast(vertex_buffer), + static_cast(index_buffer)}; dst->geometry_ptrs_.push_back(geometry_ptr); } return copy; @@ -1299,9 +1299,10 @@ struct RaycastingScene::CPUImpl : public RaycastingScene::Impl { rtcAttachGeometry(copy->scene_, geom); rtcReleaseGeometry(geom); - GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, - (const void*)vertex_buffer, - (const void*)index_buffer}; + GeometryPtr geometry_ptr = { + RTC_GEOMETRY_TYPE_TRIANGLE, + static_cast(vertex_buffer), + static_cast(index_buffer)}; copy->geometry_ptrs_.push_back(geometry_ptr); } return copy; @@ -1437,8 +1438,8 @@ uint32_t RaycastingScene::AddTriangles(const core::Tensor& vertex_positions, rtcReleaseGeometry(geom); GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, - (const void*)vertex_buffer, - (const void*)index_buffer}; + static_cast(vertex_buffer), + static_cast(index_buffer)}; impl_->geometry_ptrs_.push_back(geometry_ptr); impl_->geometry_sizes_.push_back({num_vertices, num_triangles}); return geom_id; From b50177b0e12f4708f7484a93782b15066fbac10f Mon Sep 17 00:00:00 2001 From: Michal Bakshi Date: Sun, 12 Apr 2026 16:00:04 +0300 Subject: [PATCH 15/15] style fix #7014 --- cpp/open3d/t/geometry/RaycastingScene.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cpp/open3d/t/geometry/RaycastingScene.cpp b/cpp/open3d/t/geometry/RaycastingScene.cpp index 7ce23324ac1..964db7cae5b 100644 --- a/cpp/open3d/t/geometry/RaycastingScene.cpp +++ b/cpp/open3d/t/geometry/RaycastingScene.cpp @@ -869,10 +869,9 @@ struct RaycastingScene::SYCLImpl : public RaycastingScene::Impl { rtcAttachGeometry(dst->scene_, geom); rtcReleaseGeometry(geom); - GeometryPtr geometry_ptr = { - RTC_GEOMETRY_TYPE_TRIANGLE, - static_cast(vertex_buffer), - static_cast(index_buffer)}; + GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, + static_cast(vertex_buffer), + static_cast(index_buffer)}; dst->geometry_ptrs_.push_back(geometry_ptr); } return copy; @@ -1299,10 +1298,9 @@ struct RaycastingScene::CPUImpl : public RaycastingScene::Impl { rtcAttachGeometry(copy->scene_, geom); rtcReleaseGeometry(geom); - GeometryPtr geometry_ptr = { - RTC_GEOMETRY_TYPE_TRIANGLE, - static_cast(vertex_buffer), - static_cast(index_buffer)}; + GeometryPtr geometry_ptr = {RTC_GEOMETRY_TYPE_TRIANGLE, + static_cast(vertex_buffer), + static_cast(index_buffer)}; copy->geometry_ptrs_.push_back(geometry_ptr); } return copy;