xinjjj commited on
Commit
1d37bbc
·
1 Parent(s): 1bbfd93
app.py CHANGED
@@ -34,7 +34,7 @@ import gradio as gr
34
  import numpy as np
35
  import pandas as pd
36
  import trimesh
37
- from app_style import custom_theme, lighting_css
38
  from embodied_gen.utils.tags import VERSION
39
 
40
  try:
@@ -124,6 +124,7 @@ os.makedirs(TMP_DIR, exist_ok=True)
124
  css = """
125
  .gradio-container .gradio-group { box-shadow: 0 2px 4px rgba(0,0,0,0.05) !important; }
126
  #asset-gallery { border: 1px solid #E5E7EB; border-radius: 8px; padding: 8px; background-color: #F9FAFB; }
 
127
  """
128
 
129
  lighting_css = """
@@ -724,13 +725,33 @@ def download_mjcf(asset_dir: str, req: gr.Request) -> str | None:
724
  return zip_path
725
 
726
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
  # Download buttons keyed by format; order matches the outputs list used when
728
  # locking/unlocking them together.
729
- _DL_KEYS = ("urdf", "usd", "mjcf")
730
  _DL_LABELS = {
731
  "urdf": "⬇️ Download URDF",
732
  "usd": "⬇️ Download USD",
733
  "mjcf": "⬇️ Download MJCF",
 
734
  }
735
 
736
 
@@ -780,7 +801,7 @@ with gr.Blocks(
780
  css=css,
781
  title="3D Asset Library",
782
  ) as demo:
783
- gr.HTML(lighting_css, visible=False)
784
  gr.Markdown(
785
  """
786
  ## 🏛️ ***EmbodiedGen***: 3D Asset Gallery Explorer
@@ -931,7 +952,7 @@ with gr.Blocks(
931
  urdf_file = gr.Textbox(
932
  label="URDF File Path", interactive=False, lines=2
933
  )
934
- with gr.Row():
935
  # DownloadButtons that build their zip into their own value
936
  # on click; a chained JS handler then triggers the browser
937
  # download from that value (one-click). If the JS ever
@@ -952,6 +973,11 @@ with gr.Blocks(
952
  variant="primary",
953
  interactive=False,
954
  )
 
 
 
 
 
955
 
956
  search_button.click(
957
  fn=search_assets,
@@ -1030,7 +1056,7 @@ with gr.Blocks(
1030
  ],
1031
  ).success(
1032
  fn=_reset_downloads,
1033
- outputs=[urdf_dl_btn, usd_dl_btn, mjcf_dl_btn],
1034
  )
1035
 
1036
  # After the zip is built into the button's own value, pass that file value
@@ -1050,7 +1076,7 @@ with gr.Blocks(
1050
  }
1051
  """
1052
 
1053
- dl_btns = [urdf_dl_btn, usd_dl_btn, mjcf_dl_btn]
1054
 
1055
  # Each flow: lock all buttons (prevent spam clicks) -> build the zip ->
1056
  # JS-trigger the browser download -> unlock. Selecting another asset
@@ -1077,6 +1103,16 @@ with gr.Blocks(
1077
  fn=_unlock_downloads, outputs=dl_btns
1078
  )
1079
 
 
 
 
 
 
 
 
 
 
 
1080
  demo.load(start_session)
1081
  demo.unload(end_session)
1082
 
 
34
  import numpy as np
35
  import pandas as pd
36
  import trimesh
37
+ from app_style import custom_theme
38
  from embodied_gen.utils.tags import VERSION
39
 
40
  try:
 
124
  css = """
125
  .gradio-container .gradio-group { box-shadow: 0 2px 4px rgba(0,0,0,0.05) !important; }
126
  #asset-gallery { border: 1px solid #E5E7EB; border-radius: 8px; padding: 8px; background-color: #F9FAFB; }
127
+ #download-row button { white-space: nowrap; }
128
  """
129
 
130
  lighting_css = """
 
725
  return zip_path
726
 
727
 
728
+ def download_affordance(asset_dir: str, req: gr.Request) -> str | None:
729
+ """Package the ``affordance/`` folder."""
730
+ if not asset_dir or not os.path.isdir(asset_dir):
731
+ gr.Warning("Please select an asset first.")
732
+ return None
733
+
734
+ gr.Info("⏳ Preparing affordance asset for download, please wait...")
735
+ ensure_hf_files([f"{_rel_dir(asset_dir)}/affordance/**"])
736
+ affordance_dir = os.path.join(asset_dir, "affordance")
737
+ if not os.path.isdir(affordance_dir):
738
+ gr.Warning("No affordance folder available for this asset.")
739
+ return None
740
+
741
+ zip_path, uid, zip_name = _fmt_zip_path(asset_dir, "affordance", req)
742
+ _zip_items(zip_path, [(affordance_dir, "affordance")])
743
+ gr.Info(f"✅ {zip_name} is ready.")
744
+ return zip_path
745
+
746
+
747
  # Download buttons keyed by format; order matches the outputs list used when
748
  # locking/unlocking them together.
749
+ _DL_KEYS = ("urdf", "usd", "mjcf", "affordance")
750
  _DL_LABELS = {
751
  "urdf": "⬇️ Download URDF",
752
  "usd": "⬇️ Download USD",
753
  "mjcf": "⬇️ Download MJCF",
754
+ "affordance": "⬇️ Affordance",
755
  }
756
 
757
 
 
801
  css=css,
802
  title="3D Asset Library",
803
  ) as demo:
804
+ # gr.HTML(lighting_css, visible=False)
805
  gr.Markdown(
806
  """
807
  ## 🏛️ ***EmbodiedGen***: 3D Asset Gallery Explorer
 
952
  urdf_file = gr.Textbox(
953
  label="URDF File Path", interactive=False, lines=2
954
  )
955
+ with gr.Row(elem_id="download-row"):
956
  # DownloadButtons that build their zip into their own value
957
  # on click; a chained JS handler then triggers the browser
958
  # download from that value (one-click). If the JS ever
 
973
  variant="primary",
974
  interactive=False,
975
  )
976
+ affordance_dl_btn = gr.DownloadButton(
977
+ label="⬇️ Affordance",
978
+ variant="primary",
979
+ interactive=False,
980
+ )
981
 
982
  search_button.click(
983
  fn=search_assets,
 
1056
  ],
1057
  ).success(
1058
  fn=_reset_downloads,
1059
+ outputs=[urdf_dl_btn, usd_dl_btn, mjcf_dl_btn, affordance_dl_btn],
1060
  )
1061
 
1062
  # After the zip is built into the button's own value, pass that file value
 
1076
  }
1077
  """
1078
 
1079
+ dl_btns = [urdf_dl_btn, usd_dl_btn, mjcf_dl_btn, affordance_dl_btn]
1080
 
1081
  # Each flow: lock all buttons (prevent spam clicks) -> build the zip ->
1082
  # JS-trigger the browser download -> unlock. Selecting another asset
 
1103
  fn=_unlock_downloads, outputs=dl_btns
1104
  )
1105
 
1106
+ affordance_dl_btn.click(
1107
+ fn=lambda: _lock_downloads("affordance"), outputs=dl_btns
1108
+ ).then(
1109
+ fn=download_affordance,
1110
+ inputs=[asset_folder],
1111
+ outputs=[affordance_dl_btn],
1112
+ ).then(
1113
+ fn=lambda *a: None, inputs=[affordance_dl_btn], js=download_js
1114
+ ).then(fn=_unlock_downloads, outputs=dl_btns)
1115
+
1116
  demo.load(start_session)
1117
  demo.unload(end_session)
1118
 
embodied_gen/utils/gpt_clients.py CHANGED
@@ -255,7 +255,10 @@ class GPTclient:
255
  if is_gpt5:
256
  # GPT-5.x rejects custom temperature/top_p/penalty/stop and
257
  # uses `max_completion_tokens` instead of `max_tokens`.
258
- if "max_tokens" in params and "max_completion_tokens" not in params:
 
 
 
259
  params["max_completion_tokens"] = params.pop("max_tokens")
260
  for k in (
261
  "temperature",
 
255
  if is_gpt5:
256
  # GPT-5.x rejects custom temperature/top_p/penalty/stop and
257
  # uses `max_completion_tokens` instead of `max_tokens`.
258
+ if (
259
+ "max_tokens" in params
260
+ and "max_completion_tokens" not in params
261
+ ):
262
  params["max_completion_tokens"] = params.pop("max_tokens")
263
  for k in (
264
  "temperature",
embodied_gen/utils/gpt_config.yaml CHANGED
@@ -1,5 +1,5 @@
1
  # config.yaml
2
- agent_type: "gpt-5.4" # gpt-4o, gpt-5.4 or qwen2.5-vl
3
 
4
  gpt-4o:
5
  endpoint: https://xxx.openai.azure.com
@@ -13,8 +13,8 @@ gpt-5.4:
13
  api_version: 2024-12-01-preview
14
  model_name: gpt-5.4
15
 
16
- qwen2.5-vl:
17
  endpoint: https://openrouter.ai/api/v1
18
  api_key: sk-or-v1-xxx
19
  api_version: null
20
- model_name: qwen/qwen2.5-vl-72b-instruct:free
 
1
  # config.yaml
2
+ agent_type: "gpt-5.4" # gpt-4o, gpt-5.4 or gemma-4-31b
3
 
4
  gpt-4o:
5
  endpoint: https://xxx.openai.azure.com
 
13
  api_version: 2024-12-01-preview
14
  model_name: gpt-5.4
15
 
16
+ gemma-4-31b:
17
  endpoint: https://openrouter.ai/api/v1
18
  api_key: sk-or-v1-xxx
19
  api_version: null
20
+ model_name: google/gemma-4-31b-it:free
embodied_gen/utils/tags.py CHANGED
@@ -1 +1 @@
1
- VERSION = "v0.1.8"
 
1
+ VERSION = "v2.0.0"