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

Viser and multi-window display functionality #821

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
309 changes: 309 additions & 0 deletions visualization/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
name: gtsfm-dask
channels:
- conda-forge
- defaults
dependencies:
- _libgcc_mutex=0.1
- _openmp_mutex=4.5
- alsa-lib=1.2.13
- attr=2.5.1
- aws-c-auth=0.8.1
- aws-c-cal=0.8.1
- aws-c-common=0.10.6
- aws-c-compression=0.3.0
- aws-c-event-stream=0.5.0
- aws-c-http=0.9.2
- aws-c-io=0.15.3
- aws-c-mqtt=0.11.0
- aws-c-s3=0.7.9
- aws-c-sdkutils=0.2.2
- aws-checksums=0.2.2
- aws-crt-cpp=0.29.9
- aws-sdk-cpp=1.11.489
- azure-core-cpp=1.14.0
- azure-identity-cpp=1.10.0
- azure-storage-blobs-cpp=12.13.0
- azure-storage-common-cpp=12.8.0
- azure-storage-files-datalake-cpp=12.12.0
- blinker=1.9.0
- bokeh=3.6.2
- brotli-python=1.1.0
- bzip2=1.0.8
- c-ares=1.34.4
- ca-certificates=2024.12.14
- cairo=1.18.2
- cffi=1.17.1
- charset-normalizer=3.4.1
- click=8.1.8
- cloudpickle=3.1.1
- contourpy=1.3.1
- cyrus-sasl=2.1.27
- cytoolz=1.0.1
- dask=2025.1.0
- dask-core=2025.1.0
- dbus=1.13.6
- distributed=2025.1.0
- expat=2.6.4
- flask=3.1.0
- font-ttf-dejavu-sans-mono=2.37
- font-ttf-inconsolata=3.000
- font-ttf-source-code-pro=2.038
- font-ttf-ubuntu=0.83
- fontconfig=2.15.0
- fonts-conda-ecosystem=1
- fonts-conda-forge=1
- freetype=2.12.1
- fsspec=2024.12.0
- gettext=0.22.5
- gettext-tools=0.22.5
- gflags=2.2.2
- glib=2.82.2
- glib-tools=2.82.2
- glog=0.7.1
- graphite2=1.3.13
- gst-plugins-base=1.24.7
- gstreamer=1.24.7
- h2=4.1.0
- harfbuzz=10.2.0
- hpack=4.1.0
- hyperframe=6.1.0
- icu=75.1
- idna=3.10
- importlib-metadata=8.6.1
- importlib_metadata=8.6.1
- itsdangerous=2.2.0
- jinja2=3.1.5
- keyutils=1.6.1
- krb5=1.21.3
- lame=3.100
- lcms2=2.16
- ld_impl_linux-64=2.43
- lerc=4.0.0
- libabseil=20240722.0
- libarrow=19.0.0
- libarrow-acero=19.0.0
- libarrow-dataset=19.0.0
- libarrow-substrait=19.0.0
- libasprintf=0.22.5
- libasprintf-devel=0.22.5
- libblas=3.9.0
- libbrotlicommon=1.1.0
- libbrotlidec=1.1.0
- libbrotlienc=1.1.0
- libcap=2.71
- libcblas=3.9.0
- libclang-cpp19.1=19.1.7
- libclang13=19.1.7
- libcrc32c=1.1.2
- libcups=2.3.3
- libcurl=8.11.1
- libdeflate=1.23
- libdrm=2.4.124
- libedit=3.1.20240808
- libegl=1.7.0
- libev=4.33
- libevent=2.1.12
- libexpat=2.6.4
- libffi=3.4.2
- libflac=1.4.3
- libgcc=14.2.0
- libgcc-ng=14.2.0
- libgcrypt-lib=1.11.0
- libgettextpo=0.22.5
- libgettextpo-devel=0.22.5
- libgfortran=14.2.0
- libgfortran5=14.2.0
- libgl=1.7.0
- libglib=2.82.2
- libglvnd=1.7.0
- libglx=1.7.0
- libgomp=14.2.0
- libgoogle-cloud=2.34.0
- libgoogle-cloud-storage=2.34.0
- libgpg-error=1.51
- libgrpc=1.67.1
- libiconv=1.17
- libjpeg-turbo=3.0.0
- liblapack=3.9.0
- libllvm19=19.1.7
- liblzma=5.6.3
- libnghttp2=1.64.0
- libnsl=2.0.1
- libntlm=1.8
- libogg=1.3.5
- libopenblas=0.3.28
- libopentelemetry-cpp=1.18.0
- libopentelemetry-cpp-headers=1.18.0
- libopus=1.3.1
- libparquet=19.0.0
- libpciaccess=0.18
- libpng=1.6.46
- libpq=17.2
- libprotobuf=5.28.3
- libre2-11=2024.07.02
- libsndfile=1.2.2
- libsqlite=3.48.0
- libssh2=1.11.1
- libstdcxx=14.2.0
- libstdcxx-ng=14.2.0
- libsystemd0=257.2
- libthrift=0.21.0
- libtiff=4.7.0
- libutf8proc=2.10.0
- libuuid=2.38.1
- libvorbis=1.3.7
- libwebp-base=1.5.0
- libxcb=1.17.0
- libxcrypt=4.4.36
- libxkbcommon=1.7.0
- libxml2=2.13.5
- libzlib=1.3.1
- locket=1.0.0
- lz4=4.3.3
- lz4-c=1.10.0
- markupsafe=3.0.2
- mpg123=1.32.9
- msgpack-python=1.1.0
- mysql-common=9.0.1
- mysql-libs=9.0.1
- ncurses=6.5
- nlohmann_json=3.11.3
- nspr=4.36
- nss=3.107
- numpy=2.2.2
- openjpeg=2.5.3
- openldap=2.6.9
- openssl=3.4.0
- orc=2.0.3
- packaging=24.2
- pandas=2.2.3
- partd=1.4.2
- pcre2=10.44
- pillow=11.1.0
- pip=25.0
- pixman=0.44.2
- ply=3.11
- prometheus-cpp=1.3.0
- psutil=6.1.1
- pthread-stubs=0.4
- pulseaudio-client=17.0
- pyarrow=19.0.0
- pyarrow-core=19.0.0
- pycparser=2.22
- pyqt=5.15.9
- pyqt5-sip=12.12.2
- pysocks=1.7.1
- python=3.10.16
- python-dateutil=2.9.0.post0
- python-tzdata=2025.1
- python_abi=3.10
- pytz=2024.1
- pyyaml=6.0.2
- qt-main=5.15.15
- re2=2024.07.02
- readline=8.2
- requests=2.32.3
- s2n=1.5.11
- setuptools=75.8.0
- sip=6.7.12
- six=1.17.0
- snappy=1.2.1
- sortedcontainers=2.4.0
- tblib=3.0.0
- tk=8.6.13
- toml=0.10.2
- tomli=2.2.1
- toolz=1.0.0
- tornado=6.4.2
- tzdata=2025a
- urllib3=2.3.0
- werkzeug=3.1.3
- wheel=0.45.1
- xcb-util=0.4.1
- xcb-util-image=0.4.0
- xcb-util-keysyms=0.4.1
- xcb-util-renderutil=0.3.10
- xcb-util-wm=0.4.2
- xkeyboard-config=2.43
- xorg-libice=1.1.2
- xorg-libsm=1.2.5
- xorg-libx11=1.8.10
- xorg-libxau=1.0.12
- xorg-libxdamage=1.1.6
- xorg-libxdmcp=1.1.5
- xorg-libxext=1.3.6
- xorg-libxfixes=6.0.1
- xorg-libxrender=0.9.12
- xorg-libxxf86vm=1.1.6
- xyzservices=2025.1.0
- yaml=0.2.5
- zict=3.0.0
- zipp=3.21.0
- zlib=1.3.1
- zstandard=0.23.0
- zstd=1.5.6
- pip:
- anyio==4.8.0
- astroid==3.3.8
- attrs==25.1.0
- black==24.10.0
- certifi==2024.12.14
- chardet==5.2.0
- colorlog==6.9.0
- dill==0.3.9
- docstring-parser==0.16
- embreex==2.17.7.post6
- exceptiongroup==1.2.2
- flake8==7.1.1
- h11==0.14.0
- httpcore==1.0.7
- httpx==0.28.1
- imageio==2.37.0
- isort==5.13.2
- jsonschema==4.23.0
- jsonschema-specifications==2024.10.1
- lazy-loader==0.4
- lxml==5.3.0
- manifold3d==3.0.1
- mapbox-earcut==1.0.3
- markdown-it-py==3.0.0
- mccabe==0.7.0
- mdurl==0.1.2
- msgspec==0.19.0
- mypy==1.14.1
- mypy-extensions==1.0.0
- networkx==3.4.2
- nodeenv==1.9.1
- pathspec==0.12.1
- platformdirs==4.3.6
- plyfile==1.1
- pycodestyle==2.12.1
- pycollada==0.8
- pyflakes==3.2.0
- pygments==2.19.1
- pyliblzfse==0.4.1
- pylint==3.3.3
- referencing==0.36.2
- rich==13.9.4
- rpds-py==0.22.3
- rtree==1.3.0
- scikit-image==0.25.1
- scipy==1.15.1
- shapely==2.0.6
- shtab==1.7.1
- sniffio==1.3.1
- svg-path==6.3
- tifffile==2025.1.10
- tomlkit==0.13.2
- tqdm==4.67.1
- trimesh==4.6.0
- typeguard==4.4.1
- typing-extensions==4.12.2
- tyro==0.9.13
- vhacdx==0.0.8.post1
- viser==0.2.21
- websockets==14.2
- xatlas==0.0.9
- xxhash==3.5.0
- yourdfpy==0.0.56
prefix: /home/sma/miniconda3/envs/gtsfm-dask
82 changes: 82 additions & 0 deletions visualization/local_dask_pointcloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import asyncio
import numpy as np
from dask.distributed import Client, LocalCluster
from viser import ViserServer

# Function to simulate point cloud processing
def process_pointcloud(worker_id):
num_points = 10
# Simulate some processing
points = np.random.rand(num_points, 3) # Random 3D points
points[:, 2] += worker_id * 0.5 # Offset for visual differentiation

# Define a unique color for each worker (RGB values normalized between 0 and 1)
predefined_colors = [
[1.0, 0.0, 0.0], # Red
[0.0, 1.0, 0.0], # Green
[0.0, 0.0, 1.0], # Blue
[1.0, 1.0, 0.0], # Yellow
[1.0, 0.0, 1.0], # Magenta
[0.0, 1.0, 1.0], # Cyan
]
color = predefined_colors[worker_id % len(predefined_colors)] # Cycle through colors

# Repeat the same color for all points in the worker's point cloud
colors = np.tile(color, (num_points, 1))
return points, colors

# Worker task
async def worker_task(worker_id, viser_server):
points, colors = process_pointcloud(worker_id) # Simulate point cloud processing

# Add the point cloud to Viser
viser_server.scene.add_point_cloud(
name=f"worker_{worker_id}",
points=points,
colors=colors,
)
print(f"Worker {worker_id} point cloud added to Viser.")

# Main function
async def main(num_workers):
# Create a local Dask cluster
cluster = LocalCluster(n_workers=num_workers)
client = Client(cluster)
print("Dask Cluster Created:")
print(client)

# Initialize Viser server for visualization
viser_server = ViserServer(host="localhost", port=5174) # Explicit port setup
print("Viser server initialized. Open browser at http://localhost:5174 to view.")

# Launch worker tasks
tasks = [
asyncio.create_task(worker_task(worker_id, viser_server))
for worker_id in range(num_workers)
]

# Run the tasks
await asyncio.gather(*tasks)

# Keep the server running indefinitely
try:
print("Viser server is running. Press Ctrl+C to exit.")
while True:
await asyncio.sleep(3600) # Sleep loop to keep the server alive
except KeyboardInterrupt:
print("Exiting...")

# Entry point
if __name__ == "__main__":
import argparse

parser = argparse.ArgumentParser(description="Run local Dask workers for point cloud processing.")
parser.add_argument(
"--nodes",
type=int,
required=True,
help="Number of worker nodes to create.",
)
args = parser.parse_args()

asyncio.run(main(args.nodes))
Loading
Loading