ginipick commited on
Commit
73ae303
Β·
verified Β·
1 Parent(s): 8503628

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -13
app.py CHANGED
@@ -3,8 +3,6 @@ GLB μ• λ‹ˆλ©”μ΄μ…˜ 생성기
3
  ────────────────────────────────────────────────────────
4
  μ—…λ‘œλ“œν•œ GLB 3D λͺ¨λΈμ— νšŒμ „Β·λΆ€μœ Β·ν­λ°œ λ“± μ• λ‹ˆλ©”μ΄μ…˜μ„ μ μš©ν•΄
5
  β‘  λ³€ν˜•λœ GLB β‘‘ μ‹€μ œ λͺ¨λΈμ„ λ Œλ”λ§ν•œ GIF β‘’ 메타데이터 JSON 을 λŒλ €μ€λ‹ˆλ‹€.
6
- β€’ headless μ„œλ²„ λŒ€μ‘: EGL + pyglet.headless + trimesh β†’ μ‹€νŒ¨ μ‹œ pyrender 폴백
7
- β€’ μ΅œλŒ€ 60 fpsΒ·60 ν”„λ ˆμž„λ‘œ μ œν•œ (데λͺ¨ λͺ©μ )
8
  """
9
 
10
  # ──────────────────── 1. 곡톡 λͺ¨λ“ˆ ────────────────────
@@ -13,8 +11,8 @@ import numpy as np
13
  from PIL import Image
14
 
15
  import pyglet
16
- pyglet.options["headless"] = True # λ°˜λ“œμ‹œ trimesh 전에!
17
- os.environ["PYOPENGL_PLATFORM"] = "egl" # Off-screen GL
18
 
19
  import trimesh
20
  import trimesh.transformations as tf
@@ -33,7 +31,7 @@ def _render_with_trimesh(scene: trimesh.Scene, res):
33
  return Image.open(io.BytesIO(png)).convert("RGB")
34
 
35
  def _render_with_pyrender(mesh_or_scene, res):
36
- import pyrender # μ§€μ—° μž„ν¬νŠΈ
37
  if isinstance(mesh_or_scene, trimesh.Scene):
38
  mesh = trimesh.util.concatenate(mesh_or_scene.dump())
39
  else:
@@ -59,7 +57,6 @@ def create_model_animation_gif(
59
  fps: int = 30,
60
  resolution=(640, 480),
61
  ):
62
- """GLB λͺ¨λΈμ„ μ‹€μ œ λ Œλ”λ§ν•˜μ—¬ μ• λ‹ˆλ©”μ΄μ…˜ GIF 생성"""
63
  base = trimesh.load(input_glb_path)
64
  if isinstance(base, trimesh.Trimesh):
65
  base = trimesh.Scene(base)
@@ -70,7 +67,6 @@ def create_model_animation_gif(
70
  t = i / (num_frames - 1)
71
  scene = base.copy()
72
 
73
- # λ³€ν™˜ ν–‰λ ¬
74
  if animation_type == "rotate":
75
  M = tf.rotation_matrix(2 * math.pi * t, [0, 1, 0])
76
  elif animation_type == "float":
@@ -87,7 +83,6 @@ def create_model_animation_gif(
87
  M = np.eye(4)
88
  scene.apply_transform(M)
89
 
90
- # β‘  trimesh β†’ β‘‘ pyrender 폴백
91
  try:
92
  frame = _render_with_trimesh(scene, resolution)
93
  except Exception as e:
@@ -103,12 +98,10 @@ def create_model_animation_gif(
103
  duration=int(1000 / fps),
104
  loop=0,
105
  )
106
- print("GIF saved:", output_path)
107
  return output_path
108
 
109
  # ──────────────────── 4. GLB λ³€ν˜• ────────────────────
110
  def modify_glb_file(input_glb_path, output_glb_path, animation_type="rotate"):
111
- """단일 λ³€ν™˜μ„ μ μš©ν•œ μƒˆ GLB μ €μž₯ (μ‹€μ œ μ• λ‹ˆλ©”μ΄μ…˜μ€ μ•„λ‹˜)"""
112
  try:
113
  scn = trimesh.load(input_glb_path)
114
  if not isinstance(scn, trimesh.Scene):
@@ -140,7 +133,6 @@ def modify_glb_file(input_glb_path, output_glb_path, animation_type="rotate"):
140
  # ──────────────────── 5. Gradio νŒŒμ΄ν”„λΌμΈ ────────────────────
141
  @spaces.GPU
142
  def process_3d_model(input_3d, animation_type, animation_duration, fps):
143
- """전체 νŒŒμ΄ν”„λΌμΈ: GLB λ³€ν˜• β†’ GIF λ Œλ” β†’ JSON μž‘μ„±"""
144
  try:
145
  base = os.path.splitext(os.path.basename(input_3d))[0]
146
  glb_out = os.path.join(LOG_PATH, f"animated_{base}.glb")
@@ -186,8 +178,20 @@ with gr.Blocks(title="GLB μ• λ‹ˆλ©”μ΄μ…˜ 생성기") as demo:
186
  choices=["rotate", "float", "explode", "assemble", "pulse", "swing"],
187
  value="rotate",
188
  )
189
- dur = gr.Slider("μ• λ‹ˆλ©”μ΄μ…˜ 길이 (초)", 1.0, 10.0, 3.0, 0.5)
190
- fps = gr.Slider("FPS", 15, 60, 30, 1)
 
 
 
 
 
 
 
 
 
 
 
 
191
  btn = gr.Button("μ• λ‹ˆλ©”μ΄μ…˜ 생성")
192
  with gr.Column():
193
  out_glb = gr.Model3D(label="μ• λ‹ˆλ©”μ΄μ…˜λœ GLB")
 
3
  ────────────────────────────────────────────────────────
4
  μ—…λ‘œλ“œν•œ GLB 3D λͺ¨λΈμ— νšŒμ „Β·λΆ€μœ Β·ν­λ°œ λ“± μ• λ‹ˆλ©”μ΄μ…˜μ„ μ μš©ν•΄
5
  β‘  λ³€ν˜•λœ GLB β‘‘ μ‹€μ œ λͺ¨λΈμ„ λ Œλ”λ§ν•œ GIF β‘’ 메타데이터 JSON 을 λŒλ €μ€λ‹ˆλ‹€.
 
 
6
  """
7
 
8
  # ──────────────────── 1. 곡톡 λͺ¨λ“ˆ ────────────────────
 
11
  from PIL import Image
12
 
13
  import pyglet
14
+ pyglet.options["headless"] = True
15
+ os.environ["PYOPENGL_PLATFORM"] = "egl"
16
 
17
  import trimesh
18
  import trimesh.transformations as tf
 
31
  return Image.open(io.BytesIO(png)).convert("RGB")
32
 
33
  def _render_with_pyrender(mesh_or_scene, res):
34
+ import pyrender
35
  if isinstance(mesh_or_scene, trimesh.Scene):
36
  mesh = trimesh.util.concatenate(mesh_or_scene.dump())
37
  else:
 
57
  fps: int = 30,
58
  resolution=(640, 480),
59
  ):
 
60
  base = trimesh.load(input_glb_path)
61
  if isinstance(base, trimesh.Trimesh):
62
  base = trimesh.Scene(base)
 
67
  t = i / (num_frames - 1)
68
  scene = base.copy()
69
 
 
70
  if animation_type == "rotate":
71
  M = tf.rotation_matrix(2 * math.pi * t, [0, 1, 0])
72
  elif animation_type == "float":
 
83
  M = np.eye(4)
84
  scene.apply_transform(M)
85
 
 
86
  try:
87
  frame = _render_with_trimesh(scene, resolution)
88
  except Exception as e:
 
98
  duration=int(1000 / fps),
99
  loop=0,
100
  )
 
101
  return output_path
102
 
103
  # ──────────────────── 4. GLB λ³€ν˜• ────────────────────
104
  def modify_glb_file(input_glb_path, output_glb_path, animation_type="rotate"):
 
105
  try:
106
  scn = trimesh.load(input_glb_path)
107
  if not isinstance(scn, trimesh.Scene):
 
133
  # ──────────────────── 5. Gradio νŒŒμ΄ν”„λΌμΈ ────────────────────
134
  @spaces.GPU
135
  def process_3d_model(input_3d, animation_type, animation_duration, fps):
 
136
  try:
137
  base = os.path.splitext(os.path.basename(input_3d))[0]
138
  glb_out = os.path.join(LOG_PATH, f"animated_{base}.glb")
 
178
  choices=["rotate", "float", "explode", "assemble", "pulse", "swing"],
179
  value="rotate",
180
  )
181
+ dur = gr.Slider(
182
+ label="μ• λ‹ˆλ©”μ΄μ…˜ 길이 (초)",
183
+ minimum=1.0,
184
+ maximum=10.0,
185
+ value=3.0,
186
+ step=0.5,
187
+ )
188
+ fps = gr.Slider(
189
+ label="FPS",
190
+ minimum=15,
191
+ maximum=60,
192
+ value=30,
193
+ step=1,
194
+ )
195
  btn = gr.Button("μ• λ‹ˆλ©”μ΄μ…˜ 생성")
196
  with gr.Column():
197
  out_glb = gr.Model3D(label="μ• λ‹ˆλ©”μ΄μ…˜λœ GLB")