Breeze1124 commited on
Commit
04c1763
·
1 Parent(s): 304c700
Files changed (1) hide show
  1. app.py +64 -47
app.py CHANGED
@@ -1,7 +1,8 @@
1
  import gradio as gr
2
  import os
 
3
 
4
- # 獲取當前絕對路徑,確保讀取檔案無誤
5
  BASE_DIR = os.path.abspath(os.getcwd())
6
 
7
  SCENES = [
@@ -28,57 +29,80 @@ SCENES = [
28
  gallery_items = [(item["thumb"], item["name"]) for item in SCENES]
29
 
30
  def load_scene(evt: gr.SelectData, request: gr.Request):
31
- """
32
- 載入選定的場景並生成自動播放的 iframe 連結
33
- request: 用來獲取當前 Gradio 的網址 (localhost 或 share link)
34
- """
35
  index = evt.index
36
  scene = SCENES[index]
37
 
 
38
  full_model_path = os.path.join(BASE_DIR, scene["model"])
39
 
40
  if not os.path.exists(full_model_path):
41
  return (
42
- "<div style='text-align:center; padding:50px'>⚠️ File not found</div>",
43
  None,
44
- f"**⚠️ Error:** File not found: {scene['model']}"
45
  )
46
 
47
- # 1. 取得你目前的 Gradio 伺服器網址 (例如 https://xxxx.gradio.live 或 http://127.0.0.1:7860)
48
- # 注意:如果是在本地跑且沒有 share=True,這個網址通常是 http
 
 
 
 
 
 
 
 
49
  if request:
50
- host = request.headers.get("host") # e.g. "7213...gradio.live"
51
- # 判斷是 http 還是 https (Gradio Share 連結通常是 https)
52
- protocol = "https" if "gradio.live" in host else "http"
53
- base_url = f"{protocol}://{host}"
54
- else:
55
- base_url = "http://127.0.0.1:7860"
56
 
57
- # 2. 組合檔案的下載連結 (Gradio 的 /file/ 路徑)
58
- # 注意 Windows路徑的反斜線可能需要處理,但在 Gradio file serving 通常沒問題
59
- file_url = f"{base_url}/file={full_model_path}"
 
60
 
61
- # 3. 組合外部 Viewer 的連結 (利用 ?url= 參數)
62
- viewer_url = f"https://antimatter15.com/splat/?url={file_url}"
 
63
 
64
- print(f"🔗 Generated Link: {viewer_url}") # Debug 用,可以在終端機看到連結
65
-
66
- # 4. 生成 HTML
67
- html = f"""
68
- <iframe
69
- src="{viewer_url}"
70
- width="100%"
71
- height="600px"
72
- frameborder="0"
73
- allow="camera; gpu"
74
- style="border-radius: 8px; background: #000;"
75
- ></iframe>
76
- """
77
 
 
 
 
 
 
 
78
  # 提示訊息
79
- status_msg = f"**{scene['name']}** - Auto-loading via External Viewer..."
80
- if protocol == "http":
81
- status_msg += "\n\n⚠️ **Note:** If screen is black, use `share=True` (see explanation)."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  return (
84
  html,
@@ -86,11 +110,9 @@ def load_scene(evt: gr.SelectData, request: gr.Request):
86
  status_msg
87
  )
88
 
89
- # --- UI ---
90
  with gr.Blocks(title="RGS-SLAM Demo") as demo:
91
-
92
  gr.Markdown("# 🚀 RGS-SLAM Gaussian Splatting Viewer")
93
-
94
  with gr.Row():
95
  with gr.Column(scale=1):
96
  gr.Markdown("### 📂 Select Scene")
@@ -102,26 +124,21 @@ with gr.Blocks(title="RGS-SLAM Demo") as demo:
102
  object_fit="contain",
103
  allow_preview=False
104
  )
105
-
106
  with gr.Column(scale=3):
107
  status = gr.Markdown("**👈 Select a scene to auto-load**")
108
-
109
  with gr.Tab("🎯 3D Viewer"):
110
- # 初始狀態為空
111
  viewer_frame = gr.HTML(
112
  value="<div style='text-align: center; padding: 100px; color: #666;'>Select a scene</div>"
113
  )
114
-
115
  with gr.Tab("📍 Camera Trajectory"):
116
  trajectory_img = gr.Image(label="Camera Path", height=600)
117
 
118
  scene_gallery.select(
119
  fn=load_scene,
120
- inputs=None, # inputs 不需要顯式傳入,gr.SelectData 會自動處理
121
  outputs=[viewer_frame, trajectory_img, status]
122
  )
123
 
124
  if __name__ == "__main__":
125
- # 關鍵:allowed_paths 允許 Gradio 讀取當前資料夾的檔案
126
- # 建議開啟 share=True 以解決 HTTPS 跨域問題
127
- demo.launch(share=True, allowed_paths=[BASE_DIR])
 
1
  import gradio as gr
2
  import os
3
+ import urllib.parse # 新增:用於處理網址編碼
4
 
5
+ # 獲取當前絕對路徑
6
  BASE_DIR = os.path.abspath(os.getcwd())
7
 
8
  SCENES = [
 
29
  gallery_items = [(item["thumb"], item["name"]) for item in SCENES]
30
 
31
  def load_scene(evt: gr.SelectData, request: gr.Request):
 
 
 
 
32
  index = evt.index
33
  scene = SCENES[index]
34
 
35
+ # 組合絕對路徑
36
  full_model_path = os.path.join(BASE_DIR, scene["model"])
37
 
38
  if not os.path.exists(full_model_path):
39
  return (
40
+ "<div style='text-align:center; padding:50px; color:red'>⚠️ File not found</div>",
41
  None,
42
+ f"**⚠️ Error:** File not found: {full_model_path}"
43
  )
44
 
45
+ # --- 關鍵修正開始 ---
46
+
47
+ # 1. 處理 Windows 路徑 (將 \ 轉為 /)
48
+ # Gradio 的 file路由需要正斜線,且不能有磁碟機代號之後的雙反斜線混亂
49
+ clean_path = full_model_path.replace("\\", "/")
50
+
51
+ # 2. 判斷網址 (這是最容易報錯的地方)
52
+ base_url = "http://127.0.0.1:7860" # 預設值
53
+ is_https = False
54
+
55
  if request:
56
+ host = request.headers.get("host")
57
+ if "gradio.live" in host:
58
+ base_url = f"https://{host}"
59
+ is_https = True
60
+ else:
61
+ base_url = f"http://{host}"
62
 
63
+ # 3. 組合檔案連結並進行 URL 編碼
64
+ # 我們只對路徑部分進行編碼,避免空白變成無效字元
65
+ # 瀏覽器看到的連結會類似: https://xxx.gradio.live/file=D:/Path/To/File.ply
66
+ file_url = f"{base_url}/file={clean_path}"
67
 
68
+ # file_url 再進行一次完整編碼,因為它將作為 ?url= 的參數傳遞給外部網站
69
+ # 外部網站讀取時會解碼一次
70
+ encoded_file_url = urllib.parse.quote(file_url, safe=':/')
71
 
72
+ # 4. 組合外部 Viewer 連結
73
+ viewer_url = f"https://antimatter15.com/splat/?url={encoded_file_url}"
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ print(f"🔗 Base URL: {base_url}")
76
+ print(f"📂 File URL: {file_url}")
77
+ print(f"🚀 Final Viewer URL: {viewer_url}")
78
+
79
+ # --- 關鍵修正結束 ---
80
+
81
  # 提示訊息
82
+ if not is_https:
83
+ status_msg = f"""
84
+ ### ⚠️ 警告:無法載入 (CORS Error)
85
+ 偵測到您正在使用 **Localhost (http)**。
86
+ 由於安全性限制,外部 Viewer (https) 無法讀取您的本機檔案。
87
+
88
+ **請解決:**
89
+ 1. 查看終端機 (Terminal)。
90
+ 2. 複製 **Running on public URL: https://xxxx.gradio.live** 的連結。
91
+ 3. 用該連結開啟網頁,即可正常顯示。
92
+ """
93
+ html = f"<div style='background:#333; color:white; padding:20px; border-radius:10px;'>{status_msg}</div>"
94
+ else:
95
+ status_msg = f"**{scene['name']}** Loaded successfully from {base_url}"
96
+ html = f"""
97
+ <iframe
98
+ src="{viewer_url}"
99
+ width="100%"
100
+ height="600px"
101
+ frameborder="0"
102
+ allow="camera; display-capture"
103
+ style="border-radius: 8px; background: #000;"
104
+ ></iframe>
105
+ """
106
 
107
  return (
108
  html,
 
110
  status_msg
111
  )
112
 
113
+ # --- UI (保持不變) ---
114
  with gr.Blocks(title="RGS-SLAM Demo") as demo:
 
115
  gr.Markdown("# 🚀 RGS-SLAM Gaussian Splatting Viewer")
 
116
  with gr.Row():
117
  with gr.Column(scale=1):
118
  gr.Markdown("### 📂 Select Scene")
 
124
  object_fit="contain",
125
  allow_preview=False
126
  )
 
127
  with gr.Column(scale=3):
128
  status = gr.Markdown("**👈 Select a scene to auto-load**")
 
129
  with gr.Tab("🎯 3D Viewer"):
 
130
  viewer_frame = gr.HTML(
131
  value="<div style='text-align: center; padding: 100px; color: #666;'>Select a scene</div>"
132
  )
 
133
  with gr.Tab("📍 Camera Trajectory"):
134
  trajectory_img = gr.Image(label="Camera Path", height=600)
135
 
136
  scene_gallery.select(
137
  fn=load_scene,
138
+ inputs=None,
139
  outputs=[viewer_frame, trajectory_img, status]
140
  )
141
 
142
  if __name__ == "__main__":
143
+ # 這裡必須保留 share=True
144
+ demo.launch(share=True, allowed_paths=[BASE_DIR])