cortwave commited on
Commit
f5d0a33
Β·
1 Parent(s): b7b00e2

occluded-trellis

Browse files
Files changed (2) hide show
  1. app.py +81 -192
  2. requirements.txt +2 -1
app.py CHANGED
@@ -1,20 +1,19 @@
1
- import gradio as gr
2
- import spaces
3
- from gradio_litmodel3d import LitModel3D
4
-
5
  import os
6
  import shutil
7
- os.environ['SPCONV_ALGO'] = 'native'
8
  from typing import *
9
- import torch
10
- import numpy as np
11
  import imageio
12
- from easydict import EasyDict as edict
 
13
  from PIL import Image
 
 
14
  from trellis.pipelines import TrellisImageTo3DPipeline
15
  from trellis.representations import Gaussian, MeshExtractResult
16
  from trellis.utils import render_utils, postprocessing_utils
17
 
 
18
 
19
  MAX_SEED = np.iinfo(np.int32).max
20
  TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
@@ -24,42 +23,13 @@ os.makedirs(TMP_DIR, exist_ok=True)
24
  def start_session(req: gr.Request):
25
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
26
  os.makedirs(user_dir, exist_ok=True)
27
-
28
-
29
  def end_session(req: gr.Request):
30
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
31
  shutil.rmtree(user_dir)
32
 
33
 
34
- def preprocess_image(image: Image.Image) -> Image.Image:
35
- """
36
- Preprocess the input image.
37
-
38
- Args:
39
- image (Image.Image): The input image.
40
-
41
- Returns:
42
- Image.Image: The preprocessed image.
43
- """
44
- processed_image = pipeline.preprocess_image(image)
45
- return processed_image
46
-
47
-
48
- def preprocess_images(images: List[Tuple[Image.Image, str]]) -> List[Image.Image]:
49
- """
50
- Preprocess a list of input images.
51
-
52
- Args:
53
- images (List[Tuple[Image.Image, str]]): The input images.
54
-
55
- Returns:
56
- List[Image.Image]: The preprocessed images.
57
- """
58
- images = [image[0] for image in images]
59
- processed_images = [pipeline.preprocess_image(image) for image in images]
60
- return processed_images
61
-
62
-
63
  def pack_state(gs: Gaussian, mesh: MeshExtractResult) -> dict:
64
  return {
65
  'gaussian': {
@@ -75,8 +45,8 @@ def pack_state(gs: Gaussian, mesh: MeshExtractResult) -> dict:
75
  'faces': mesh.faces.cpu().numpy(),
76
  },
77
  }
78
-
79
-
80
  def unpack_state(state: dict) -> Tuple[Gaussian, edict, str]:
81
  gs = Gaussian(
82
  aabb=state['gaussian']['aabb'],
@@ -91,12 +61,12 @@ def unpack_state(state: dict) -> Tuple[Gaussian, edict, str]:
91
  gs._scaling = torch.tensor(state['gaussian']['_scaling'], device='cuda')
92
  gs._rotation = torch.tensor(state['gaussian']['_rotation'], device='cuda')
93
  gs._opacity = torch.tensor(state['gaussian']['_opacity'], device='cuda')
94
-
95
  mesh = edict(
96
  vertices=torch.tensor(state['mesh']['vertices'], device='cuda'),
97
  faces=torch.tensor(state['mesh']['faces'], device='cuda'),
98
  )
99
-
100
  return gs, mesh
101
 
102
 
@@ -107,69 +77,52 @@ def get_seed(randomize_seed: bool, seed: int) -> int:
107
  return np.random.randint(0, MAX_SEED) if randomize_seed else seed
108
 
109
 
110
- @spaces.GPU
111
  def image_to_3d(
112
- image: Image.Image,
113
- multiimages: List[Tuple[Image.Image, str]],
114
- is_multiimage: bool,
115
- seed: int,
116
- ss_guidance_strength: float,
117
- ss_sampling_steps: int,
118
- slat_guidance_strength: float,
119
- slat_sampling_steps: int,
120
- multiimage_algo: Literal["multidiffusion", "stochastic"],
121
- req: gr.Request,
122
  ) -> Tuple[dict, str]:
123
  """
124
  Convert an image to a 3D model.
125
 
126
  Args:
127
  image (Image.Image): The input image.
128
- multiimages (List[Tuple[Image.Image, str]]): The input images in multi-image mode.
129
- is_multiimage (bool): Whether is in multi-image mode.
130
  seed (int): The random seed.
131
  ss_guidance_strength (float): The guidance strength for sparse structure generation.
132
  ss_sampling_steps (int): The number of sampling steps for sparse structure generation.
133
  slat_guidance_strength (float): The guidance strength for structured latent generation.
134
  slat_sampling_steps (int): The number of sampling steps for structured latent generation.
135
- multiimage_algo (Literal["multidiffusion", "stochastic"]): The algorithm for multi-image generation.
136
 
137
  Returns:
138
  dict: The information of the generated 3D model.
139
  str: The path to the video of the 3D model.
140
  """
141
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
142
- if not is_multiimage:
143
- outputs = pipeline.run(
144
- image,
145
- seed=seed,
146
- formats=["gaussian", "mesh"],
147
- preprocess_image=False,
148
- sparse_structure_sampler_params={
149
- "steps": ss_sampling_steps,
150
- "cfg_strength": ss_guidance_strength,
151
- },
152
- slat_sampler_params={
153
- "steps": slat_sampling_steps,
154
- "cfg_strength": slat_guidance_strength,
155
- },
156
- )
157
- else:
158
- outputs = pipeline.run_multi_image(
159
- [image[0] for image in multiimages],
160
- seed=seed,
161
- formats=["gaussian", "mesh"],
162
- preprocess_image=False,
163
- sparse_structure_sampler_params={
164
- "steps": ss_sampling_steps,
165
- "cfg_strength": ss_guidance_strength,
166
- },
167
- slat_sampler_params={
168
- "steps": slat_sampling_steps,
169
- "cfg_strength": slat_guidance_strength,
170
- },
171
- mode=multiimage_algo,
172
- )
173
  video = render_utils.render_video(outputs['gaussian'][0], num_frames=120)['color']
174
  video_geo = render_utils.render_video(outputs['mesh'][0], num_frames=120)['normal']
175
  video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
@@ -180,12 +133,11 @@ def image_to_3d(
180
  return state, video_path
181
 
182
 
183
- @spaces.GPU(duration=90)
184
  def extract_glb(
185
- state: dict,
186
- mesh_simplify: float,
187
- texture_size: int,
188
- req: gr.Request,
189
  ) -> Tuple[str, str]:
190
  """
191
  Extract a GLB file from the 3D model.
@@ -207,7 +159,6 @@ def extract_glb(
207
  return glb_path, glb_path
208
 
209
 
210
- @spaces.GPU
211
  def extract_gaussian(state: dict, req: gr.Request) -> Tuple[str, str]:
212
  """
213
  Extract a Gaussian file from the 3D model.
@@ -226,57 +177,39 @@ def extract_gaussian(state: dict, req: gr.Request) -> Tuple[str, str]:
226
  return gaussian_path, gaussian_path
227
 
228
 
229
- def prepare_multi_example() -> List[Image.Image]:
230
- multi_case = list(set([i.split('_')[0] for i in os.listdir("assets/example_multi_image")]))
231
- images = []
232
- for case in multi_case:
233
- _images = []
234
- for i in range(1, 4):
235
- img = Image.open(f'assets/example_multi_image/{case}_{i}.png')
236
- W, H = img.size
237
- img = img.resize((int(W / H * 512), 512))
238
- _images.append(np.array(img))
239
- images.append(Image.fromarray(np.concatenate(_images, axis=1)))
240
- return images
241
 
 
 
242
 
243
- def split_image(image: Image.Image) -> List[Image.Image]:
244
- """
245
- Split an image into multiple views.
246
- """
247
- image = np.array(image)
248
- alpha = image[..., 3]
249
- alpha = np.any(alpha>0, axis=0)
250
- start_pos = np.where(~alpha[:-1] & alpha[1:])[0].tolist()
251
- end_pos = np.where(alpha[:-1] & ~alpha[1:])[0].tolist()
252
- images = []
253
- for s, e in zip(start_pos, end_pos):
254
- images.append(Image.fromarray(image[:, s:e+1]))
255
- return [preprocess_image(image) for image in images]
256
 
257
 
258
  with gr.Blocks(delete_cache=(600, 600)) as demo:
259
  gr.Markdown("""
260
- ## Image to 3D Asset with [TRELLIS](https://trellis3d.github.io/)
261
- * Upload an image and click "Generate" to create a 3D asset. If the image has alpha channel, it be used as the mask. Otherwise, we use `rembg` to remove the background.
262
  * If you find the generated 3D asset satisfactory, click "Extract GLB" to extract the GLB file and download it.
263
-
264
- ✨New: 1) Experimental multi-image support. 2) Gaussian file extraction.
265
  """)
266
-
267
  with gr.Row():
268
  with gr.Column():
269
- with gr.Tabs() as input_tabs:
270
- with gr.Tab(label="Single Image", id=0) as single_image_input_tab:
271
- image_prompt = gr.Image(label="Image Prompt", format="png", image_mode="RGBA", type="pil", height=300)
272
- with gr.Tab(label="Multiple Images", id=1) as multiimage_input_tab:
273
- multiimage_prompt = gr.Gallery(label="Image Prompt", format="png", type="pil", height=300, columns=3)
274
- gr.Markdown("""
275
- Input different views of the object in separate images.
276
-
277
- *NOTE: this is an experimental algorithm without training a specialized model. It may not produce the best results for all images, especially those having different poses or inconsistent details.*
278
- """)
279
-
280
  with gr.Accordion(label="Generation Settings", open=False):
281
  seed = gr.Slider(0, MAX_SEED, label="Seed", value=0, step=1)
282
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
@@ -288,14 +221,13 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
288
  with gr.Row():
289
  slat_guidance_strength = gr.Slider(0.0, 10.0, label="Guidance Strength", value=3.0, step=0.1)
290
  slat_sampling_steps = gr.Slider(1, 50, label="Sampling Steps", value=12, step=1)
291
- multiimage_algo = gr.Radio(["stochastic", "multidiffusion"], label="Multi-image Algorithm", value="stochastic")
292
 
293
  generate_btn = gr.Button("Generate")
294
-
295
  with gr.Accordion(label="GLB Extraction Settings", open=False):
296
  mesh_simplify = gr.Slider(0.9, 0.98, label="Simplify", value=0.95, step=0.01)
297
  texture_size = gr.Slider(512, 2048, label="Texture Size", value=1024, step=512)
298
-
299
  with gr.Row():
300
  extract_glb_btn = gr.Button("Extract GLB", interactive=False)
301
  extract_gs_btn = gr.Button("Extract Gaussian", interactive=False)
@@ -306,68 +238,29 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
306
  with gr.Column():
307
  video_output = gr.Video(label="Generated 3D Asset", autoplay=True, loop=True, height=300)
308
  model_output = LitModel3D(label="Extracted GLB/Gaussian", exposure=10.0, height=300)
309
-
310
  with gr.Row():
311
  download_glb = gr.DownloadButton(label="Download GLB", interactive=False)
312
- download_gs = gr.DownloadButton(label="Download Gaussian", interactive=False)
313
-
314
- is_multiimage = gr.State(False)
315
- output_buf = gr.State()
316
 
317
- # Example images at the bottom of the page
318
- with gr.Row() as single_image_example:
319
- examples = gr.Examples(
320
- examples=[
321
- f'assets/example_image/{image}'
322
- for image in os.listdir("assets/example_image")
323
- ],
324
- inputs=[image_prompt],
325
- fn=preprocess_image,
326
- outputs=[image_prompt],
327
- run_on_click=True,
328
- examples_per_page=64,
329
- )
330
- with gr.Row(visible=False) as multiimage_example:
331
- examples_multi = gr.Examples(
332
- examples=prepare_multi_example(),
333
- inputs=[image_prompt],
334
- fn=split_image,
335
- outputs=[multiimage_prompt],
336
- run_on_click=True,
337
- examples_per_page=8,
338
- )
339
 
340
  # Handlers
341
  demo.load(start_session)
342
  demo.unload(end_session)
343
-
344
- single_image_input_tab.select(
345
- lambda: tuple([False, gr.Row.update(visible=True), gr.Row.update(visible=False)]),
346
- outputs=[is_multiimage, single_image_example, multiimage_example]
347
- )
348
- multiimage_input_tab.select(
349
- lambda: tuple([True, gr.Row.update(visible=False), gr.Row.update(visible=True)]),
350
- outputs=[is_multiimage, single_image_example, multiimage_example]
351
- )
352
-
353
- image_prompt.upload(
354
- preprocess_image,
355
- inputs=[image_prompt],
356
- outputs=[image_prompt],
357
- )
358
- multiimage_prompt.upload(
359
- preprocess_images,
360
- inputs=[multiimage_prompt],
361
- outputs=[multiimage_prompt],
362
- )
363
 
364
  generate_btn.click(
365
  get_seed,
366
  inputs=[randomize_seed, seed],
367
  outputs=[seed],
 
 
 
 
368
  ).then(
369
  image_to_3d,
370
- inputs=[image_prompt, multiimage_prompt, is_multiimage, seed, ss_guidance_strength, ss_sampling_steps, slat_guidance_strength, slat_sampling_steps, multiimage_algo],
 
371
  outputs=[output_buf, video_output],
372
  ).then(
373
  lambda: tuple([gr.Button(interactive=True), gr.Button(interactive=True)]),
@@ -387,7 +280,7 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
387
  lambda: gr.Button(interactive=True),
388
  outputs=[download_glb],
389
  )
390
-
391
  extract_gs_btn.click(
392
  extract_gaussian,
393
  inputs=[output_buf],
@@ -401,14 +294,10 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
401
  lambda: gr.Button(interactive=False),
402
  outputs=[download_glb],
403
  )
404
-
405
 
406
  # Launch the Gradio app
407
  if __name__ == "__main__":
408
  pipeline = TrellisImageTo3DPipeline.from_pretrained("JeffreyXiang/TRELLIS-image-large")
 
409
  pipeline.cuda()
410
- try:
411
- pipeline.preprocess_image(Image.fromarray(np.zeros((512, 512, 3), dtype=np.uint8))) # Preload rembg
412
- except:
413
- pass
414
  demo.launch()
 
 
 
 
 
1
  import os
2
  import shutil
 
3
  from typing import *
4
+
5
+ import gradio as gr
6
  import imageio
7
+ import numpy as np
8
+ import torch
9
  from PIL import Image
10
+ from easydict import EasyDict as edict
11
+ from gradio_litmodel3d import LitModel3D
12
  from trellis.pipelines import TrellisImageTo3DPipeline
13
  from trellis.representations import Gaussian, MeshExtractResult
14
  from trellis.utils import render_utils, postprocessing_utils
15
 
16
+ from occluded_trellis import apply_occluded_patch
17
 
18
  MAX_SEED = np.iinfo(np.int32).max
19
  TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
 
23
  def start_session(req: gr.Request):
24
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
25
  os.makedirs(user_dir, exist_ok=True)
26
+
27
+
28
  def end_session(req: gr.Request):
29
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
30
  shutil.rmtree(user_dir)
31
 
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  def pack_state(gs: Gaussian, mesh: MeshExtractResult) -> dict:
34
  return {
35
  'gaussian': {
 
45
  'faces': mesh.faces.cpu().numpy(),
46
  },
47
  }
48
+
49
+
50
  def unpack_state(state: dict) -> Tuple[Gaussian, edict, str]:
51
  gs = Gaussian(
52
  aabb=state['gaussian']['aabb'],
 
61
  gs._scaling = torch.tensor(state['gaussian']['_scaling'], device='cuda')
62
  gs._rotation = torch.tensor(state['gaussian']['_rotation'], device='cuda')
63
  gs._opacity = torch.tensor(state['gaussian']['_opacity'], device='cuda')
64
+
65
  mesh = edict(
66
  vertices=torch.tensor(state['mesh']['vertices'], device='cuda'),
67
  faces=torch.tensor(state['mesh']['faces'], device='cuda'),
68
  )
69
+
70
  return gs, mesh
71
 
72
 
 
77
  return np.random.randint(0, MAX_SEED) if randomize_seed else seed
78
 
79
 
 
80
  def image_to_3d(
81
+ image: Image.Image,
82
+ mask: Image.Image,
83
+ seed: int,
84
+ ss_guidance_strength: float,
85
+ ss_sampling_steps: int,
86
+ slat_guidance_strength: float,
87
+ slat_sampling_steps: int,
88
+ req: gr.Request,
 
 
89
  ) -> Tuple[dict, str]:
90
  """
91
  Convert an image to a 3D model.
92
 
93
  Args:
94
  image (Image.Image): The input image.
 
 
95
  seed (int): The random seed.
96
  ss_guidance_strength (float): The guidance strength for sparse structure generation.
97
  ss_sampling_steps (int): The number of sampling steps for sparse structure generation.
98
  slat_guidance_strength (float): The guidance strength for structured latent generation.
99
  slat_sampling_steps (int): The number of sampling steps for structured latent generation.
 
100
 
101
  Returns:
102
  dict: The information of the generated 3D model.
103
  str: The path to the video of the 3D model.
104
  """
105
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
106
+ # if image.mode == "RGBA":
107
+ # image_np = np.array(image)
108
+ # alpha = image_np[..., 3]
109
+ # if np.all(alpha == 255):
110
+ # image = image.convert("RGB")
111
+ outputs = pipeline.run(
112
+ image,
113
+ mask,
114
+ seed=seed,
115
+ formats=["gaussian", "mesh"],
116
+ preprocess_image=True,
117
+ sparse_structure_sampler_params={
118
+ "steps": ss_sampling_steps,
119
+ "cfg_strength": ss_guidance_strength,
120
+ },
121
+ slat_sampler_params={
122
+ "steps": slat_sampling_steps,
123
+ "cfg_strength": slat_guidance_strength,
124
+ },
125
+ )
 
 
 
 
 
 
 
 
 
 
 
126
  video = render_utils.render_video(outputs['gaussian'][0], num_frames=120)['color']
127
  video_geo = render_utils.render_video(outputs['mesh'][0], num_frames=120)['normal']
128
  video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
 
133
  return state, video_path
134
 
135
 
 
136
  def extract_glb(
137
+ state: dict,
138
+ mesh_simplify: float,
139
+ texture_size: int,
140
+ req: gr.Request,
141
  ) -> Tuple[str, str]:
142
  """
143
  Extract a GLB file from the 3D model.
 
159
  return glb_path, glb_path
160
 
161
 
 
162
  def extract_gaussian(state: dict, req: gr.Request) -> Tuple[str, str]:
163
  """
164
  Extract a Gaussian file from the 3D model.
 
177
  return gaussian_path, gaussian_path
178
 
179
 
180
+ def extract_mask(editor_content):
181
+ bg = editor_content.get("background", None)
182
+ layers = editor_content.get("layers", [])
 
 
 
 
 
 
 
 
 
183
 
184
+ if bg is None and not layers:
185
+ raise ValueError("No background or layers provided")
186
 
187
+ mask = layers[0]
188
+ mask = np.array(mask)
189
+ mask = np.where(mask[..., 3] != 0, 0, 255).astype(
190
+ np.uint8)
191
+ mask = np.stack([mask] * 3, -1)
192
+ mask = Image.fromarray(mask)
193
+ return [bg, mask]
 
 
 
 
 
 
194
 
195
 
196
  with gr.Blocks(delete_cache=(600, 600)) as demo:
197
  gr.Markdown("""
198
+ ## Image to 3D Asset with [TRELLIS](https://trellis3d.github.io/), [Occluded version](https://github.com/cortwave/OccludedTrellis)
199
+ * Upload an image, draw a mask and click "Generate" to create a 3D asset. If the image has alpha channel, it be used as the mask. Otherwise, we use `rembg` to remove the background.
200
  * If you find the generated 3D asset satisfactory, click "Extract GLB" to extract the GLB file and download it.
201
+ * If image is already corrupted even before masking it's highly recommended to upload with your own alpha mask (remove background)
 
202
  """)
203
+
204
  with gr.Row():
205
  with gr.Column():
206
+ im_ed = gr.ImageMask(label="Image Prompt",
207
+ format="png",
208
+ image_mode="RGBA",
209
+ type="pil",
210
+ sources=["upload", "clipboard"])
211
+ image_prompt = gr.Image(visible=False, type="pil", image_mode="RGBA", format="png")
212
+ mask = gr.Image(visible=False, type="pil")
 
 
 
 
213
  with gr.Accordion(label="Generation Settings", open=False):
214
  seed = gr.Slider(0, MAX_SEED, label="Seed", value=0, step=1)
215
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
 
221
  with gr.Row():
222
  slat_guidance_strength = gr.Slider(0.0, 10.0, label="Guidance Strength", value=3.0, step=0.1)
223
  slat_sampling_steps = gr.Slider(1, 50, label="Sampling Steps", value=12, step=1)
 
224
 
225
  generate_btn = gr.Button("Generate")
226
+
227
  with gr.Accordion(label="GLB Extraction Settings", open=False):
228
  mesh_simplify = gr.Slider(0.9, 0.98, label="Simplify", value=0.95, step=0.01)
229
  texture_size = gr.Slider(512, 2048, label="Texture Size", value=1024, step=512)
230
+
231
  with gr.Row():
232
  extract_glb_btn = gr.Button("Extract GLB", interactive=False)
233
  extract_gs_btn = gr.Button("Extract Gaussian", interactive=False)
 
238
  with gr.Column():
239
  video_output = gr.Video(label="Generated 3D Asset", autoplay=True, loop=True, height=300)
240
  model_output = LitModel3D(label="Extracted GLB/Gaussian", exposure=10.0, height=300)
241
+
242
  with gr.Row():
243
  download_glb = gr.DownloadButton(label="Download GLB", interactive=False)
244
+ download_gs = gr.DownloadButton(label="Download Gaussian", interactive=False)
 
 
 
245
 
246
+ output_buf = gr.State()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
  # Handlers
249
  demo.load(start_session)
250
  demo.unload(end_session)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  generate_btn.click(
253
  get_seed,
254
  inputs=[randomize_seed, seed],
255
  outputs=[seed],
256
+ ).then(
257
+ extract_mask,
258
+ inputs=im_ed,
259
+ outputs=[image_prompt, mask]
260
  ).then(
261
  image_to_3d,
262
+ inputs=[image_prompt, mask, seed, ss_guidance_strength, ss_sampling_steps,
263
+ slat_guidance_strength, slat_sampling_steps],
264
  outputs=[output_buf, video_output],
265
  ).then(
266
  lambda: tuple([gr.Button(interactive=True), gr.Button(interactive=True)]),
 
280
  lambda: gr.Button(interactive=True),
281
  outputs=[download_glb],
282
  )
283
+
284
  extract_gs_btn.click(
285
  extract_gaussian,
286
  inputs=[output_buf],
 
294
  lambda: gr.Button(interactive=False),
295
  outputs=[download_glb],
296
  )
 
297
 
298
  # Launch the Gradio app
299
  if __name__ == "__main__":
300
  pipeline = TrellisImageTo3DPipeline.from_pretrained("JeffreyXiang/TRELLIS-image-large")
301
+ pipeline = apply_occluded_patch(pipeline)
302
  pipeline.cuda()
 
 
 
 
303
  demo.launch()
requirements.txt CHANGED
@@ -23,4 +23,5 @@ transformers==4.46.3
23
  gradio_litmodel3d==0.0.1
24
  https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post2/flash_attn-2.7.0.post2+cu12torch2.4cxx11abiFALSE-cp310-cp310-linux_x86_64.whl
25
  https://huggingface.co/spaces/JeffreyXiang/TRELLIS/resolve/main/wheels/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl?download=true
26
- https://huggingface.co/spaces/JeffreyXiang/TRELLIS/resolve/main/wheels/nvdiffrast-0.3.3-cp310-cp310-linux_x86_64.whl?download=true
 
 
23
  gradio_litmodel3d==0.0.1
24
  https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post2/flash_attn-2.7.0.post2+cu12torch2.4cxx11abiFALSE-cp310-cp310-linux_x86_64.whl
25
  https://huggingface.co/spaces/JeffreyXiang/TRELLIS/resolve/main/wheels/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl?download=true
26
+ https://huggingface.co/spaces/JeffreyXiang/TRELLIS/resolve/main/wheels/nvdiffrast-0.3.3-cp310-cp310-linux_x86_64.whl?download=true
27
+ occluded-trellis=0.1.1