Spaces:
				
			
			
	
			
			
		Running
		
			on 
			
			Zero
	
	
	
			
			
	
	
	
	
		
		
		Running
		
			on 
			
			Zero
	Upload folder using huggingface_hub
Browse files- README.md +37 -11
- assets/qrcode/discord.png +0 -0
- assets/qrcode/wechat.png +0 -0
- assets/qrcode/x.png +0 -0
- assets/qrcode/xiaohongshu.png +0 -0
- gradio_app.py +4 -4
- hg_app.py +67 -56
- minimal_demo.py +11 -2
    	
        README.md
    CHANGED
    
    | @@ -10,20 +10,23 @@ pinned: false | |
| 10 | 
             
            short_description: Text-to-3D and Image-to-3D Generation
         | 
| 11 | 
             
            ---
         | 
| 12 |  | 
|  | |
| 13 | 
             
            [中文阅读](README_zh_cn.md)
         | 
|  | |
| 14 |  | 
| 15 | 
            -
            <p align="center">
         | 
| 16 | 
             
              <img src="./assets/images/teaser.jpg">
         | 
| 17 |  | 
| 18 |  | 
| 19 | 
             
            </p>
         | 
| 20 |  | 
| 21 | 
             
            <div align="center">
         | 
| 22 | 
            -
              <a href=https://3d.hunyuan.tencent.com target="_blank"><img src=https://img.shields.io/badge/ | 
| 23 | 
             
              <a href=https://huggingface.co/spaces/tencent/Hunyuan3D-2  target="_blank"><img src=https://img.shields.io/badge/%F0%9F%A4%97%20Demo-276cb4.svg height=22px></a>
         | 
| 24 | 
             
              <a href=https://huggingface.co/tencent/Hunyuan3D-2 target="_blank"><img src=https://img.shields.io/badge/%F0%9F%A4%97%20Models-d96902.svg height=22px></a>
         | 
| 25 | 
             
              <a href=https://3d-models.hunyuan.tencent.com/ target="_blank"><img src= https://img.shields.io/badge/Page-bb8a2e.svg?logo=github height=22px></a>
         | 
| 26 | 
            -
            <a href=https://discord.gg/GuaWYwzKbX target="_blank"><img src= https://img.shields.io/badge/ | 
|  | |
| 27 | 
             
            </div>
         | 
| 28 |  | 
| 29 |  | 
| @@ -33,14 +36,21 @@ short_description: Text-to-3D and Image-to-3D Generation | |
| 33 |  | 
| 34 | 
             
            [//]: # (  <a href="#"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/v/mulankit?logo=pypi"  height=22px></a>)
         | 
| 35 |  | 
| 36 | 
            -
             | 
|  | |
|  | |
| 37 | 
             
            <p align="center">
         | 
| 38 | 
             
            “ Living out everyone’s imagination on creating and manipulating 3D assets.”
         | 
| 39 | 
             
            </p>
         | 
| 40 |  | 
| 41 | 
             
            ## 🔥 News
         | 
| 42 |  | 
| 43 | 
            -
            - Jan 21, 2025: 💬  | 
|  | |
|  | |
|  | |
|  | |
|  | |
| 44 |  | 
| 45 | 
             
            ## **Abstract**
         | 
| 46 |  | 
| @@ -92,8 +102,8 @@ and the condition following ability. | |
| 92 |  | 
| 93 | 
             
            Generation results of Hunyuan3D 2.0:
         | 
| 94 | 
             
            <p align="left">
         | 
| 95 | 
            -
              <img src="assets/images/e2e-1.gif"  height= | 
| 96 | 
            -
              <img src="assets/images/e2e-2.gif"  height= | 
| 97 | 
             
            </p>
         | 
| 98 |  | 
| 99 | 
             
            ### Pretrained Models
         | 
| @@ -159,7 +169,6 @@ for handcrafted mesh**. | |
| 159 | 
             
            You could also host a [Gradio](https://www.gradio.app/) App in your own computer via:
         | 
| 160 |  | 
| 161 | 
             
            ```bash
         | 
| 162 | 
            -
            pip3 install gradio==3.39.0
         | 
| 163 | 
             
            python3 gradio_app.py
         | 
| 164 | 
             
            ```
         | 
| 165 |  | 
| @@ -169,12 +178,13 @@ Don't forget to visit [Hunyuan3D](https://3d.hunyuan.tencent.com) for quick use, | |
| 169 |  | 
| 170 | 
             
            - [x] Inference Code
         | 
| 171 | 
             
            - [x] Model Checkpoints
         | 
|  | |
| 172 | 
             
            - [ ] ComfyUI
         | 
| 173 | 
             
            - [ ] TensorRT Version
         | 
| 174 |  | 
| 175 | 
             
            ## 🔗 BibTeX
         | 
| 176 |  | 
| 177 | 
            -
            If you found this repository helpful, please cite our  | 
| 178 |  | 
| 179 | 
             
            ```bibtex
         | 
| 180 | 
             
            @misc{hunyuan3d22025tencent,
         | 
| @@ -182,13 +192,29 @@ If you found this repository helpful, please cite our report: | |
| 182 | 
             
                author={Tencent Hunyuan3D Team},
         | 
| 183 | 
             
                year={2025},
         | 
| 184 | 
             
            }
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 185 | 
             
            ```
         | 
| 186 |  | 
| 187 | 
             
            ## Acknowledgements
         | 
| 188 |  | 
| 189 | 
             
            We would like to thank the contributors to
         | 
| 190 | 
            -
            the [DINOv2](https://github.com/facebookresearch/dinov2), [Stable Diffusion](https://github.com/Stability-AI/stablediffusion), [FLUX](https://github.com/black-forest-labs/flux), [diffusers](https://github.com/huggingface/diffusers)
         | 
| 191 | 
            -
            and [ | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 192 |  | 
| 193 | 
             
            ## Star History
         | 
| 194 |  | 
|  | |
| 10 | 
             
            short_description: Text-to-3D and Image-to-3D Generation
         | 
| 11 | 
             
            ---
         | 
| 12 |  | 
| 13 | 
            +
             | 
| 14 | 
             
            [中文阅读](README_zh_cn.md)
         | 
| 15 | 
            +
            [日本語で読む](README_ja_jp.md)
         | 
| 16 |  | 
| 17 | 
            +
            <p align="center"> 
         | 
| 18 | 
             
              <img src="./assets/images/teaser.jpg">
         | 
| 19 |  | 
| 20 |  | 
| 21 | 
             
            </p>
         | 
| 22 |  | 
| 23 | 
             
            <div align="center">
         | 
| 24 | 
            +
              <a href=https://3d.hunyuan.tencent.com target="_blank"><img src=https://img.shields.io/badge/Official%20Site-black.svg?logo=homepage height=22px></a>
         | 
| 25 | 
             
              <a href=https://huggingface.co/spaces/tencent/Hunyuan3D-2  target="_blank"><img src=https://img.shields.io/badge/%F0%9F%A4%97%20Demo-276cb4.svg height=22px></a>
         | 
| 26 | 
             
              <a href=https://huggingface.co/tencent/Hunyuan3D-2 target="_blank"><img src=https://img.shields.io/badge/%F0%9F%A4%97%20Models-d96902.svg height=22px></a>
         | 
| 27 | 
             
              <a href=https://3d-models.hunyuan.tencent.com/ target="_blank"><img src= https://img.shields.io/badge/Page-bb8a2e.svg?logo=github height=22px></a>
         | 
| 28 | 
            +
              <a href=https://discord.gg/GuaWYwzKbX target="_blank"><img src= https://img.shields.io/badge/Discord-white.svg?logo=discord height=22px></a>
         | 
| 29 | 
            +
              <a href=https://github.com/Tencent/Hunyuan3D-2/blob/main/assets/report/Tencent_Hunyuan3D_2_0.pdf target="_blank"><img src=https://img.shields.io/badge/Report-b5212f.svg?logo=arxiv height=22px></a>
         | 
| 30 | 
             
            </div>
         | 
| 31 |  | 
| 32 |  | 
|  | |
| 36 |  | 
| 37 | 
             
            [//]: # (  <a href="#"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/v/mulankit?logo=pypi"  height=22px></a>)
         | 
| 38 |  | 
| 39 | 
            +
            > Join our **[Wechat](#find-us)** and **[Discord](#find-us)** group to discuss and find help from us.
         | 
| 40 | 
            +
             | 
| 41 | 
            +
             | 
| 42 | 
             
            <p align="center">
         | 
| 43 | 
             
            “ Living out everyone’s imagination on creating and manipulating 3D assets.”
         | 
| 44 | 
             
            </p>
         | 
| 45 |  | 
| 46 | 
             
            ## 🔥 News
         | 
| 47 |  | 
| 48 | 
            +
            - Jan 21, 2025: 💬 Enjoy exciting 3D generation on our website [Hunyuan3D Studio](https://3d.hunyuan.tencent.com)!
         | 
| 49 | 
            +
            - Jan 21, 2025: 💬 Release inference code and pretrained models
         | 
| 50 | 
            +
              of [Hunyuan3D 2.0](https://huggingface.co/tencent/Hunyuan3D-2).
         | 
| 51 | 
            +
            - Jan 21, 2025: 💬 Release Hunyuan3D 2.0. Please give it a try
         | 
| 52 | 
            +
              via [huggingface space](https://huggingface.co/spaces/tencent/Hunyuan3D-2)
         | 
| 53 | 
            +
              our [official site](https://3d.hunyuan.tencent.com)!
         | 
| 54 |  | 
| 55 | 
             
            ## **Abstract**
         | 
| 56 |  | 
|  | |
| 102 |  | 
| 103 | 
             
            Generation results of Hunyuan3D 2.0:
         | 
| 104 | 
             
            <p align="left">
         | 
| 105 | 
            +
              <img src="assets/images/e2e-1.gif"  height=250>
         | 
| 106 | 
            +
              <img src="assets/images/e2e-2.gif"  height=250>
         | 
| 107 | 
             
            </p>
         | 
| 108 |  | 
| 109 | 
             
            ### Pretrained Models
         | 
|  | |
| 169 | 
             
            You could also host a [Gradio](https://www.gradio.app/) App in your own computer via:
         | 
| 170 |  | 
| 171 | 
             
            ```bash
         | 
|  | |
| 172 | 
             
            python3 gradio_app.py
         | 
| 173 | 
             
            ```
         | 
| 174 |  | 
|  | |
| 178 |  | 
| 179 | 
             
            - [x] Inference Code
         | 
| 180 | 
             
            - [x] Model Checkpoints
         | 
| 181 | 
            +
            - [x] Technical Report
         | 
| 182 | 
             
            - [ ] ComfyUI
         | 
| 183 | 
             
            - [ ] TensorRT Version
         | 
| 184 |  | 
| 185 | 
             
            ## 🔗 BibTeX
         | 
| 186 |  | 
| 187 | 
            +
            If you found this repository helpful, please cite our reports:
         | 
| 188 |  | 
| 189 | 
             
            ```bibtex
         | 
| 190 | 
             
            @misc{hunyuan3d22025tencent,
         | 
|  | |
| 192 | 
             
                author={Tencent Hunyuan3D Team},
         | 
| 193 | 
             
                year={2025},
         | 
| 194 | 
             
            }
         | 
| 195 | 
            +
             | 
| 196 | 
            +
            @misc{yang2024tencent,
         | 
| 197 | 
            +
                title={Tencent Hunyuan3D-1.0: A Unified Framework for Text-to-3D and Image-to-3D Generation},
         | 
| 198 | 
            +
                year={2024},
         | 
| 199 | 
            +
                author={Tencent Hunyuan3D Team},
         | 
| 200 | 
            +
                eprint={2411.02293},
         | 
| 201 | 
            +
                archivePrefix={arXiv},
         | 
| 202 | 
            +
                primaryClass={cs.CV}
         | 
| 203 | 
            +
            }
         | 
| 204 | 
             
            ```
         | 
| 205 |  | 
| 206 | 
             
            ## Acknowledgements
         | 
| 207 |  | 
| 208 | 
             
            We would like to thank the contributors to
         | 
| 209 | 
            +
            the [DINOv2](https://github.com/facebookresearch/dinov2), [Stable Diffusion](https://github.com/Stability-AI/stablediffusion), [FLUX](https://github.com/black-forest-labs/flux), [diffusers](https://github.com/huggingface/diffusers), [HuggingFace](https://huggingface.co), [CraftsMan3D](https://github.com/wyysf-98/CraftsMan3D),
         | 
| 210 | 
            +
            and [Michelangelo](https://github.com/NeuralCarver/Michelangelo/tree/main) repositories, for their open research and
         | 
| 211 | 
            +
            exploration.
         | 
| 212 | 
            +
             | 
| 213 | 
            +
            ## Find Us
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            | Wechat Group | Xiaohongshu | X | Discord |
         | 
| 216 | 
            +
            |--------------|-------------|---|---------|
         | 
| 217 | 
            +
            |              |             |   |         |        
         | 
| 218 |  | 
| 219 | 
             
            ## Star History
         | 
| 220 |  | 
    	
        assets/qrcode/discord.png
    ADDED
    
    |   | 
    	
        assets/qrcode/wechat.png
    ADDED
    
    |   | 
    	
        assets/qrcode/x.png
    ADDED
    
    |   | 
    	
        assets/qrcode/xiaohongshu.png
    ADDED
    
    |   | 
    	
        gradio_app.py
    CHANGED
    
    | @@ -138,7 +138,7 @@ def _gen_shape( | |
| 138 | 
             
                time_meta['image_to_textured_3d'] = {'total': time.time() - start_time}
         | 
| 139 | 
             
                time_meta['total'] = time.time() - start_time_0
         | 
| 140 | 
             
                stats['time'] = time_meta
         | 
| 141 | 
            -
                return mesh, save_folder
         | 
| 142 |  | 
| 143 |  | 
| 144 | 
             
            def generation_all(
         | 
| @@ -150,7 +150,7 @@ def generation_all( | |
| 150 | 
             
                octree_resolution=256,
         | 
| 151 | 
             
                check_box_rembg=False
         | 
| 152 | 
             
            ):
         | 
| 153 | 
            -
                mesh, save_folder = _gen_shape(
         | 
| 154 | 
             
                    caption,
         | 
| 155 | 
             
                    image,
         | 
| 156 | 
             
                    steps=steps,
         | 
| @@ -183,7 +183,7 @@ def shape_generation( | |
| 183 | 
             
                octree_resolution=256,
         | 
| 184 | 
             
                check_box_rembg=False,
         | 
| 185 | 
             
            ):
         | 
| 186 | 
            -
                mesh, save_folder = _gen_shape(
         | 
| 187 | 
             
                    caption,
         | 
| 188 | 
             
                    image,
         | 
| 189 | 
             
                    steps=steps,
         | 
| @@ -366,7 +366,7 @@ if __name__ == '__main__': | |
| 366 | 
             
                if args.enable_t23d:
         | 
| 367 | 
             
                    from hy3dgen.text2image import HunyuanDiTPipeline
         | 
| 368 |  | 
| 369 | 
            -
                    t2i_worker = HunyuanDiTPipeline('Tencent-Hunyuan | 
| 370 | 
             
                    HAS_T2I = True
         | 
| 371 |  | 
| 372 | 
             
                from hy3dgen.shapegen import FaceReducer, FloaterRemover, DegenerateFaceRemover, \
         | 
|  | |
| 138 | 
             
                time_meta['image_to_textured_3d'] = {'total': time.time() - start_time}
         | 
| 139 | 
             
                time_meta['total'] = time.time() - start_time_0
         | 
| 140 | 
             
                stats['time'] = time_meta
         | 
| 141 | 
            +
                return mesh, image, save_folder
         | 
| 142 |  | 
| 143 |  | 
| 144 | 
             
            def generation_all(
         | 
|  | |
| 150 | 
             
                octree_resolution=256,
         | 
| 151 | 
             
                check_box_rembg=False
         | 
| 152 | 
             
            ):
         | 
| 153 | 
            +
                mesh, image, save_folder = _gen_shape(
         | 
| 154 | 
             
                    caption,
         | 
| 155 | 
             
                    image,
         | 
| 156 | 
             
                    steps=steps,
         | 
|  | |
| 183 | 
             
                octree_resolution=256,
         | 
| 184 | 
             
                check_box_rembg=False,
         | 
| 185 | 
             
            ):
         | 
| 186 | 
            +
                mesh, image, save_folder = _gen_shape(
         | 
| 187 | 
             
                    caption,
         | 
| 188 | 
             
                    image,
         | 
| 189 | 
             
                    steps=steps,
         | 
|  | |
| 366 | 
             
                if args.enable_t23d:
         | 
| 367 | 
             
                    from hy3dgen.text2image import HunyuanDiTPipeline
         | 
| 368 |  | 
| 369 | 
            +
                    t2i_worker = HunyuanDiTPipeline('Tencent-Hunyuan--HunyuanDiT-v1.1-Diffusers-Distilled')
         | 
| 370 | 
             
                    HAS_T2I = True
         | 
| 371 |  | 
| 372 | 
             
                from hy3dgen.shapegen import FaceReducer, FloaterRemover, DegenerateFaceRemover, \
         | 
    	
        hg_app.py
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 | 
             
            # pip install gradio==4.44.1
         | 
| 2 | 
            -
            if  | 
| 3 | 
             
                import os
         | 
| 4 | 
             
                import spaces
         | 
| 5 | 
             
                import subprocess
         | 
| @@ -9,8 +9,8 @@ if True: | |
| 9 | 
             
                print("cd /home/user/app/hy3dgen/texgen/differentiable_renderer/ && bash compile_mesh_painter.sh")
         | 
| 10 | 
             
                os.system("cd /home/user/app/hy3dgen/texgen/differentiable_renderer/ && bash compile_mesh_painter.sh")
         | 
| 11 | 
             
                print('install custom')
         | 
| 12 | 
            -
                subprocess.run(shlex.split("pip install custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl"), check=True)
         | 
| 13 | 
            -
             | 
| 14 | 
             
                IP = "0.0.0.0"
         | 
| 15 | 
             
                PORT = 7860
         | 
| 16 |  | 
| @@ -29,7 +29,9 @@ import shutil | |
| 29 | 
             
            import time
         | 
| 30 | 
             
            from glob import glob
         | 
| 31 | 
             
            from pathlib import Path
         | 
| 32 | 
            -
             | 
|  | |
|  | |
| 33 | 
             
            import gradio as gr
         | 
| 34 | 
             
            import torch
         | 
| 35 | 
             
            import uvicorn
         | 
| @@ -37,6 +39,14 @@ from fastapi import FastAPI | |
| 37 | 
             
            from fastapi.staticfiles import StaticFiles
         | 
| 38 |  | 
| 39 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 40 | 
             
            def get_example_img_list():
         | 
| 41 | 
             
                print('Loading example img list ...')
         | 
| 42 | 
             
                return sorted(glob('./assets/example_images/*.png'))
         | 
| @@ -50,19 +60,6 @@ def get_example_txt_list(): | |
| 50 | 
             
                return txt_list
         | 
| 51 |  | 
| 52 |  | 
| 53 | 
            -
            def gen_save_folder(max_size=60):
         | 
| 54 | 
            -
                os.makedirs(SAVE_DIR, exist_ok=True)
         | 
| 55 | 
            -
                exists = set(int(_) for _ in os.listdir(SAVE_DIR) if not _.startswith("."))
         | 
| 56 | 
            -
                cur_id = min(set(range(max_size)) - exists) if len(exists) < max_size else -1
         | 
| 57 | 
            -
                if os.path.exists(f"{SAVE_DIR}/{(cur_id + 1) % max_size}"):
         | 
| 58 | 
            -
                    shutil.rmtree(f"{SAVE_DIR}/{(cur_id + 1) % max_size}")
         | 
| 59 | 
            -
                    print(f"remove {SAVE_DIR}/{(cur_id + 1) % max_size} success !!!")
         | 
| 60 | 
            -
                save_folder = f"{SAVE_DIR}/{max(0, cur_id)}"
         | 
| 61 | 
            -
                os.makedirs(save_folder, exist_ok=True)
         | 
| 62 | 
            -
                print(f"mkdir {save_folder} suceess !!!")
         | 
| 63 | 
            -
                return save_folder
         | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
             
            def export_mesh(mesh, save_folder, textured=False):
         | 
| 67 | 
             
                if textured:
         | 
| 68 | 
             
                    path = os.path.join(save_folder, f'textured_mesh.glb')
         | 
| @@ -71,16 +68,15 @@ def export_mesh(mesh, save_folder, textured=False): | |
| 71 | 
             
                mesh.export(path, include_normals=textured)
         | 
| 72 | 
             
                return path
         | 
| 73 |  | 
| 74 | 
            -
             | 
| 75 | 
             
            def build_model_viewer_html(save_folder, height=660, width=790, textured=False):
         | 
| 76 | 
             
                if textured:
         | 
| 77 | 
             
                    related_path = f"./textured_mesh.glb"
         | 
| 78 | 
             
                    template_name = './assets/modelviewer-textured-template.html'
         | 
| 79 | 
            -
                    output_html_path = os.path.join(save_folder, f' | 
| 80 | 
             
                else:
         | 
| 81 | 
             
                    related_path = f"./white_mesh.glb"
         | 
| 82 | 
             
                    template_name = './assets/modelviewer-template.html'
         | 
| 83 | 
            -
                    output_html_path = os.path.join(save_folder, f' | 
| 84 |  | 
| 85 | 
             
                with open(os.path.join(CURRENT_DIR, template_name), 'r') as f:
         | 
| 86 | 
             
                    template_html = f.read()
         | 
| @@ -111,18 +107,20 @@ def build_model_viewer_html(save_folder, height=660, width=790, textured=False): | |
| 111 | 
             
                    </div>
         | 
| 112 | 
             
                """
         | 
| 113 |  | 
|  | |
| 114 | 
             
            @spaces.GPU(duration=100)
         | 
| 115 | 
             
            def _gen_shape(
         | 
| 116 | 
            -
                caption,
         | 
| 117 | 
            -
                image,
         | 
| 118 | 
            -
                steps | 
| 119 | 
            -
                guidance_scale | 
| 120 | 
            -
                seed | 
| 121 | 
            -
                octree_resolution | 
| 122 | 
            -
                check_box_rembg | 
|  | |
| 123 | 
             
            ):
         | 
| 124 | 
             
                if caption: print('prompt is', caption)
         | 
| 125 | 
            -
                save_folder =  | 
| 126 | 
             
                stats = {}
         | 
| 127 | 
             
                time_meta = {}
         | 
| 128 | 
             
                start_time_0 = time.time()
         | 
| @@ -137,7 +135,7 @@ def _gen_shape( | |
| 137 |  | 
| 138 | 
             
                image.save(os.path.join(save_folder, 'input.png'))
         | 
| 139 |  | 
| 140 | 
            -
                print(image.mode)
         | 
| 141 | 
             
                if check_box_rembg or image.mode == "RGB":
         | 
| 142 | 
             
                    start_time = time.time()
         | 
| 143 | 
             
                    image = rmbg_worker(image.convert('RGB'))
         | 
| @@ -168,17 +166,20 @@ def _gen_shape( | |
| 168 | 
             
                time_meta['image_to_textured_3d'] = {'total': time.time() - start_time}
         | 
| 169 | 
             
                time_meta['total'] = time.time() - start_time_0
         | 
| 170 | 
             
                stats['time'] = time_meta
         | 
|  | |
|  | |
| 171 | 
             
                return mesh, save_folder, image
         | 
| 172 |  | 
| 173 | 
             
            @spaces.GPU(duration=150)
         | 
| 174 | 
             
            def generation_all(
         | 
| 175 | 
            -
                caption,
         | 
| 176 | 
            -
                image,
         | 
| 177 | 
            -
                steps | 
| 178 | 
            -
                guidance_scale | 
| 179 | 
            -
                seed | 
| 180 | 
            -
                octree_resolution | 
| 181 | 
            -
                check_box_rembg | 
|  | |
| 182 | 
             
            ):
         | 
| 183 | 
             
                mesh, save_folder, image = _gen_shape(
         | 
| 184 | 
             
                    caption,
         | 
| @@ -187,7 +188,8 @@ def generation_all( | |
| 187 | 
             
                    guidance_scale=guidance_scale,
         | 
| 188 | 
             
                    seed=seed,
         | 
| 189 | 
             
                    octree_resolution=octree_resolution,
         | 
| 190 | 
            -
                    check_box_rembg=check_box_rembg
         | 
|  | |
| 191 | 
             
                )
         | 
| 192 | 
             
                path = export_mesh(mesh, save_folder, textured=False)
         | 
| 193 | 
             
                model_viewer_html = build_model_viewer_html(save_folder, height=596, width=700)
         | 
| @@ -196,22 +198,24 @@ def generation_all( | |
| 196 | 
             
                path_textured = export_mesh(textured_mesh, save_folder, textured=True)
         | 
| 197 | 
             
                model_viewer_html_textured = build_model_viewer_html(save_folder, height=596, width=700, textured=True)
         | 
| 198 |  | 
|  | |
| 199 | 
             
                return (
         | 
| 200 | 
            -
                     | 
| 201 | 
            -
                     | 
| 202 | 
             
                    model_viewer_html,
         | 
| 203 | 
             
                    model_viewer_html_textured,
         | 
| 204 | 
             
                )
         | 
| 205 |  | 
| 206 | 
             
            @spaces.GPU(duration=100)
         | 
| 207 | 
             
            def shape_generation(
         | 
| 208 | 
            -
                caption,
         | 
| 209 | 
            -
                image,
         | 
| 210 | 
            -
                steps | 
| 211 | 
            -
                guidance_scale | 
| 212 | 
            -
                seed | 
| 213 | 
            -
                octree_resolution | 
| 214 | 
            -
                check_box_rembg | 
|  | |
| 215 | 
             
            ):
         | 
| 216 | 
             
                mesh, save_folder, image = _gen_shape(
         | 
| 217 | 
             
                    caption,
         | 
| @@ -220,14 +224,15 @@ def shape_generation( | |
| 220 | 
             
                    guidance_scale=guidance_scale,
         | 
| 221 | 
             
                    seed=seed,
         | 
| 222 | 
             
                    octree_resolution=octree_resolution,
         | 
| 223 | 
            -
                    check_box_rembg=check_box_rembg
         | 
|  | |
| 224 | 
             
                )
         | 
| 225 |  | 
| 226 | 
             
                path = export_mesh(mesh, save_folder, textured=False)
         | 
| 227 | 
             
                model_viewer_html = build_model_viewer_html(save_folder, height=596, width=700)
         | 
| 228 |  | 
| 229 | 
             
                return (
         | 
| 230 | 
            -
                     | 
| 231 | 
             
                    model_viewer_html,
         | 
| 232 | 
             
                )
         | 
| 233 |  | 
| @@ -249,7 +254,7 @@ def build_app(): | |
| 249 | 
             
                </div>
         | 
| 250 | 
             
                """
         | 
| 251 |  | 
| 252 | 
            -
                with gr.Blocks(theme=gr.themes.Base(), title='Hunyuan-3D-2.0') as demo:
         | 
| 253 | 
             
                    gr.HTML(title_html)
         | 
| 254 |  | 
| 255 | 
             
                    with gr.Row():
         | 
| @@ -275,9 +280,13 @@ def build_app(): | |
| 275 | 
             
                                btn = gr.Button(value='Generate Shape Only', variant='primary')
         | 
| 276 | 
             
                                btn_all = gr.Button(value='Generate Shape and Texture', variant='primary', visible=HAS_TEXTUREGEN)
         | 
| 277 |  | 
|  | |
|  | |
|  | |
|  | |
| 278 | 
             
                            with gr.Group():
         | 
| 279 | 
            -
                                file_out = gr. | 
| 280 | 
            -
                                file_out2 = gr. | 
| 281 |  | 
| 282 | 
             
                        with gr.Column(scale=5):
         | 
| 283 | 
             
                            with gr.Tabs():
         | 
| @@ -331,7 +340,7 @@ def build_app(): | |
| 331 | 
             
                        ],
         | 
| 332 | 
             
                        outputs=[file_out, html_output1]
         | 
| 333 | 
             
                    ).then(
         | 
| 334 | 
            -
                        lambda: gr. | 
| 335 | 
             
                        outputs=[file_out],
         | 
| 336 | 
             
                    )
         | 
| 337 |  | 
| @@ -348,10 +357,13 @@ def build_app(): | |
| 348 | 
             
                        ],
         | 
| 349 | 
             
                        outputs=[file_out, file_out2, html_output1, html_output2]
         | 
| 350 | 
             
                    ).then(
         | 
| 351 | 
            -
                        lambda: (gr. | 
| 352 | 
             
                        outputs=[file_out, file_out2],
         | 
| 353 | 
             
                    )
         | 
| 354 |  | 
|  | |
|  | |
|  | |
| 355 | 
             
                return demo
         | 
| 356 |  | 
| 357 |  | 
| @@ -364,10 +376,9 @@ if __name__ == '__main__': | |
| 364 | 
             
                parser.add_argument('--enable_t23d', default=True)
         | 
| 365 | 
             
                args = parser.parse_args()
         | 
| 366 |  | 
| 367 | 
            -
                SAVE_DIR = args.cache_path
         | 
| 368 | 
            -
                os.makedirs(SAVE_DIR, exist_ok=True)
         | 
| 369 | 
            -
             | 
| 370 | 
             
                CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
         | 
|  | |
|  | |
| 371 |  | 
| 372 | 
             
                HTML_OUTPUT_PLACEHOLDER = """
         | 
| 373 | 
             
                <div style='height: 596px; width: 100%; border-radius: 8px; border-color: #e5e7eb; order-style: solid; border-width: 1px;'></div>
         | 
|  | |
| 1 | 
             
            # pip install gradio==4.44.1
         | 
| 2 | 
            +
            if False:
         | 
| 3 | 
             
                import os
         | 
| 4 | 
             
                import spaces
         | 
| 5 | 
             
                import subprocess
         | 
|  | |
| 9 | 
             
                print("cd /home/user/app/hy3dgen/texgen/differentiable_renderer/ && bash compile_mesh_painter.sh")
         | 
| 10 | 
             
                os.system("cd /home/user/app/hy3dgen/texgen/differentiable_renderer/ && bash compile_mesh_painter.sh")
         | 
| 11 | 
             
                print('install custom')
         | 
| 12 | 
            +
                subprocess.run(shlex.split("pip install custom_rasterizer-0.1-cp310-cp310-linux_x86_64.whl"), check=True)    
         | 
| 13 | 
            +
                
         | 
| 14 | 
             
                IP = "0.0.0.0"
         | 
| 15 | 
             
                PORT = 7860
         | 
| 16 |  | 
|  | |
| 29 | 
             
            import time
         | 
| 30 | 
             
            from glob import glob
         | 
| 31 | 
             
            from pathlib import Path
         | 
| 32 | 
            +
            from PIL import Image
         | 
| 33 | 
            +
            from datetime import datetime
         | 
| 34 | 
            +
            import uuid
         | 
| 35 | 
             
            import gradio as gr
         | 
| 36 | 
             
            import torch
         | 
| 37 | 
             
            import uvicorn
         | 
|  | |
| 39 | 
             
            from fastapi.staticfiles import StaticFiles
         | 
| 40 |  | 
| 41 |  | 
| 42 | 
            +
            def start_session(req: gr.Request):
         | 
| 43 | 
            +
                save_folder = os.path.join(SAVE_DIR, str(req.session_hash))
         | 
| 44 | 
            +
                os.makedirs(save_folder, exist_ok=True)
         | 
| 45 | 
            +
                    
         | 
| 46 | 
            +
            def end_session(req: gr.Request):
         | 
| 47 | 
            +
                save_folder = os.path.join(SAVE_DIR, str(req.session_hash))
         | 
| 48 | 
            +
                shutil.rmtree(save_folder)
         | 
| 49 | 
            +
             | 
| 50 | 
             
            def get_example_img_list():
         | 
| 51 | 
             
                print('Loading example img list ...')
         | 
| 52 | 
             
                return sorted(glob('./assets/example_images/*.png'))
         | 
|  | |
| 60 | 
             
                return txt_list
         | 
| 61 |  | 
| 62 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 63 | 
             
            def export_mesh(mesh, save_folder, textured=False):
         | 
| 64 | 
             
                if textured:
         | 
| 65 | 
             
                    path = os.path.join(save_folder, f'textured_mesh.glb')
         | 
|  | |
| 68 | 
             
                mesh.export(path, include_normals=textured)
         | 
| 69 | 
             
                return path
         | 
| 70 |  | 
|  | |
| 71 | 
             
            def build_model_viewer_html(save_folder, height=660, width=790, textured=False):
         | 
| 72 | 
             
                if textured:
         | 
| 73 | 
             
                    related_path = f"./textured_mesh.glb"
         | 
| 74 | 
             
                    template_name = './assets/modelviewer-textured-template.html'
         | 
| 75 | 
            +
                    output_html_path = os.path.join(save_folder, f'{uuid.uuid4()}_textured_mesh.html')
         | 
| 76 | 
             
                else:
         | 
| 77 | 
             
                    related_path = f"./white_mesh.glb"
         | 
| 78 | 
             
                    template_name = './assets/modelviewer-template.html'
         | 
| 79 | 
            +
                    output_html_path = os.path.join(save_folder, f'{uuid.uuid4()}_white_mesh.html')
         | 
| 80 |  | 
| 81 | 
             
                with open(os.path.join(CURRENT_DIR, template_name), 'r') as f:
         | 
| 82 | 
             
                    template_html = f.read()
         | 
|  | |
| 107 | 
             
                    </div>
         | 
| 108 | 
             
                """
         | 
| 109 |  | 
| 110 | 
            +
             | 
| 111 | 
             
            @spaces.GPU(duration=100)
         | 
| 112 | 
             
            def _gen_shape(
         | 
| 113 | 
            +
                caption: str,
         | 
| 114 | 
            +
                image: Image.Image,
         | 
| 115 | 
            +
                steps: int,
         | 
| 116 | 
            +
                guidance_scale: float,
         | 
| 117 | 
            +
                seed: int,
         | 
| 118 | 
            +
                octree_resolution: int,
         | 
| 119 | 
            +
                check_box_rembg: bool,
         | 
| 120 | 
            +
                req: gr.Request,
         | 
| 121 | 
             
            ):
         | 
| 122 | 
             
                if caption: print('prompt is', caption)
         | 
| 123 | 
            +
                save_folder = os.path.join(SAVE_DIR, str(req.session_hash))
         | 
| 124 | 
             
                stats = {}
         | 
| 125 | 
             
                time_meta = {}
         | 
| 126 | 
             
                start_time_0 = time.time()
         | 
|  | |
| 135 |  | 
| 136 | 
             
                image.save(os.path.join(save_folder, 'input.png'))
         | 
| 137 |  | 
| 138 | 
            +
                print(f"[{datetime.now()}][HunYuan3D-2]]", str(req.session_hash), image.mode)
         | 
| 139 | 
             
                if check_box_rembg or image.mode == "RGB":
         | 
| 140 | 
             
                    start_time = time.time()
         | 
| 141 | 
             
                    image = rmbg_worker(image.convert('RGB'))
         | 
|  | |
| 166 | 
             
                time_meta['image_to_textured_3d'] = {'total': time.time() - start_time}
         | 
| 167 | 
             
                time_meta['total'] = time.time() - start_time_0
         | 
| 168 | 
             
                stats['time'] = time_meta
         | 
| 169 | 
            +
                
         | 
| 170 | 
            +
                torch.cuda.empty_cache()
         | 
| 171 | 
             
                return mesh, save_folder, image
         | 
| 172 |  | 
| 173 | 
             
            @spaces.GPU(duration=150)
         | 
| 174 | 
             
            def generation_all(
         | 
| 175 | 
            +
                caption: str,
         | 
| 176 | 
            +
                image: Image.Image,
         | 
| 177 | 
            +
                steps: int,
         | 
| 178 | 
            +
                guidance_scale: float,
         | 
| 179 | 
            +
                seed: int,
         | 
| 180 | 
            +
                octree_resolution: int,
         | 
| 181 | 
            +
                check_box_rembg: bool,
         | 
| 182 | 
            +
                req: gr.Request,
         | 
| 183 | 
             
            ):
         | 
| 184 | 
             
                mesh, save_folder, image = _gen_shape(
         | 
| 185 | 
             
                    caption,
         | 
|  | |
| 188 | 
             
                    guidance_scale=guidance_scale,
         | 
| 189 | 
             
                    seed=seed,
         | 
| 190 | 
             
                    octree_resolution=octree_resolution,
         | 
| 191 | 
            +
                    check_box_rembg=check_box_rembg,
         | 
| 192 | 
            +
                    req=req
         | 
| 193 | 
             
                )
         | 
| 194 | 
             
                path = export_mesh(mesh, save_folder, textured=False)
         | 
| 195 | 
             
                model_viewer_html = build_model_viewer_html(save_folder, height=596, width=700)
         | 
|  | |
| 198 | 
             
                path_textured = export_mesh(textured_mesh, save_folder, textured=True)
         | 
| 199 | 
             
                model_viewer_html_textured = build_model_viewer_html(save_folder, height=596, width=700, textured=True)
         | 
| 200 |  | 
| 201 | 
            +
                torch.cuda.empty_cache()
         | 
| 202 | 
             
                return (
         | 
| 203 | 
            +
                    path,
         | 
| 204 | 
            +
                    path_textured, 
         | 
| 205 | 
             
                    model_viewer_html,
         | 
| 206 | 
             
                    model_viewer_html_textured,
         | 
| 207 | 
             
                )
         | 
| 208 |  | 
| 209 | 
             
            @spaces.GPU(duration=100)
         | 
| 210 | 
             
            def shape_generation(
         | 
| 211 | 
            +
                caption: str,
         | 
| 212 | 
            +
                image: Image.Image,
         | 
| 213 | 
            +
                steps: int,
         | 
| 214 | 
            +
                guidance_scale: float,
         | 
| 215 | 
            +
                seed: int,
         | 
| 216 | 
            +
                octree_resolution: int,
         | 
| 217 | 
            +
                check_box_rembg: bool,
         | 
| 218 | 
            +
                req: gr.Request,
         | 
| 219 | 
             
            ):
         | 
| 220 | 
             
                mesh, save_folder, image = _gen_shape(
         | 
| 221 | 
             
                    caption,
         | 
|  | |
| 224 | 
             
                    guidance_scale=guidance_scale,
         | 
| 225 | 
             
                    seed=seed,
         | 
| 226 | 
             
                    octree_resolution=octree_resolution,
         | 
| 227 | 
            +
                    check_box_rembg=check_box_rembg,
         | 
| 228 | 
            +
                    req=req,
         | 
| 229 | 
             
                )
         | 
| 230 |  | 
| 231 | 
             
                path = export_mesh(mesh, save_folder, textured=False)
         | 
| 232 | 
             
                model_viewer_html = build_model_viewer_html(save_folder, height=596, width=700)
         | 
| 233 |  | 
| 234 | 
             
                return (
         | 
| 235 | 
            +
                    path,
         | 
| 236 | 
             
                    model_viewer_html,
         | 
| 237 | 
             
                )
         | 
| 238 |  | 
|  | |
| 254 | 
             
                </div>
         | 
| 255 | 
             
                """
         | 
| 256 |  | 
| 257 | 
            +
                with gr.Blocks(theme=gr.themes.Base(), title='Hunyuan-3D-2.0', delete_cache=(1000,1000)) as demo:
         | 
| 258 | 
             
                    gr.HTML(title_html)
         | 
| 259 |  | 
| 260 | 
             
                    with gr.Row():
         | 
|  | |
| 280 | 
             
                                btn = gr.Button(value='Generate Shape Only', variant='primary')
         | 
| 281 | 
             
                                btn_all = gr.Button(value='Generate Shape and Texture', variant='primary', visible=HAS_TEXTUREGEN)
         | 
| 282 |  | 
| 283 | 
            +
                            # with gr.Group():
         | 
| 284 | 
            +
                            #     file_out = gr.File(label="File", visible=False)
         | 
| 285 | 
            +
                            #     file_out2 = gr.File(label="File", visible=False)
         | 
| 286 | 
            +
             | 
| 287 | 
             
                            with gr.Group():
         | 
| 288 | 
            +
                                file_out = gr.DownloadButton(label="Download White Mesh", interactive=False)
         | 
| 289 | 
            +
                                file_out2 = gr.DownloadButton(label="Download Textured Mesh", interactive=False)  
         | 
| 290 |  | 
| 291 | 
             
                        with gr.Column(scale=5):
         | 
| 292 | 
             
                            with gr.Tabs():
         | 
|  | |
| 340 | 
             
                        ],
         | 
| 341 | 
             
                        outputs=[file_out, html_output1]
         | 
| 342 | 
             
                    ).then(
         | 
| 343 | 
            +
                        lambda: gr.Button(interactive=True),
         | 
| 344 | 
             
                        outputs=[file_out],
         | 
| 345 | 
             
                    )
         | 
| 346 |  | 
|  | |
| 357 | 
             
                        ],
         | 
| 358 | 
             
                        outputs=[file_out, file_out2, html_output1, html_output2]
         | 
| 359 | 
             
                    ).then(
         | 
| 360 | 
            +
                        lambda: (gr.Button(interactive=True),gr.Button(interactive=True)),
         | 
| 361 | 
             
                        outputs=[file_out, file_out2],
         | 
| 362 | 
             
                    )
         | 
| 363 |  | 
| 364 | 
            +
                    demo.load(start_session)
         | 
| 365 | 
            +
                    demo.unload(end_session)
         | 
| 366 | 
            +
             | 
| 367 | 
             
                return demo
         | 
| 368 |  | 
| 369 |  | 
|  | |
| 376 | 
             
                parser.add_argument('--enable_t23d', default=True)
         | 
| 377 | 
             
                args = parser.parse_args()
         | 
| 378 |  | 
|  | |
|  | |
|  | |
| 379 | 
             
                CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
         | 
| 380 | 
            +
                SAVE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), args.cache_path)
         | 
| 381 | 
            +
                os.makedirs(SAVE_DIR, exist_ok=True)
         | 
| 382 |  | 
| 383 | 
             
                HTML_OUTPUT_PLACEHOLDER = """
         | 
| 384 | 
             
                <div style='height: 596px; width: 100%; border-radius: 8px; border-color: #e5e7eb; order-style: solid; border-width: 1px;'></div>
         | 
    	
        minimal_demo.py
    CHANGED
    
    | @@ -23,6 +23,7 @@ | |
| 23 | 
             
            # by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
         | 
| 24 |  | 
| 25 | 
             
            import torch
         | 
|  | |
| 26 |  | 
| 27 | 
             
            from hy3dgen.rembg import BackgroundRemover
         | 
| 28 | 
             
            from hy3dgen.shapegen import Hunyuan3DDiTFlowMatchingPipeline, FaceReducer, FloaterRemover, DegenerateFaceRemover
         | 
| @@ -30,10 +31,18 @@ from hy3dgen.text2image import HunyuanDiTPipeline | |
| 30 |  | 
| 31 |  | 
| 32 | 
             
            def image_to_3d(image_path='assets/demo.png'):
         | 
|  | |
| 33 | 
             
                model_path = 'Hunyuan3D-2'
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 34 | 
             
                pipeline = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained(model_path)
         | 
| 35 |  | 
| 36 | 
            -
                mesh = pipeline(image= | 
| 37 | 
             
                                generator=torch.manual_seed(2025))[0]
         | 
| 38 | 
             
                mesh = FloaterRemover()(mesh)
         | 
| 39 | 
             
                mesh = DegenerateFaceRemover()(mesh)
         | 
| @@ -43,7 +52,7 @@ def image_to_3d(image_path='assets/demo.png'): | |
| 43 | 
             
                try:
         | 
| 44 | 
             
                    from hy3dgen.texgen import Hunyuan3DPaintPipeline
         | 
| 45 | 
             
                    pipeline = Hunyuan3DPaintPipeline.from_pretrained(model_path)
         | 
| 46 | 
            -
                    mesh = pipeline(mesh, image= | 
| 47 | 
             
                    mesh.export('texture.glb')
         | 
| 48 | 
             
                except Exception as e:
         | 
| 49 | 
             
                    print(e)
         | 
|  | |
| 23 | 
             
            # by Tencent in accordance with TENCENT HUNYUAN COMMUNITY LICENSE AGREEMENT.
         | 
| 24 |  | 
| 25 | 
             
            import torch
         | 
| 26 | 
            +
            from PIL imprt Image
         | 
| 27 |  | 
| 28 | 
             
            from hy3dgen.rembg import BackgroundRemover
         | 
| 29 | 
             
            from hy3dgen.shapegen import Hunyuan3DDiTFlowMatchingPipeline, FaceReducer, FloaterRemover, DegenerateFaceRemover
         | 
|  | |
| 31 |  | 
| 32 |  | 
| 33 | 
             
            def image_to_3d(image_path='assets/demo.png'):
         | 
| 34 | 
            +
                rembg = BackgroundRemover()
         | 
| 35 | 
             
                model_path = 'Hunyuan3D-2'
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                image = Image.open(image_path)
         | 
| 38 | 
            +
                image = image.resize((1024, 1024))
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                if image.mode == 'RGB':
         | 
| 41 | 
            +
                    image = rembg(image)
         | 
| 42 | 
            +
             | 
| 43 | 
             
                pipeline = Hunyuan3DDiTFlowMatchingPipeline.from_pretrained(model_path)
         | 
| 44 |  | 
| 45 | 
            +
                mesh = pipeline(image=image, num_inference_steps=30, mc_algo='mc',
         | 
| 46 | 
             
                                generator=torch.manual_seed(2025))[0]
         | 
| 47 | 
             
                mesh = FloaterRemover()(mesh)
         | 
| 48 | 
             
                mesh = DegenerateFaceRemover()(mesh)
         | 
|  | |
| 52 | 
             
                try:
         | 
| 53 | 
             
                    from hy3dgen.texgen import Hunyuan3DPaintPipeline
         | 
| 54 | 
             
                    pipeline = Hunyuan3DPaintPipeline.from_pretrained(model_path)
         | 
| 55 | 
            +
                    mesh = pipeline(mesh, image=image)
         | 
| 56 | 
             
                    mesh.export('texture.glb')
         | 
| 57 | 
             
                except Exception as e:
         | 
| 58 | 
             
                    print(e)
         | 

