frogleo commited on
Commit
6e8b9a9
·
1 Parent(s): 3c7b849

暂时完成业务逻辑

Browse files
Files changed (1) hide show
  1. app.py +102 -6
app.py CHANGED
@@ -8,6 +8,7 @@ from pathlib import Path
8
  import uuid
9
  import argparse
10
  import torch
 
11
 
12
 
13
  parser = argparse.ArgumentParser()
@@ -30,6 +31,11 @@ args.enable_flashvdm = True
30
  SAVE_DIR = args.cache_path
31
  os.makedirs(SAVE_DIR, exist_ok=True)
32
 
 
 
 
 
 
33
 
34
  def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
35
  if randomize_seed:
@@ -57,9 +63,53 @@ def gen_save_folder(max_size=200):
57
 
58
  return new_folder
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  from hy3dgen.shapegen import FaceReducer, FloaterRemover, DegenerateFaceRemover, MeshSimplifier, \
62
  Hunyuan3DDiTFlowMatchingPipeline
 
63
  from hy3dgen.rembg import BackgroundRemover
64
 
65
  rmbg_worker = BackgroundRemover()
@@ -75,6 +125,10 @@ if args.enable_flashvdm:
75
  if args.compile:
76
  i23d_worker.compile()
77
 
 
 
 
 
78
  progress=gr.Progress()
79
 
80
  @spaces.GPU(duration=60)
@@ -88,21 +142,24 @@ def gen_shape(
88
  target_face_num=10000,
89
  randomize_seed: bool = False,
90
  ):
91
-
 
92
  def callback(step_idx, timestep, outputs):
93
- progress_value = (step_idx+1.0)/steps
94
  progress(progress_value, desc=f"Mesh generating, {step_idx + 1}/{steps} steps")
95
 
96
 
97
  if image is None:
98
  raise gr.Error("Please provide either a caption or an image.")
99
 
 
100
  seed = int(randomize_seed_fn(seed, randomize_seed))
101
  octree_resolution = int(octree_resolution)
102
  save_folder = gen_save_folder()
103
-
104
  image = rmbg_worker(image.convert('RGB'))
105
 
 
106
  generator = torch.Generator()
107
  generator = generator.manual_seed(int(seed))
108
  outputs = i23d_worker(
@@ -113,9 +170,47 @@ def gen_shape(
113
  octree_resolution=octree_resolution,
114
  num_chunks=num_chunks,
115
  output_type='mesh',
116
- callback=callback
 
117
  )
118
- print(outputs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
 
121
 
@@ -167,6 +262,7 @@ with gr.Blocks().queue() as demo:
167
  with gr.Column(scale=6):
168
  gr.Markdown("#### Generated Mesh")
169
  html_export_mesh = gr.HTML(HTML_OUTPUT_PLACEHOLDER, label='Output')
 
170
 
171
  with gr.Column(scale=3):
172
  gr.Markdown("#### Image Examples")
@@ -176,7 +272,7 @@ with gr.Blocks().queue() as demo:
176
  gen_button.click(
177
  fn=gen_shape,
178
  inputs=[image,num_steps,cfg_scale,seed,octree_resolution,num_chunks,target_face_num, randomize_seed],
179
- outputs=[html_export_mesh]
180
  )
181
 
182
  demo.launch()
 
8
  import uuid
9
  import argparse
10
  import torch
11
+ import trimesh
12
 
13
 
14
  parser = argparse.ArgumentParser()
 
31
  SAVE_DIR = args.cache_path
32
  os.makedirs(SAVE_DIR, exist_ok=True)
33
 
34
+ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
35
+
36
+ HTML_HEIGHT = 690
37
+ HTML_WIDTH = 500
38
+
39
 
40
  def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
41
  if randomize_seed:
 
63
 
64
  return new_folder
65
 
66
+ def export_mesh(mesh, save_folder, textured=False, type='glb'):
67
+ if textured:
68
+ path = os.path.join(save_folder, f'textured_mesh.{type}')
69
+ else:
70
+ path = os.path.join(save_folder, f'white_mesh.{type}')
71
+ if type not in ['glb', 'obj']:
72
+ mesh.export(path)
73
+ else:
74
+ mesh.export(path, include_normals=textured)
75
+ return path
76
+
77
+ def build_model_viewer_html(save_folder, height=660, width=790, textured=False):
78
+ # Remove first folder from path to make relative path
79
+ if textured:
80
+ related_path = f"./textured_mesh.glb"
81
+ template_name = './assets/modelviewer-textured-template.html'
82
+ output_html_path = os.path.join(save_folder, f'textured_mesh.html')
83
+ else:
84
+ related_path = f"./white_mesh.glb"
85
+ template_name = './assets/modelviewer-template.html'
86
+ output_html_path = os.path.join(save_folder, f'white_mesh.html')
87
+
88
+ offset = 50 if textured else 10
89
+ with open(os.path.join(CURRENT_DIR, template_name), 'r', encoding='utf-8') as f:
90
+ template_html = f.read()
91
+
92
+ with open(output_html_path, 'w', encoding='utf-8') as f:
93
+ template_html = template_html.replace('#height#', f'{height - offset}')
94
+ template_html = template_html.replace('#width#', f'{width}')
95
+ template_html = template_html.replace('#src#', f'{related_path}/')
96
+ f.write(template_html)
97
+
98
+ rel_path = os.path.relpath(output_html_path, SAVE_DIR)
99
+ iframe_tag = f'<iframe src="/static/{rel_path}" height="{height}" width="100%" frameborder="0"></iframe>'
100
+ print(
101
+ f'Find html file {output_html_path}, {os.path.exists(output_html_path)}, relative HTML path is /static/{rel_path}')
102
+
103
+ return f"""
104
+ <div style='height: {height}; width: 100%;'>
105
+ {iframe_tag}
106
+ </div>
107
+ """
108
+
109
 
110
  from hy3dgen.shapegen import FaceReducer, FloaterRemover, DegenerateFaceRemover, MeshSimplifier, \
111
  Hunyuan3DDiTFlowMatchingPipeline
112
+ from hy3dgen.shapegen.pipelines import export_to_trimesh
113
  from hy3dgen.rembg import BackgroundRemover
114
 
115
  rmbg_worker = BackgroundRemover()
 
125
  if args.compile:
126
  i23d_worker.compile()
127
 
128
+ floater_remove_worker = FloaterRemover()
129
+ degenerate_face_remove_worker = DegenerateFaceRemover()
130
+ face_reduce_worker = FaceReducer()
131
+
132
  progress=gr.Progress()
133
 
134
  @spaces.GPU(duration=60)
 
142
  target_face_num=10000,
143
  randomize_seed: bool = False,
144
  ):
145
+ progress(0,desc="Starting")
146
+
147
  def callback(step_idx, timestep, outputs):
148
+ progress_value = ((step_idx+1.0)/steps)*(0.5/1.0)
149
  progress(progress_value, desc=f"Mesh generating, {step_idx + 1}/{steps} steps")
150
 
151
 
152
  if image is None:
153
  raise gr.Error("Please provide either a caption or an image.")
154
 
155
+
156
  seed = int(randomize_seed_fn(seed, randomize_seed))
157
  octree_resolution = int(octree_resolution)
158
  save_folder = gen_save_folder()
159
+ # 先移除背景
160
  image = rmbg_worker(image.convert('RGB'))
161
 
162
+ # 生成模型
163
  generator = torch.Generator()
164
  generator = generator.manual_seed(int(seed))
165
  outputs = i23d_worker(
 
170
  octree_resolution=octree_resolution,
171
  num_chunks=num_chunks,
172
  output_type='mesh',
173
+ callback=callback,
174
+ callback_steps=1
175
  )
176
+
177
+ mesh = export_to_trimesh(outputs)[0]
178
+
179
+ path = export_mesh(mesh, save_folder, textured=False)
180
+
181
+ model_viewer_html = build_model_viewer_html(save_folder, height=HTML_HEIGHT, width=HTML_WIDTH)
182
+
183
+ return model_viewer_html, path
184
+
185
+ # if args.low_vram_mode:
186
+ # torch.cuda.empty_cache()
187
+
188
+ # if path is None:
189
+ # raise gr.Error('Please generate a mesh first.')
190
+
191
+ # # 简化模型
192
+ # print(f'exporting {path}')
193
+ # print(f'reduce face to {target_face_num}')
194
+
195
+ # mesh = trimesh.load(path)
196
+ # progress(0.5,desc="Optimizing mesh")
197
+
198
+ # mesh = floater_remove_worker(mesh)
199
+ # mesh = degenerate_face_remove_worker(mesh)
200
+ # progress(0.6,desc="Reducing mesh faces")
201
+ # mesh = face_reduce_worker(mesh, target_face_num)
202
+ # save_folder = gen_save_folder()
203
+
204
+ # file_type = "obj"
205
+ # path = export_mesh(mesh, save_folder, textured=False, type=file_type)
206
+
207
+ # # for preview
208
+ # save_folder = gen_save_folder()
209
+ # _ = export_mesh(mesh, save_folder, textured=False)
210
+ # model_viewer_html = build_model_viewer_html(save_folder, height=HTML_HEIGHT, width=HTML_WIDTH, textured=False)
211
+
212
+ # progress(1,desc="Complete")
213
+ # return model_viewer_html, path
214
 
215
 
216
 
 
262
  with gr.Column(scale=6):
263
  gr.Markdown("#### Generated Mesh")
264
  html_export_mesh = gr.HTML(HTML_OUTPUT_PLACEHOLDER, label='Output')
265
+ path_output = gr.Textbox(label="Mesh Path")
266
 
267
  with gr.Column(scale=3):
268
  gr.Markdown("#### Image Examples")
 
272
  gen_button.click(
273
  fn=gen_shape,
274
  inputs=[image,num_steps,cfg_scale,seed,octree_resolution,num_chunks,target_face_num, randomize_seed],
275
+ outputs=[html_export_mesh, path_output]
276
  )
277
 
278
  demo.launch()