mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-10 18:17:31 +08:00
parent
1bb0c88fb5
commit
5fac867502
@ -34,7 +34,7 @@ conda install -c conda-forge pandoc
|
||||
To ensure that you will be passing all tests and checks on github, you will need to run the following command:
|
||||
|
||||
```bash
|
||||
python scripts/debugging/run_actions.py
|
||||
ns-dev-test
|
||||
```
|
||||
|
||||
This will perform the following checks and actions:
|
||||
|
||||
@ -19,7 +19,7 @@ from rich.text import Text
|
||||
|
||||
|
||||
class ItersPerSecColumn(ProgressColumn):
|
||||
"""Renders human readable fps."""
|
||||
"""Renders the iterations per second for a progress bar."""
|
||||
|
||||
def __init__(self, suffix="it/s") -> None:
|
||||
super().__init__()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "viewer",
|
||||
"homepage": ".",
|
||||
"version": "22-09-27-0",
|
||||
"version": "22-09-30-0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.4",
|
||||
@ -34,7 +34,6 @@
|
||||
"redux": "^4.2.0",
|
||||
"sass": "^1.54.8",
|
||||
"socket.io-client": "^4.5.1",
|
||||
"stats.js": "^0.17.0",
|
||||
"three": "^0.142.0",
|
||||
"three-wtm": "^1.0",
|
||||
"websocket": "^1.0.34",
|
||||
|
||||
@ -2,8 +2,6 @@ import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import Button from '@mui/material/Button';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||
import DescriptionRoundedIcon from '@mui/icons-material/DescriptionRounded';
|
||||
import LandingModal from '../LandingModal';
|
||||
@ -25,18 +23,8 @@ function getWebsocketEndpoint() {
|
||||
}
|
||||
|
||||
export default function Banner() {
|
||||
// const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
const [anchorEl, setAnchorEl] = React.useState(0);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
let open_modal = true;
|
||||
const websocket_url_from_argument = getWebsocketEndpoint();
|
||||
if (websocket_url_from_argument !== undefined) {
|
||||
@ -51,34 +39,6 @@ export default function Banner() {
|
||||
return (
|
||||
<div className="banner">
|
||||
<LandingModal initial_state={open_modal} />
|
||||
<Button
|
||||
id="basic-button"
|
||||
className="banner-button"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
aria-controls={open ? 'basic-menu' : undefined}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={open ? 'true' : undefined}
|
||||
onClick={handleClick}
|
||||
>
|
||||
Options
|
||||
</Button>
|
||||
<Menu
|
||||
id="basic-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
MenuListProps={{
|
||||
'aria-labelledby': 'basic-button',
|
||||
}}
|
||||
>
|
||||
<MenuItem onClick={handleClose}>Load Training Config</MenuItem>
|
||||
<MenuItem onClick={handleClose}>Export Training Config</MenuItem>
|
||||
<MenuItem onClick={handleClose}>Dark Mode</MenuItem>
|
||||
</Menu>
|
||||
<Button className="banner-button" variant="outlined" size="small">
|
||||
Download Desktop App
|
||||
</Button>
|
||||
<Button // button with view in ar icon
|
||||
className="banner-button"
|
||||
variant="outlined"
|
||||
|
||||
@ -29,8 +29,7 @@ export default function StatusPanel(props: StatusPanelProps) {
|
||||
const isWebrtcConnected = useSelector(
|
||||
(state) => state.webrtcState.isConnected,
|
||||
);
|
||||
const eval_fps = useSelector((state) => state.renderingState.eval_fps);
|
||||
const train_eta = useSelector((state) => state.renderingState.train_eta);
|
||||
const eval_res = useSelector((state) => state.renderingState.eval_res);
|
||||
const vis_train_ratio = useSelector(
|
||||
(state) => state.renderingState.vis_train_ratio,
|
||||
);
|
||||
@ -109,10 +108,7 @@ export default function StatusPanel(props: StatusPanelProps) {
|
||||
<WebSocketUrlField />
|
||||
<div className="StatusPanel-metrics">
|
||||
<div>
|
||||
<b>Eval FPS:</b> {eval_fps}
|
||||
</div>
|
||||
<div>
|
||||
<b>Train ETA:</b> {train_eta}
|
||||
<b>Resolution:</b> {eval_res}
|
||||
</div>
|
||||
<div>
|
||||
<b>Time Allocation:</b> {vis_train_ratio}
|
||||
|
||||
@ -8,22 +8,12 @@ import { IconButton, ToggleButtonGroup, ToggleButton } from '@mui/material';
|
||||
import OpenWithIcon from '@mui/icons-material/OpenWith';
|
||||
import PublicOffSharpIcon from '@mui/icons-material/PublicOffSharp';
|
||||
import PublicSharpIcon from '@mui/icons-material/PublicSharp';
|
||||
import Stats from 'stats.js';
|
||||
import SyncOutlinedIcon from '@mui/icons-material/SyncOutlined';
|
||||
import WebRtcWindow from '../WebRtcWindow/WebRtcWindow';
|
||||
import { WebSocketContext } from '../WebSocket/WebSocket';
|
||||
|
||||
const msgpack = require('msgpack-lite');
|
||||
|
||||
function createStats() {
|
||||
const stats = new Stats();
|
||||
stats.setMode(0);
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.left = '0';
|
||||
stats.domElement.style.top = '0';
|
||||
return stats;
|
||||
}
|
||||
|
||||
function CameraToggle() {
|
||||
const dispatch = useDispatch();
|
||||
const camera_choice = useSelector(
|
||||
@ -129,8 +119,6 @@ export default function ViewerWindow(props) {
|
||||
// on change, update the camera and controls
|
||||
sceneTree.metadata.camera = sceneTree.find_object(['Cameras', camera_choice]);
|
||||
|
||||
let stats = null;
|
||||
|
||||
const get_window_width = () => {
|
||||
const width = myRef.current.clientWidth;
|
||||
return width - (width % 2);
|
||||
@ -208,14 +196,11 @@ export default function ViewerWindow(props) {
|
||||
requestAnimationFrame(render);
|
||||
renderer.render(scene, sceneTree.metadata.camera);
|
||||
labelRenderer.render(scene, sceneTree.metadata.camera);
|
||||
stats.update();
|
||||
};
|
||||
|
||||
// start the three.js rendering loop
|
||||
// when the DOM is ready
|
||||
useEffect(() => {
|
||||
stats = createStats();
|
||||
myRef.current.append(stats.domElement);
|
||||
myRef.current.append(renderer.domElement);
|
||||
render();
|
||||
}, []);
|
||||
|
||||
@ -30,7 +30,7 @@ const initialState = {
|
||||
colormap_choice: 'default', // the selected colormap
|
||||
maxResolution: 1024,
|
||||
targetTrainUtil: 0.9,
|
||||
eval_fps: 'Paused',
|
||||
eval_res: '?',
|
||||
train_eta: 'Paused',
|
||||
vis_train_ratio: 'Paused',
|
||||
log_errors: '',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ import sys
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
@ -464,22 +464,21 @@ class ViewerState:
|
||||
image = selected_output.cpu().numpy()
|
||||
self.vis.set_image(image)
|
||||
|
||||
def _update_viewer_stats(self, render_time: float, num_rays: int, image_height: int) -> None:
|
||||
def _update_viewer_stats(self, render_time: float, num_rays: int, image_height: int, image_width: int) -> None:
|
||||
"""Function that calculates and populates all the rendering statistics accordingly
|
||||
|
||||
Args:
|
||||
render_time: total time spent rendering current view
|
||||
num_rays: number of rays rendered
|
||||
image_height: resolution of the current view
|
||||
image_width: resolution of the current view
|
||||
"""
|
||||
writer.put_time(
|
||||
name=EventName.VIS_RAYS_PER_SEC, duration=num_rays / render_time, step=self.step, avg_over_steps=True
|
||||
)
|
||||
is_training = self.vis["renderingState/isTraining"].read()
|
||||
self.vis["renderingState/eval_res"].write(f"{image_height}x{image_width}px")
|
||||
if is_training is None or is_training:
|
||||
# process the current rendering fps
|
||||
eval_fps = f"{1 / render_time:.2f} fps at {image_height} res"
|
||||
self.vis["renderingState/eval_fps"].write(eval_fps)
|
||||
# process remaining training ETA
|
||||
self.vis["renderingState/train_eta"].write(GLOBAL_BUFFER["events"].get(EventName.ETA.value, "Starting"))
|
||||
# process ratio time spent on vis vs train
|
||||
@ -491,11 +490,10 @@ class ViewerState:
|
||||
else:
|
||||
self.vis["renderingState/vis_train_ratio"].write("Starting")
|
||||
else:
|
||||
self.vis["renderingState/eval_fps"].write("Paused")
|
||||
self.vis["renderingState/train_eta"].write("Paused")
|
||||
self.vis["renderingState/vis_train_ratio"].write("100% spent on viewer")
|
||||
|
||||
def _calculate_image_height(self, camera_object, is_training: bool) -> Optional[int]:
|
||||
def _calculate_image_res(self, camera_object, is_training: bool) -> Optional[Tuple[int, int]]:
|
||||
"""Calculate the maximum image height that can be rendered in the time budget
|
||||
|
||||
Args:
|
||||
@ -503,6 +501,7 @@ class ViewerState:
|
||||
is_training: whether or not we are training
|
||||
Returns:
|
||||
image_height: the maximum image height that can be rendered in the time budget
|
||||
image_width: the maximum image width that can be rendered in the time budget
|
||||
"""
|
||||
max_resolution = self.vis["renderingState/maxResolution"].read()
|
||||
if max_resolution:
|
||||
@ -535,7 +534,7 @@ class ViewerState:
|
||||
image_height = int(round(image_height, -1))
|
||||
image_height = min(self.max_resolution, image_height)
|
||||
|
||||
return image_height
|
||||
return image_height, int(image_height * aspect_ratio)
|
||||
|
||||
def _process_invalid_output(self, output_type: str) -> str:
|
||||
"""Check to see whether we are in the corner case of RGB; if still invalid, throw error
|
||||
@ -587,7 +586,7 @@ class ViewerState:
|
||||
|
||||
# Calculate camera pose and intrinsics
|
||||
try:
|
||||
image_height = self._calculate_image_height(camera_object, is_training)
|
||||
image_height, image_width = self._calculate_image_res(camera_object, is_training)
|
||||
except ZeroDivisionError as e:
|
||||
self.vis["renderingState/log_errors"].write("Error: Screen too small; no rays intersecting scene.")
|
||||
time.sleep(0.03) # sleep to allow buffer to reset
|
||||
@ -649,4 +648,6 @@ class ViewerState:
|
||||
if outputs is not None:
|
||||
stuff_colors = graph.stuff_colors if hasattr(graph, "stuff_colors") else None
|
||||
self._send_output_to_viewer(outputs, stuff_colors=stuff_colors)
|
||||
self._update_viewer_stats(vis_t.duration, num_rays=len(camera_ray_bundle), image_height=image_height)
|
||||
self._update_viewer_stats(
|
||||
vis_t.duration, num_rays=len(camera_ray_bundle), image_height=image_height, image_width=image_width
|
||||
)
|
||||
|
||||
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "nerfstudio"
|
||||
version = "0.0.1"
|
||||
version = "0.0.2"
|
||||
description = "All-in-one repository for state-of-the-art NeRFs"
|
||||
readme = "README.md"
|
||||
license = { text="Apache 2.0"}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user