Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix color update in gpu #6886

Merged
merged 1 commit into from
Aug 1, 2024
Merged

Conversation

cdh981009
Copy link
Contributor

Type

  • Bug fix (non-breaking change which fixes an issue): Fixes #
  • New feature (non-breaking change which adds functionality). Resolves #
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) Resolves #

Motivation and Context

There was a typo, UpdateGeometry called GetPointPositions instead of GetPointColors for the color data when updating the colors of a pointcloud in a gpu.

Checklist:

  • I have run python util/check_style.py --apply to apply Open3D code style
    to my code.
  • This PR changes Open3D behavior or adds new functionality.
    • Both C++ (Doxygen) and Python (Sphinx / Google style) documentation is
      updated accordingly.
    • I have added or updated C++ and / or Python unit tests OR included test
      results
      (e.g. screenshots or numbers) here.
  • I will follow up and update the code if CI fails.
  • For fork PRs, I have selected Allow edits from maintainers.

Description

Fixed the typo.

Copy link

update-docs bot commented Jul 23, 2024

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

@benjaminum
Copy link
Contributor

Hi @cdh981009 , thanks for creating this PR. Do you have a minimal example to produce the problem? Does the problem only occur when using a point cloud stored on the GPU?

@cdh981009
Copy link
Contributor Author

cdh981009 commented Jul 29, 2024

Hi @benjaminum.

I modified examples/python/visualization/multiple_windows.py and removed irrelevant part. Hope this works as a minimum example.

import open3d as o3d
import threading
import time

CLOUD_NAME = "points"

def main():
    App().run()

class App:
    def __init__(self):
        self.is_done = False
        self.cloud = None
        self.main_vis = None

    def run(self):
        app = o3d.visualization.gui.Application.instance
        app.initialize()

        self.main_vis = o3d.visualization.O3DVisualizer()
        self.main_vis.set_on_close(self.on_main_window_closing)

        app.add_window(self.main_vis)

        threading.Thread(target=self.update_thread).start()

        app.run()

    def on_main_window_closing(self):
        self.is_done = True
        return True

    def update_thread(self):
        pcd_data = o3d.data.DemoICPPointClouds()
        self.cloud = o3d.io.read_point_cloud(pcd_data.paths[0])
        
        self.cloud = o3d.t.geometry.PointCloud.from_legacy(self.cloud).cuda() # <-- remove cuda() here to test on CPU
        bounds = self.cloud.get_axis_aligned_bounding_box().to_legacy()

        def add_first_cloud():
            mat = o3d.visualization.rendering.MaterialRecord()
            mat.shader = "defaultUnlit"
            self.main_vis.add_geometry(CLOUD_NAME, self.cloud, mat)
            self.main_vis.reset_camera_to_default()
            self.main_vis.setup_camera(60, bounds.get_center(),
                                       bounds.get_center() + [0, 0, -3],
                                       [0, -1, 0])

        o3d.visualization.gui.Application.instance.post_to_main_thread(
            self.main_vis, add_first_cloud)

        while not self.is_done:
            time.sleep(0.01)

            def update_cloud():
                mat = o3d.visualization.rendering.MaterialRecord()
                mat.shader = "defaultUnlit"
                flags = o3d.visualization.rendering.Scene.UPDATE_COLORS_FLAG
                self.main_vis.update_geometry(CLOUD_NAME, self.cloud, flags)

                self.main_vis.post_redraw()

            if self.is_done:
                break
            o3d.visualization.gui.Application.instance.post_to_main_thread(
                self.main_vis, update_cloud)

if __name__ == "__main__":
    main()

Screenshot from 2024-07-29 10-02-03

color values are using position values.

Does the problem only occur when using a point cloud stored on the GPU?

As far as I know, yes.

For some context, I was trying using update_geometry instead of removing and re-adding (because of #4992 related problem. Do you know anything about this issue?). And for some reasons, updating a point cloud stored on the CPU sometimes makes flickering artifact (I'm guessing it is related to buffering speed, as slowing down the updating rate mitigates the artifact). So I tried sending the point cloud to GPU, which solved the flickering problem, but caused weird coloring artifact. I looked into the code and found that on GPU, position buffer was being used instead of color buffer.

@ssheorey ssheorey requested a review from benjaminum July 31, 2024 14:47
@benjaminum benjaminum merged commit b271acb into isl-org:main Aug 1, 2024
35 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants