Surn commited on
Commit
7f0bd23
·
1 Parent(s): 6b95b0d

Add versions info and project description

Browse files
Files changed (3) hide show
  1. README.md +71 -0
  2. app.py +19 -11
  3. modules/version_info.py +127 -0
README.md CHANGED
@@ -16,4 +16,75 @@ thumbnail: >-
16
  https://cdn-uploads.huggingface.co/production/uploads/6346595c9e5f0fe83fc60444/s0fQvcoiSBlH36AXpVwPi.png
17
  ---
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
16
  https://cdn-uploads.huggingface.co/production/uploads/6346595c9e5f0fe83fc60444/s0fQvcoiSBlH36AXpVwPi.png
17
  ---
18
 
19
+ # 3D Viewer
20
+
21
+ **3D Viewer** is a lightweight web application built with [Gradio](https://gradio.app) that allows users to view 3D models along with their corresponding height map and source images. The app dynamically loads these resources by parsing URL query string parameters, providing a seamless and interactive experience.
22
+
23
+ ## Features
24
+
25
+ - **3D Model Display:**
26
+ Uses `gr.Model3D` to render 3D models dynamically from a URL parameter (`3d`).
27
+
28
+ - **Image Slider:**
29
+ Displays images (height map and source image) using `gr.ImageSlider`. The images are loaded via URL query parameters named `hm` (height map) and `image` (source image).
30
+
31
+ - **File Upload:**
32
+ Includes an `gr.UploadButton` for uploading new file types like `.glb`, `.gltf`, `.obj`, `.png`, `.jpg`, and `.ply`.
33
+
34
+ - **Custom Theming:**
35
+ The interface is styled with the `Surn/Beeuty` theme to ensure a modern and cohesive look.
36
+
37
+ ## How It Works
38
+
39
+ - **Query String Parsing:**
40
+ While running in Gradio, since the Python callback does not operate within a conventional HTTP request context, the app retrieves query string values by using client-side JavaScript. This JavaScript snippet captures the URL parameters and passes them to the Python callback, which then updates the components accordingly.
41
+
42
+ - **Static Paths:**
43
+ The app sets static paths for directories such as `images/`, `models/`, and `assets/` for accessing local resources.
44
+
45
+ ## Getting Started
46
+
47
+ 1. **Install Dependencies:**
48
+
49
+ Ensure you have Python 3.12.8 installed and install Gradio (v5.29.0 or compatible):
50
+
51
+ ```pip install gradio==5.29.0```
52
+
53
+
54
+ 2. **Run the Application:**
55
+
56
+ Start the app by executing:
57
+
58
+ ```python app.py```
59
+
60
+
61
+ 3. **Use the Query String:**
62
+
63
+ After launching, the app can load specific resources if you pass the following query parameters in the URL:
64
+
65
+ - `3d`: URL for the 3D model (e.g., `?3d=https://example.com/model.glb`)
66
+ - `hm`: URL for the height map image (e.g., `?hm=https://example.com/heightmap.png`)
67
+ - `image`: URL for the source image (e.g., `?image=https://example.com/source.png`)
68
+
69
+ Example URL:
70
+
71
+ ```http://localhost:7860/?3d=https://example.com/model.glb&hm=https://example.com/heightmap.png&image=https://example.com/source.png```
72
+
73
+
74
+ ## Project Structure
75
+
76
+ - **app.py:**
77
+ The core application script defining the Gradio interface, callbacks, and dynamic query string processing.
78
+
79
+ - **README.md:**
80
+ This documentation file outlining the project details and configuration.
81
+
82
+ - **assets, images, models:**
83
+ Directories containing static resources such as images, 3D models, and other assets.
84
+
85
+ ## License
86
+
87
+ This project is licensed under the Apache-2.0 license.
88
+
89
+
90
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,4 +1,9 @@
1
  import gradio as gr
 
 
 
 
 
2
 
3
  def load_data(query_params, model_3d, image_slider):
4
  # set default values or pull from querystring
@@ -21,23 +26,26 @@ with gr.Blocks(css_paths="style_20250314.css", title="3D viewer", theme='Surn/Be
21
  gr.Markdown("# 3D Model Viewer")
22
 
23
  with gr.Row():
24
- model_3d = gr.Model3D(
25
- label="3D Model",
26
- value=None,
27
- height=400
28
- )
29
- image_slider = gr.ImageSlider(
30
- label="Images",
31
- value=None,
32
- height=400
33
- )
 
34
 
35
  with gr.Row():
36
  upload_btn = gr.UploadButton(
37
  "Upload",
38
  file_types=[".glb", ".gltf", ".obj", ".png", ".jpg", ".ply"]
39
  )
40
-
 
 
41
  # Use JavaScript to pass the query parameters to your callback.
42
  viewer3d.load(
43
  load_data,
 
1
  import gradio as gr
2
+ import modules.version_info as version_info
3
+
4
+ def getVersions():
5
+ #return html_versions
6
+ return version_info.versions_html()
7
 
8
  def load_data(query_params, model_3d, image_slider):
9
  # set default values or pull from querystring
 
26
  gr.Markdown("# 3D Model Viewer")
27
 
28
  with gr.Row():
29
+ with gr.Column():
30
+ model_3d = gr.Model3D(
31
+ label="3D Model",
32
+ value=None,
33
+ height=400
34
+ )
35
+ image_slider = gr.ImageSlider(
36
+ label="Images",
37
+ value=None,
38
+ height=400
39
+ )
40
 
41
  with gr.Row():
42
  upload_btn = gr.UploadButton(
43
  "Upload",
44
  file_types=[".glb", ".gltf", ".obj", ".png", ".jpg", ".ply"]
45
  )
46
+ with gr.Row():
47
+ gr.HTML(value=getVersions(), visible=True, elem_id="versions")
48
+
49
  # Use JavaScript to pass the query parameters to your callback.
50
  viewer3d.load(
51
  load_data,
modules/version_info.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # modules/version_info.py
2
+
3
+ import subprocess
4
+ import os
5
+ import sys
6
+ import gc
7
+ import gradio as gr
8
+
9
+ git = os.environ.get('GIT', "git")
10
+
11
+ def commit_hash():
12
+ try:
13
+ return subprocess.check_output([git, "rev-parse", "HEAD"], shell=False, encoding='utf8').strip()
14
+ except Exception:
15
+ return "<none>"
16
+
17
+ def get_xformers_version():
18
+ try:
19
+ import xformers
20
+ return xformers.__version__
21
+ except Exception:
22
+ return "<none>"
23
+ def get_transformers_version():
24
+ try:
25
+ import transformers
26
+ return transformers.__version__
27
+ except Exception:
28
+ return "<none>"
29
+
30
+ def get_accelerate_version():
31
+ try:
32
+ import accelerate
33
+ return accelerate.__version__
34
+ except Exception:
35
+ return "<none>"
36
+ def get_safetensors_version():
37
+ try:
38
+ import safetensors
39
+ return safetensors.__version__
40
+ except Exception:
41
+ return "<none>"
42
+ def get_diffusers_version():
43
+ try:
44
+ import diffusers
45
+ return diffusers.__version__
46
+ except Exception:
47
+ return "<none>"
48
+ def get_open3d_version():
49
+ try:
50
+ import open3d
51
+ return f"{open3d.__version__} cuda:{open3d.core.cuda.is_available()}"
52
+ except Exception:
53
+ return "<none>"
54
+
55
+ def get_torch_info():
56
+ from torch import __version__ as torch_version_, version, cuda, backends
57
+ initialize_cuda()
58
+ try:
59
+ info = [torch_version_, f"CUDA Version:{version.cuda}", f"Available:{cuda.is_available()}", f"flash attention enabled: {backends.cuda.flash_sdp_enabled()}", f"Capabilities: {cuda.get_device_capability(0)}", f"Device Name: {cuda.get_device_name(0)}", f"Device Count: {cuda.device_count()}",f"Devices: {os.environ['CUDA_VISIBLE_DEVICES']}", f"Zero :{os.environ['CUDA_MODULE_LOADING']}"]
60
+ del torch_version_, version, cuda, backends
61
+ return info
62
+ except Exception:
63
+ del torch_version_, version, cuda, backends
64
+ return "<none>"
65
+
66
+ def release_torch_resources():
67
+ from torch import cuda
68
+ if cuda.is_available():
69
+ # Clear the CUDA cache
70
+ cuda.empty_cache()
71
+ cuda.ipc_collect()
72
+ # Delete any objects that are using GPU memory
73
+ #for obj in gc.get_objects():
74
+ # if is_tensor(obj) or (hasattr(obj, 'data') and is_tensor(obj.data)):
75
+ # del obj
76
+ # Run garbage collection
77
+ del cuda
78
+ gc.collect()
79
+
80
+
81
+ def initialize_cuda():
82
+ from torch import cuda, version
83
+ if cuda.is_available():
84
+ device = cuda.device("cuda")
85
+ print(f"CUDA is available. Using device: {cuda.get_device_name(0)} with CUDA version: {version.cuda}")
86
+ result = "cuda"
87
+ else:
88
+ #device = cuda.device("cpu")
89
+ print("CUDA is not available. Using CPU.")
90
+ result = "cpu"
91
+ return result
92
+
93
+ def versions_html():
94
+ from torch import __version__ as torch_version_
95
+ python_version = ".".join([str(x) for x in sys.version_info[0:3]])
96
+ commit = commit_hash()
97
+
98
+ # Define the Toggle Dark Mode link with JavaScript
99
+ toggle_dark_link = '''
100
+ <a href="#" onclick="document.body.classList.toggle('dark'); return false;" style="cursor: pointer; text-decoration: underline;">
101
+ Toggle Dark Mode
102
+ </a>
103
+ '''
104
+
105
+ v_html = f"""
106
+ version: <a href="https://huggingface.co/spaces/Surn/3D-Viewer/commit/{"huggingface" if commit == "<none>" else commit}" target="_blank">{"huggingface" if commit == "<none>" else commit}</a>
107
+ &#x2000;•&#x2000;
108
+ python: <span title="{sys.version}">{python_version}</span>
109
+ &#x2000;•&#x2000;
110
+ torch: {torch_version_}
111
+ &#x2000;•&#x2000;
112
+ diffusers: {get_diffusers_version()}
113
+ &#x2000;•&#x2000;
114
+ transformers: {get_transformers_version()}
115
+ &#x2000;•&#x2000;
116
+ safetensors: {get_safetensors_version()}
117
+ &#x2000;•&#x2000;
118
+ open3d: {get_open3d_version()}
119
+ &#x2000;•&#x2000;
120
+ gradio: {gr.__version__}
121
+ &#x2000;•&#x2000;
122
+ {toggle_dark_link}
123
+ <br>
124
+ Full GPU Info:{get_torch_info()}
125
+ """
126
+ del torch_version_
127
+ return v_html