4
0
mirror of https://github.com/nerfstudio-project/nerfstudio.git synced 2026-11-11 02:24:38 +08:00
nerfstudio/scripts/viewer/run_viewer.py
Brent Yi 6a7c8820b8
Viewer backend refactor (#1702)
* Copy in `viser` communication infrastructure

* Update background image

* Add build directory to fix viser HTTP server
May want to remove these later

* Copy in `viser` communication infrastructure

* Update background image

* Pass dataset vis using viser

* initial impl of ViewerParameter

* idk what i did but brent and matt know

* Suppress eslint typescript warnings

* implement ViewerElement base class, then ViewerButton, ViewerSlider, etc

* client -> server message setup

* multi folder stuff

* Stream controls over viser

* import

* add types to viewer_param.py

* Move another message to viser

* Update folder color

* Use non throttled messages

* multiple folders works

* Cleanup, more porting

* starting impl of control panel in viser

* More porting

* scenebox to viser

* Cleanup

* Fix render updates

* More cleanup, docs, typing

* start control_panel.py

* set_hidden logic but not merged in

* control_panel replicates behavior of existing control panel (visually), except for setting the list of output options. not yet integrated with viewer_utils.py for logic flow. also implemented set_disabled and set_hidden in javscript/ViewerElement side

* Remove some original leva components

* add some train util logic, attempt set_value, doesn't work on javascript side fully yet (value updates but not slider visually

* bye zmq

* missing call to decoder

* 'gui_set' works properly, control panel now replicates behavior of original

* remove print

* Fix status viewer message

* More cleanup

* support set_options in dropdown

* hiding buttons works correctly

* fix set_options, switch from cur_value to get_value()

* Fix slowdown

* output options

* colormap logic converted

* add handle to cb_hook

* fix some lambda bugs

* cleanup

* Save checkpoint logic readded

* Cleanup and minor fixes

* snappier ui

* Refactoring

* Fix state update bugs

* Bug fixes

* Write less to redux

* added comments to reducer code

* Render state machine (#1727)

* state machine works, but train step throttling not implemented

* more step logic, cleanup

* remove random try catcH

* mutex logic for render

* Update lock logic

* types and docs

* added some state machine logic to help rerenders

* merge

---------

Co-authored-by: Justin <justin.g.kerr@gmail.com>

* Refactor and cleanup

* More cleanup and docs

* docstring to gui_utils

* docstrings, rename viewer_param.py to viewer_elements.py

* Fix viewer, remove bridge stuff

* Render on connect

* Fix lint errors

* More eslint fixes

* render_freq logic

* better rerender logic for crop

* More cleanup

* Purge

* Cleanup

* Lint fixes

* Fix cache

* better parsing logic

* Fix infinite test

* More cleanup

* typo

* Update webdocs

* Update docs

* rerender on custom hooks

* add more docs

* Use shared utilities in `viser.infra`

* rework callback to use elements instead of handles

* Fix ESlint errors

* change naming of handle to element, add setter for value

* cleanup

---------

Co-authored-by: Matt Tancik <mattt4001@gmail.com>
Co-authored-by: Justin <justin.g.kerr@gmail.com>
Co-authored-by: Ethan Weber <eweb0124@gmail.com>
Co-authored-by: Matthew Tancik <tancik@berkeley.edu>
2023-04-14 14:53:10 -07:00

109 lines
3.2 KiB
Python

#!/usr/bin/env python
"""
Starts viewer in eval mode.
"""
from __future__ import annotations
import time
from dataclasses import dataclass, field, fields
from pathlib import Path
import tyro
from rich.console import Console
from nerfstudio.configs.base_config import ViewerConfig
from nerfstudio.engine.trainer import TrainerConfig
from nerfstudio.pipelines.base_pipeline import Pipeline
from nerfstudio.utils import writer
from nerfstudio.utils.eval_utils import eval_setup
from nerfstudio.viewer.server.viewer_state import ViewerState
CONSOLE = Console(width=120)
@dataclass
class ViewerConfigWithoutNumRays(ViewerConfig):
"""Configuration for viewer instantiation"""
num_rays_per_chunk: tyro.conf.Suppress[int] = -1
def as_viewer_config(self):
"""Converts the instance to ViewerConfig"""
return ViewerConfig(**{x.name: getattr(self, x.name) for x in fields(self)})
@dataclass
class RunViewer:
"""Load a checkpoint and start the viewer."""
load_config: Path
"""Path to config YAML file."""
viewer: ViewerConfigWithoutNumRays = field(default_factory=ViewerConfigWithoutNumRays)
"""Viewer configuration"""
def main(self) -> None:
"""Main function."""
config, pipeline, _, step = eval_setup(
self.load_config,
eval_num_rays_per_chunk=None,
test_mode="test",
)
num_rays_per_chunk = config.viewer.num_rays_per_chunk
assert self.viewer.num_rays_per_chunk == -1
config.vis = "viewer"
config.viewer = self.viewer.as_viewer_config()
config.viewer.num_rays_per_chunk = num_rays_per_chunk
_start_viewer(config, pipeline, step)
def save_checkpoint(self, *args, **kwargs):
"""
Mock method because we pass this instance to viewer_state.update_scene
"""
def _start_viewer(config: TrainerConfig, pipeline: Pipeline, step: int):
"""Starts the viewer
Args:
config: Configuration of pipeline to load
pipeline: Pipeline instance of which to load weights
step: Step at which the pipeline was saved
"""
base_dir = config.get_base_dir()
viewer_log_path = base_dir / config.viewer.relative_log_filename
viewer_state = ViewerState(
config.viewer,
log_filename=viewer_log_path,
datapath=pipeline.datamanager.get_datapath(),
pipeline=pipeline,
)
banner_messages = [f"Viewer at: {viewer_state.viewer_url}"]
# We don't need logging, but writer.GLOBAL_BUFFER needs to be populated
config.logging.local_writer.enable = False
writer.setup_local_writer(config.logging, max_iter=config.max_num_iterations, banner_messages=banner_messages)
assert viewer_state and pipeline.datamanager.train_dataset
viewer_state.init_scene(
dataset=pipeline.datamanager.train_dataset,
start_train=False,
)
viewer_state.viser_server.set_is_training(False)
viewer_state.update_scene(step=step)
while True:
time.sleep(0.01)
def entrypoint():
"""Entrypoint for use with pyproject scripts."""
tyro.extras.set_accent_color("bright_yellow")
tyro.cli(RunViewer).main()
if __name__ == "__main__":
entrypoint()
# For sphinx docs
get_parser_fn = lambda: tyro.extras.get_parser(RunViewer) # noqa