staswrs commited on
Commit
972e6a2
·
1 Parent(s): 6eac623

fix add normals 5

Browse files
Files changed (2) hide show
  1. app.py +21 -47
  2. app_backlog.py +195 -10
app.py CHANGED
@@ -22,12 +22,15 @@ import requests
22
  import traceback
23
  import trimesh
24
  import numpy as np
 
 
25
  from trimesh.exchange.gltf import export_glb
26
 
27
  from inference_triposg import run_triposg
28
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
29
  from briarmbg import BriaRMBG
30
 
 
31
 
32
  print("Trimesh version:", trimesh.__version__)
33
 
@@ -63,53 +66,12 @@ pipe = TripoSGPipeline.from_pretrained(triposg_path).to(device, dtype)
63
  rmbg_net = BriaRMBG.from_pretrained(rmbg_path).to(device)
64
  rmbg_net.eval()
65
 
66
- # Генерация .glb
67
- # def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
68
- # print("[API CALL] image_path received:", image_path)
69
- # print("[API CALL] File exists:", os.path.exists(image_path))
70
-
71
- # temp_id = str(uuid.uuid4())
72
- # output_path = f"/tmp/{temp_id}.glb"
73
- # print("[DEBUG] Generating mesh from:", image_path)
74
-
75
- # try:
76
- # mesh = run_triposg(
77
- # pipe=pipe,
78
- # image_input=image_path,
79
- # rmbg_net=rmbg_net,
80
- # seed=42,
81
- # num_inference_steps=int(num_steps),
82
- # guidance_scale=float(guidance_scale),
83
- # faces=int(face_number),
84
- # )
85
-
86
- # if mesh is None or mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
87
- # raise ValueError("Mesh generation returned an empty mesh")
88
-
89
- # mesh = trimesh.Trimesh(vertices=mesh.vertices, faces=mesh.faces)
90
- # mesh.rezero()
91
- # mesh.fix_normals()
92
- # mesh.apply_translation(-mesh.center_mass)
93
-
94
- # # Масштабируем, чтобы модель вписывалась в размер 1x1x1
95
- # # Если нужно будет подгонять под размер в Endless Tools, то можно использовать:
96
- # # scale_factor = 1.0 / np.max(np.linalg.norm(mesh.vertices, axis=1))
97
- # # mesh.apply_scale(scale_factor)
98
-
99
-
100
- # glb_data = mesh.export(file_type='glb')
101
- # with open(output_path, "wb") as f:
102
- # f.write(glb_data)
103
-
104
- # print(f"[DEBUG] Mesh saved to {output_path}")
105
- # return output_path if os.path.exists(output_path) else None
106
-
107
- # except Exception as e:
108
- # print("[ERROR]", e)
109
- # traceback.print_exc()
110
- # return f"Error: {e}"
111
 
112
  def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
 
 
 
 
113
  print("[API CALL] image_path received:", image_path)
114
  print("[API CALL] File exists:", os.path.exists(image_path))
115
 
@@ -150,7 +112,6 @@ def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
150
  else:
151
  print("[DEBUG] Normals missing.")
152
 
153
-
154
  # 💾 Сохраняем GLB
155
  glb_data = mesh.export(file_type='glb')
156
  with open(output_path, "wb") as f:
@@ -166,9 +127,22 @@ def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
166
 
167
 
168
  # Интерфейс Gradio
 
 
 
 
 
 
 
 
169
  demo = gr.Interface(
170
  fn=generate,
171
- inputs=gr.Image(type="filepath", label="Upload image"),
 
 
 
 
 
172
  outputs=gr.File(label="Download .glb"),
173
  title="TripoSG Image to 3D",
174
  description="Upload an image to generate a 3D model (.glb)",
 
22
  import traceback
23
  import trimesh
24
  import numpy as np
25
+
26
+
27
  from trimesh.exchange.gltf import export_glb
28
 
29
  from inference_triposg import run_triposg
30
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
31
  from briarmbg import BriaRMBG
32
 
33
+ GLTF_PACK = "/tmp/gltfpack"
34
 
35
  print("Trimesh version:", trimesh.__version__)
36
 
 
66
  rmbg_net = BriaRMBG.from_pretrained(rmbg_path).to(device)
67
  rmbg_net.eval()
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
71
+ print("[API CALL] image_path =", image_path)
72
+ print("[API CALL] type =", type(image_path))
73
+ print("[API CALL] face_number =", face_number)
74
+
75
  print("[API CALL] image_path received:", image_path)
76
  print("[API CALL] File exists:", os.path.exists(image_path))
77
 
 
112
  else:
113
  print("[DEBUG] Normals missing.")
114
 
 
115
  # 💾 Сохраняем GLB
116
  glb_data = mesh.export(file_type='glb')
117
  with open(output_path, "wb") as f:
 
127
 
128
 
129
  # Интерфейс Gradio
130
+ # demo = gr.Interface(
131
+ # fn=generate,
132
+ # inputs=gr.Image(type="filepath", label="Upload image"),
133
+ # outputs=gr.File(label="Download .glb"),
134
+ # title="TripoSG Image to 3D",
135
+ # description="Upload an image to generate a 3D model (.glb)",
136
+ # )
137
+
138
  demo = gr.Interface(
139
  fn=generate,
140
+ inputs=[
141
+ gr.Image(type="filepath", label="Upload image"),
142
+ gr.Number(label="Face Number"),
143
+ gr.Number(label="Guidance Scale"),
144
+ gr.Number(label="Num Steps"),
145
+ ],
146
  outputs=gr.File(label="Download .glb"),
147
  title="TripoSG Image to 3D",
148
  description="Upload an image to generate a 3D model (.glb)",
app_backlog.py CHANGED
@@ -173,6 +173,135 @@
173
 
174
 
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  import os
177
  import subprocess
178
 
@@ -194,6 +323,7 @@ import zipfile
194
  import requests
195
  import traceback
196
  import trimesh
 
197
  from trimesh.exchange.gltf import export_glb
198
 
199
  from inference_triposg import run_triposg
@@ -236,6 +366,51 @@ rmbg_net = BriaRMBG.from_pretrained(rmbg_path).to(device)
236
  rmbg_net.eval()
237
 
238
  # Генерация .glb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
240
  print("[API CALL] image_path received:", image_path)
241
  print("[API CALL] File exists:", os.path.exists(image_path))
@@ -258,18 +433,27 @@ def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
258
  if mesh is None or mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
259
  raise ValueError("Mesh generation returned an empty mesh")
260
 
261
- # Безопасная очистка визуала
262
- if hasattr(mesh, "visual") and mesh.visual is not None:
263
- try:
264
- mesh.visual = None
265
- except Exception:
266
- print("[WARN] Failed to clear visual, skipping")
267
 
268
- mesh.metadata.clear()
269
- mesh.name = "endless_tools_mesh"
 
270
 
271
- # Экспорт .glb
272
- # glb_data = export_glb(mesh)
 
 
 
 
 
 
 
 
 
273
  glb_data = mesh.export(file_type='glb')
274
  with open(output_path, "wb") as f:
275
  f.write(glb_data)
@@ -282,6 +466,7 @@ def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
282
  traceback.print_exc()
283
  return f"Error: {e}"
284
 
 
285
  # Интерфейс Gradio
286
  demo = gr.Interface(
287
  fn=generate,
 
173
 
174
 
175
 
176
+ # import os
177
+ # import subprocess
178
+
179
+ # # Убираем pyenv
180
+ # os.environ.pop("PYENV_VERSION", None)
181
+
182
+ # # Установка зависимостей
183
+ # subprocess.run(["pip", "install", "torch", "wheel"], check=True)
184
+ # subprocess.run([
185
+ # "pip", "install", "--no-build-isolation",
186
+ # "diso@git+https://github.com/SarahWeiii/diso.git"
187
+ # ], check=True)
188
+
189
+ # # Импорты (перенесены после установки зависимостей)
190
+ # import gradio as gr
191
+ # import uuid
192
+ # import torch
193
+ # import zipfile
194
+ # import requests
195
+ # import traceback
196
+ # import trimesh
197
+ # from trimesh.exchange.gltf import export_glb
198
+
199
+ # from inference_triposg import run_triposg
200
+ # from triposg.pipelines.pipeline_triposg import TripoSGPipeline
201
+ # from briarmbg import BriaRMBG
202
+
203
+
204
+ # print("Trimesh version:", trimesh.__version__)
205
+
206
+ # # Настройки устройства
207
+ # device = "cuda" if torch.cuda.is_available() else "cpu"
208
+ # dtype = torch.float16 if device == "cuda" else torch.float32
209
+
210
+ # # Загрузка весов
211
+ # weights_dir = "pretrained_weights"
212
+ # triposg_path = os.path.join(weights_dir, "TripoSG")
213
+ # rmbg_path = os.path.join(weights_dir, "RMBG-1.4")
214
+
215
+ # if not (os.path.exists(triposg_path) and os.path.exists(rmbg_path)):
216
+ # print("📦 Downloading pretrained weights...")
217
+ # url = "https://huggingface.co/datasets/endlesstools/pretrained-assets/resolve/main/pretrained_models.zip"
218
+ # zip_path = "pretrained_models.zip"
219
+
220
+ # with requests.get(url, stream=True) as r:
221
+ # r.raise_for_status()
222
+ # with open(zip_path, "wb") as f:
223
+ # for chunk in r.iter_content(chunk_size=8192):
224
+ # f.write(chunk)
225
+
226
+ # print("📦 Extracting weights...")
227
+ # with zipfile.ZipFile(zip_path, "r") as zip_ref:
228
+ # zip_ref.extractall(weights_dir)
229
+
230
+ # os.remove(zip_path)
231
+ # print("✅ Weights ready.")
232
+
233
+ # # Загрузка моделей
234
+ # pipe = TripoSGPipeline.from_pretrained(triposg_path).to(device, dtype)
235
+ # rmbg_net = BriaRMBG.from_pretrained(rmbg_path).to(device)
236
+ # rmbg_net.eval()
237
+
238
+ # # Генерация .glb
239
+ # def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
240
+ # print("[API CALL] image_path received:", image_path)
241
+ # print("[API CALL] File exists:", os.path.exists(image_path))
242
+
243
+ # temp_id = str(uuid.uuid4())
244
+ # output_path = f"/tmp/{temp_id}.glb"
245
+ # print("[DEBUG] Generating mesh from:", image_path)
246
+
247
+ # try:
248
+ # mesh = run_triposg(
249
+ # pipe=pipe,
250
+ # image_input=image_path,
251
+ # rmbg_net=rmbg_net,
252
+ # seed=42,
253
+ # num_inference_steps=int(num_steps),
254
+ # guidance_scale=float(guidance_scale),
255
+ # faces=int(face_number),
256
+ # )
257
+
258
+ # if mesh is None or mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
259
+ # raise ValueError("Mesh generation returned an empty mesh")
260
+
261
+ # # Безопасная очистка визуала
262
+ # if hasattr(mesh, "visual") and mesh.visual is not None:
263
+ # try:
264
+ # mesh.visual = None
265
+ # except Exception:
266
+ # print("[WARN] Failed to clear visual, skipping")
267
+
268
+ # mesh.metadata.clear()
269
+ # mesh.name = "endless_tools_mesh"
270
+
271
+ # # Экспорт .glb
272
+ # # glb_data = export_glb(mesh)
273
+ # glb_data = mesh.export(file_type='glb')
274
+ # with open(output_path, "wb") as f:
275
+ # f.write(glb_data)
276
+
277
+ # print(f"[DEBUG] Mesh saved to {output_path}")
278
+ # return output_path if os.path.exists(output_path) else None
279
+
280
+ # except Exception as e:
281
+ # print("[ERROR]", e)
282
+ # traceback.print_exc()
283
+ # return f"Error: {e}"
284
+
285
+ # # Интерфейс Gradio
286
+ # demo = gr.Interface(
287
+ # fn=generate,
288
+ # inputs=gr.Image(type="filepath", label="Upload image"),
289
+ # outputs=gr.File(label="Download .glb"),
290
+ # title="TripoSG Image to 3D",
291
+ # description="Upload an image to generate a 3D model (.glb)",
292
+ # )
293
+
294
+ # # Запуск
295
+ # demo.launch()
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
  import os
306
  import subprocess
307
 
 
323
  import requests
324
  import traceback
325
  import trimesh
326
+ import numpy as np
327
  from trimesh.exchange.gltf import export_glb
328
 
329
  from inference_triposg import run_triposg
 
366
  rmbg_net.eval()
367
 
368
  # Генерация .glb
369
+ # def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
370
+ # print("[API CALL] image_path received:", image_path)
371
+ # print("[API CALL] File exists:", os.path.exists(image_path))
372
+
373
+ # temp_id = str(uuid.uuid4())
374
+ # output_path = f"/tmp/{temp_id}.glb"
375
+ # print("[DEBUG] Generating mesh from:", image_path)
376
+
377
+ # try:
378
+ # mesh = run_triposg(
379
+ # pipe=pipe,
380
+ # image_input=image_path,
381
+ # rmbg_net=rmbg_net,
382
+ # seed=42,
383
+ # num_inference_steps=int(num_steps),
384
+ # guidance_scale=float(guidance_scale),
385
+ # faces=int(face_number),
386
+ # )
387
+
388
+ # if mesh is None or mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
389
+ # raise ValueError("Mesh generation returned an empty mesh")
390
+
391
+ # mesh = trimesh.Trimesh(vertices=mesh.vertices, faces=mesh.faces)
392
+ # mesh.rezero()
393
+ # mesh.fix_normals()
394
+ # mesh.apply_translation(-mesh.center_mass)
395
+
396
+ # # Масштабируем, чтобы модель вписывалась в размер 1x1x1
397
+ # # Если нужно будет подгонять под размер в Endless Tools, то можно использовать:
398
+ # # scale_factor = 1.0 / np.max(np.linalg.norm(mesh.vertices, axis=1))
399
+ # # mesh.apply_scale(scale_factor)
400
+
401
+
402
+ # glb_data = mesh.export(file_type='glb')
403
+ # with open(output_path, "wb") as f:
404
+ # f.write(glb_data)
405
+
406
+ # print(f"[DEBUG] Mesh saved to {output_path}")
407
+ # return output_path if os.path.exists(output_path) else None
408
+
409
+ # except Exception as e:
410
+ # print("[ERROR]", e)
411
+ # traceback.print_exc()
412
+ # return f"Error: {e}"
413
+
414
  def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25):
415
  print("[API CALL] image_path received:", image_path)
416
  print("[API CALL] File exists:", os.path.exists(image_path))
 
433
  if mesh is None or mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0:
434
  raise ValueError("Mesh generation returned an empty mesh")
435
 
436
+ # 🔧 Пересоздаём Trimesh и гарантируем чистоту геометрии
437
+ mesh = trimesh.Trimesh(vertices=mesh.vertices, faces=mesh.faces, process=True)
438
+
439
+ # Центрируем модель
440
+ mesh.apply_translation(-mesh.center_mass)
 
441
 
442
+ # ✅ Масштабируем к единичному размеру (все модели ~одинаковые)
443
+ scale_factor = 1.0 / np.max(np.linalg.norm(mesh.vertices, axis=1))
444
+ mesh.apply_scale(scale_factor)
445
 
446
+ # Гарантированно пересчитываем нормали
447
+ mesh.fix_normals()
448
+
449
+ # print("[DEBUG] Normals present:", mesh.has_vertex_normals)
450
+ if hasattr(mesh, "vertex_normals"):
451
+ print("[DEBUG] Normals shape:", mesh.vertex_normals.shape)
452
+ else:
453
+ print("[DEBUG] Normals missing.")
454
+
455
+
456
+ # 💾 Сохраняем GLB
457
  glb_data = mesh.export(file_type='glb')
458
  with open(output_path, "wb") as f:
459
  f.write(glb_data)
 
466
  traceback.print_exc()
467
  return f"Error: {e}"
468
 
469
+
470
  # Интерфейс Gradio
471
  demo = gr.Interface(
472
  fn=generate,