-
Notifications
You must be signed in to change notification settings - Fork 13
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
add nerf viewer #40
base: main
Are you sure you want to change the base?
add nerf viewer #40
Conversation
|
viewers/nerf_viewer/README.md
Outdated
pip install -r ./requirements.txt | ||
``` | ||
|
||
#### 2.2 Start Server |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"###" would be enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the typo. The title hierarchy issue has been fixed.
viewers/nerf_viewer/README.md
Outdated
|
||
Visit http://localhost:3000/ in the browser: | ||
|
||
![alt viewer](./doc/viewer.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we replace it with new vierwer screenshot? The coordinate axis on upper right corner is tilted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original version of README.md is for debug purpose. In the lastest doc, the screenshots have been removed.
viewers/nerf_viewer/README.md
Outdated
@@ -0,0 +1,85 @@ | |||
# Nerf Viewer Quick Start |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nerf -> NeRF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glitch fixed: Nerf Viewer -> XRNeRF Viewer
@@ -0,0 +1,85 @@ | |||
import atexit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we rename it to bridge_server.py
? As there is no conflict, it is not necessary to add _subprocess
suffix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Renamed
bridge_server_subprocess.py
tobridge_server.py
- Renamed function
run_bridge_server_as_subprocess
tostart_bridge_server
viewers/nerf_viewer/client/README.md
Outdated
|
||
In the project directory, you can run: | ||
|
||
### `npm start` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
npm start
Same as L17, L22 and L32
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This README.md is automatically generated by Create React App. It has been replaced to XRNerf Viewer.
viewers/nerf_viewer/client/README.md
Outdated
|
||
### `npm run build` fails to minify | ||
|
||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Learn More
section, as each subsection. only as one sentence, shall we use bullet point directly? For example,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This README.md is automatically generated by Create React App. It has been replaced to XRNerf Viewer.
// }, | ||
// }, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented content if they are unnecessary anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused code blocks removed.
|
|
viewers/nerf_viewer/README.md
Outdated
|
||
Please follow the instructions in: | ||
|
||
https://juejin.cn/post/7120267871950733320/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any installation instruction in English? Say https://github.com/nvm-sh/nvm#installing-and-updating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original version of README.md is for debug purpose. In the lastest doc, the installation instructions has been updated so that it is suitable for non-chinese users.
viewers/nerf_viewer/README.md
Outdated
conda activate BridgeServer | ||
|
||
# install dependencies | ||
pip install -r ./requirements.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a requirements folder in the root directory of the repository, where many different requirements files are named according to their functionality and placed here, such as requirements/synbody.txt
. You can also consider renaming your requirements.txt
to something like bridge_server.txt
. In addition, most of the relative paths in our documentation are relative to the root directory of the repository, not to subdirectories like viewers
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For requriements, the dependencies list of server has been moved from
python/xrprimer/services/xrnerf/requirements.txt
to requirements/service_xrnerf.txt
.
For paths, they are now relative to the root directory of the repository, e.g., ./run.py
to xrprimer/python/xrprimer/services/xrnerf/run.py
.
Appreciate for the suggestion.
viewers/nerf_viewer/README.md
Outdated
#### 2.2 Start Server | ||
|
||
``` | ||
python ./run_viewer.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
python ./run_viewer.py | |
python .python/tools/un_viewer.py |
We often put files with a main function program entry point in the tools
folder to distinguish them from files that are only called and not used as entry points.
@@ -0,0 +1 @@ | |||
.idea |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we merge this file with the .gitignore file in the root directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original .gitignore file is for debug purpose only. It has been removed now.
return False | ||
|
||
|
||
def get_free_port(default_port: int = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def get_free_port(default_port: int = None): | |
from typing import Union | |
def get_free_port(default_port: Union[int, None] = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default_port: int
has been declared as default_port: Optional[int]
.
return False | ||
|
||
|
||
def get_free_port(default_port: int = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For users, there are two possible scenarios. In the first scenario, the user does not care which port is used as long as the service is started successfully and the port used is returned. The current function can meet this requirement. In the second scenario, the user may be required to use a specific port, such as port 80. If the target port is occupied, an exception should be thrown and there is no need to continue running. Considering these two scenarios, we can modify the parameter list of this function, for example:
def bind_port(allow_random_port: bool, preferred_port: Union[int, None] = None) -> int:
def bind_port(target_port: Union[int, None] = None) -> int:
In the first example, the allow_random_port
parameter is used to determine which usage scenario to use, and preferred_port
is the port number that is preferentially attempted. In the second example, the target_port
parameter is used to determine the usage scenario. If it is provided, the target port must be used. If it is not provided, there are no requirements and any available port can be returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated port binding logics: if the user specified a port, the server will check whether the port is already in use and then create connections using zmq, otherwise the server will automatically find an available port.
|
||
def run_bridge_server_as_subprocess( | ||
websocket_port: int, | ||
zmq_port: Optional[int] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChatGPT:
In Python, Union[int, None] and Optional[int] are similar in that they both indicate that a variable can be either an integer or None. However, there is a subtle difference between them.
Union[int, None] explicitly specifies that the variable can be either an integer or None. It does not allow any other type to be assigned to it. On the other hand, Optional[int] is actually an alias for Union[int, None], which means it represents the same set of possible types. However, Optional[int] does not explicitly indicate that the variable cannot be assigned any other type.
Therefore, using Union[int, None] is more specific and explicit, and may help prevent type-related bugs in your code. However, both Optional[int] and Union[int, None] can be used interchangeably in most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt the response from ChatGPT. According to PEP484 which is the official definitions of python typing hints, Optional[...]
is no more than a shorthand of Union[..., None]
. It says in The typing
module section:
Optional, defined by Optional[t] == Union[t, None]
So do the documentation of typing.Optional:
Optional[X] is equivalent to X | None (or Union[X, None]).
It's also recommended to use Optional[...]
for readability. Since for complex types, we could combine Union
with Optional
. For example, from def foo(x: Optional[Union[str, pathlib.Path]] = None): ...
, we know that foo
accepts a path-like argument or None
as default. And we can extract this complex type to be PathLike = Union[str, pathlib.Path]
and def foo(x: Optional[PathLike] = None): ...
. Otherwise, we need two typings of Union[str, pathlib.Path, None]
and Union[str, pathlib.Path]
.
There is a related disccusion at StackOverflow says why Optional
is suggested:
https://stackoverflow.com/questions/51710037/how-should-i-use-the-optional-type-hint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from ChatGPT:
In python, is there any difference between Optional[int] and Union[int, None]`?
Yes, there is a difference, but it's mainly in how they are expressed. Both Optional[int] and Union[int, None] represent the same type, which is either an integer or None. The difference lies in how you express this type annotation.
Optional[int] is a more concise and readable way to express a type that can either be an integer or None. It is equivalent to Union[int, None]. The Optional type is just a shorthand for a Union with None as one of the alternatives.
In Python, you can use both Optional[int] and Union[int, None] to annotate a variable or a function argument that accepts either an integer or None. However, it's generally recommended to use the Optional type for readability and simplicity.
from typing import Optional, Union
def example_optional(x: Optional[int]) -> None:
print(x)
def example_union(x: Union[int, None]) -> None:
print(x)
example_optional(42) # Prints 42
example_optional(None) # Prints None
example_union(42) # Prints 42
example_union(None) # Prints None
In both cases, the functions example_optional and example_union accept either an integer or None as their argument, and both function calls produce the same output.
And I asked ChatGPT about the practical difference in static type checkers mypy
.
Is there any difference between Optional[int] and Union[int, None] when using python type checkers like mypy?
No, there is no difference between Optional[int] and Union[int, None] when using Python type checkers like mypy.
Optional[int] is actually a shorthand for Union[int, None], and they are equivalent in terms of type checking. Both indicate that the annotated variable can either be an integer or None.
Using Optional[int] is generally preferred as it is more concise and easier to read. However, if you are using an older version of Python or a type checker that does not support Optional, you can use Union[int, None] instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Optional[int] is equivalent to Union[int, None] whereas more concise and readable, we're using Optional as the type annotation.
def run_bridge_server_as_subprocess( | ||
websocket_port: int, | ||
zmq_port: Optional[int] = None, | ||
ip_address: str = "127.0.0.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.0.0.0
may allow access to a larger range than 127.0.0.1
. Should we change the default value to 0.0.0.0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace the default ip address to 0.0.0.0 makes zmq fail to connect with client.
TODO: figure out why this happens.
time.sleep(0.5) | ||
|
||
message = "The bridge server subprocess failed." | ||
cleanup(process) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
process
in cleanup
is passed by arg list, but in poll_process
it looks like a global var.
Considering that the process
variable has a clear lifetime and these functions are strongly related to it, would it be better to rewrite this code as a class and access it through self.sub_process
?
@@ -0,0 +1,5 @@ | |||
pyzmq==25.0.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import umsgpack | ||
from typing import Tuple | ||
import numpy as np | ||
import cv2 as cv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about not as cv
? We use cv2
directly in other modules inside XRPrimer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed cv
to cv2
. The OpenCV is used to generate fake images for debug purpose, which should be further replaced by the nerf backend.
TODO: remove the dependency once the nerf backend is ready.
elif str(self.state.resolution) == "1080": | ||
return 1920, 1080 | ||
else: | ||
print("invalid resolution") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check logger example in class.
self.logger.error(msg)
logs the message in error level, if a file handler has been configured, the message will never be lost. After logging, by using raise ValueError, we can prevent the program from continuing to run and causing unexpected errors, which can make it easier for developers to identify the location where the error occurred.
Draw an image using current camera configuration. | ||
""" | ||
|
||
"""fetch data from state""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""fetch data from state""" | |
# fetch data from state |
pre-commit will find everything breaks rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue has been fixed by pre-commit.
""" | ||
Let the renderer relief for some time to avoid websocket blocking | ||
""" | ||
time.sleep(0.05) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 0.05? It looks like 20 fps. If the time parameter for sleep is a user-specified parameter that is set during construction or dynamically determined based on the program's running state, it may be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relief time is a time step that the backend sleep for some time to avoid websocket blocking. The value of it needs to be further evaluated. A more reasonable relief time would be:
e.g. If we want the viewer renders at 60fps, our per-frame budget is 16.6ms. Assuming that the nerf inference time is 5ms and viewer render latency is 4ms, the relif time is 16.6-5-4=7.6ms
Unfortunately, we do not have a really available backend up to now.
TODO: replace to a more reasonable relief time once the nerf backend is ready.
thread.start() | ||
thread.join(timeout_in_sec) | ||
except Exception as e: | ||
print("Failed to start thread") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try: | ||
thread.start() | ||
thread.join(timeout_in_sec) | ||
except Exception as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In most cases, we do not use Exception
because it corresponds to too broad of an error category. If we can identify a specific type of error, such as RuntimeError
or ValueError
, we should only catch the known and specific types of errors.
@@ -0,0 +1,23 @@ | |||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to redirect these logs to a designated path, such as logs/npm_log.txt
?
}, | ||
}, | ||
}, | ||
// MuiIcon: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these lines does not work, and it is no important comment, please remove them from official commit. To keep them, push another branch in a forked repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused code blocks removed.
viewers/nerf_viewer/README.md
Outdated
|
||
### 1.1 Install Dependencies | ||
|
||
#### 1.1.1 Install NVM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NVM is not a requirement but a recommendation.
Will it be better for users to choose their own method to install node.js?
And NVM
could be an optional choice like:
Install node.js 18.15.
It's suggested to use `NVM` to install and manage `node.js` installations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original version of README.md is for debug purpose. In the lastest doc, the installation guide has been replaced to:
The package.json
contains dependencies to build the viewer, which can be installed using Node Package Manager(npm
). It's suggested to manage Node.js
installations with Node Version Manager(nvm
). The installation instructions of nvm
can be found here.
viewers/nerf_viewer/README.md
Outdated
|
||
Please follow the instructions in: | ||
|
||
https://juejin.cn/post/7120267871950733320/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a blog in Chinese not suitable for non-Chinese users and only for windows platform. For i18n, post official installation instructions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original version of README.md is for debug purpose. In the lastest doc, the link for nvm installation guidelines has been replaced from https://juejin.cn/post/7120267871950733320/ to https://heynode.com/tutorial/install-nodejs-locally-nvm/.
viewers/nerf_viewer/README.md
Outdated
|
||
```shell | ||
# install node 18.15.0 | ||
nvm install 18.15.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nodejs 18.15 could be precise enough. Don't pin the patch version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patch version has been removed: 18.15.0
-> 18.15
@@ -0,0 +1,5 @@ | |||
pyzmq==25.0.2 | |||
pyngrok==5.2.1 | |||
tornado |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pin tornado's major version to prevent incompatibility (i.e. tornado>=6,<7
), since a major version update could probably break current codes.
def check_origin(self, origin: str) -> bool: | ||
return True | ||
|
||
def open(self, *args: str, **kwargs: str): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are args
of List[str] & kwargs
of Dict[str, str]?
Since they are not used, their typings could be omitted.
import time | ||
import base64 | ||
import pickle | ||
import umsgpack | ||
from typing import Tuple | ||
import numpy as np | ||
import cv2 as cv | ||
from actions import UPDATE_STATE, UPDATE_RENDER_RESULT | ||
from bridge_server_subprocess import run_bridge_server_as_subprocess | ||
from visualizer import Viewer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imports unsorted.
Recommended to run isort
to update all bridge_servers
python files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All python imports have been sorted by isort in pre-commit.
@@ -0,0 +1,38 @@ | |||
/* .App { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file includes only commented contents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused file removed.
@@ -0,0 +1,31 @@ | |||
// /* eslint-disable no-underscore-dangle */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file includes only commented contents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused file removed.
|
||
def run_bridge_server_as_subprocess( | ||
websocket_port: int, | ||
zmq_port: Optional[int] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt the response from ChatGPT. According to PEP484 which is the official definitions of python typing hints, Optional[...]
is no more than a shorthand of Union[..., None]
. It says in The typing
module section:
Optional, defined by Optional[t] == Union[t, None]
So do the documentation of typing.Optional:
Optional[X] is equivalent to X | None (or Union[X, None]).
It's also recommended to use Optional[...]
for readability. Since for complex types, we could combine Union
with Optional
. For example, from def foo(x: Optional[Union[str, pathlib.Path]] = None): ...
, we know that foo
accepts a path-like argument or None
as default. And we can extract this complex type to be PathLike = Union[str, pathlib.Path]
and def foo(x: Optional[PathLike] = None): ...
. Otherwise, we need two typings of Union[str, pathlib.Path, None]
and Union[str, pathlib.Path]
.
There is a related disccusion at StackOverflow says why Optional
is suggested:
https://stackoverflow.com/questions/51710037/how-should-i-use-the-optional-type-hint
|
||
def run_bridge_server_as_subprocess( | ||
websocket_port: int, | ||
zmq_port: Optional[int] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from ChatGPT:
In python, is there any difference between Optional[int] and Union[int, None]`?
Yes, there is a difference, but it's mainly in how they are expressed. Both Optional[int] and Union[int, None] represent the same type, which is either an integer or None. The difference lies in how you express this type annotation.
Optional[int] is a more concise and readable way to express a type that can either be an integer or None. It is equivalent to Union[int, None]. The Optional type is just a shorthand for a Union with None as one of the alternatives.
In Python, you can use both Optional[int] and Union[int, None] to annotate a variable or a function argument that accepts either an integer or None. However, it's generally recommended to use the Optional type for readability and simplicity.
from typing import Optional, Union
def example_optional(x: Optional[int]) -> None:
print(x)
def example_union(x: Union[int, None]) -> None:
print(x)
example_optional(42) # Prints 42
example_optional(None) # Prints None
example_union(42) # Prints 42
example_union(None) # Prints None
In both cases, the functions example_optional and example_union accept either an integer or None as their argument, and both function calls produce the same output.
And I asked ChatGPT about the practical difference in static type checkers mypy
.
Is there any difference between Optional[int] and Union[int, None] when using python type checkers like mypy?
No, there is no difference between Optional[int] and Union[int, None] when using Python type checkers like mypy.
Optional[int] is actually a shorthand for Union[int, None], and they are equivalent in terms of type checking. Both indicate that the annotated variable can either be an integer or None.
Using Optional[int] is generally preferred as it is more concise and easier to read. However, if you are using an older version of Python or a type checker that does not support Optional, you can use Union[int, None] instead.
…nderer/xrnerf 2. Move XRNerf bridge server from viewers/nerf_viewer/bridge_server to python/xrprimer/services/xrnerf
2. Optimized data flow that greatly reduces the react dom element refresh frequency
2.[improvement] Introduced 'typer' for CLI parsing and better printing functionality
…rer/xrnerf/, docs/en/services/xrnerf/ respectively; 2.[improvement] added an architecture diagram in the viewer doc; 3.[improvement] updated installation instructions
…vices/xrnerf/ to requirements/
|
|
|
…rt, the server will check whether the port is already in use and then create connections using zmq, otherwise the server will automatically find an available port
2.[improvement] fix typos
add nerf viewer client and server.