Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a84585a
updated requirement
AryanGrutto Aug 31, 2025
bda87d3
conda accept terms and conditions
AryanGrutto Aug 31, 2025
91fe4db
updated docker
AryanGrutto Aug 31, 2025
34cd31f
update
AryanGrutto Aug 31, 2025
e6368ae
u
AryanGrutto Aug 31, 2025
b79916d
u
AryanGrutto Aug 31, 2025
9c11a8d
u
AryanGrutto Aug 31, 2025
248d892
new one
AryanGrutto Aug 31, 2025
9c366f3
parse error
AryanGrutto Aug 31, 2025
fbdf7f7
updated
AryanGrutto Aug 31, 2025
cba218b
adjusted path
AryanGrutto Aug 31, 2025
6007f9e
path update
AryanGrutto Aug 31, 2025
7db013e
path
AryanGrutto Aug 31, 2025
b8273db
update path
AryanGrutto Aug 31, 2025
4d38095
test
AryanGrutto Sep 3, 2025
2c61c17
update path
AryanGrutto Sep 3, 2025
6bf8592
updated small naming
AryanGrutto Sep 3, 2025
4ebf83b
Added alpha API
AryanGrutto Sep 10, 2025
eb639dc
removed the alpha API
AryanGrutto Sep 14, 2025
78e5660
Merge branch 'main' into main
Aryan-Behzadi Sep 14, 2025
3e11a64
Merge branch 'Tencent-Hunyuan:main' into main
AryanGrutto Sep 25, 2025
f8c9419
updated some text
AryanGrutto Oct 3, 2025
dc0fe02
remove white space
AryanGrutto Oct 6, 2025
a645169
Multi view enabled
AryanGrutto Oct 6, 2025
dedbe42
Merge pull request #1 from AryanGrutto/dev
AryanGrutto Oct 6, 2025
e6b7b73
handling multiimage selection
AryanGrutto Oct 6, 2025
035a104
dimention mismatch potential fix
AryanGrutto Oct 6, 2025
a6d6e38
fixed
AryanGrutto Oct 6, 2025
ce12c17
Revert "remove white space"
AryanGrutto Oct 6, 2025
ff39f9e
Reapply "remove white space"
AryanGrutto Oct 6, 2025
eb8c7ed
Revert "fixed"
AryanGrutto Oct 6, 2025
0b2803c
Revert "dimention mismatch potential fix"
AryanGrutto Oct 6, 2025
f99a550
Revert "handling multiimage selection"
AryanGrutto Oct 6, 2025
3273573
Revert "Merge pull request #1 from AryanGrutto/dev"
AryanGrutto Oct 6, 2025
34e784e
Latest stable
AryanGrutto Oct 7, 2025
06ac482
small updates
AryanGrutto Oct 7, 2025
16aae6e
added Mv
AryanGrutto Oct 7, 2025
9c8e929
mv updated
AryanGrutto Oct 7, 2025
00071d8
fixed the sub folder as well
AryanGrutto Oct 7, 2025
30dd428
updated the tex gen
AryanGrutto Oct 7, 2025
dcabde9
small fixes for texgen
AryanGrutto Oct 7, 2025
140d415
adjustments
AryanGrutto Oct 7, 2025
7ad2962
Update Dockerfile
AryanGrutto Oct 7, 2025
dfcb7df
hh
AryanGrutto Oct 7, 2025
9a9ac34
reverted to normal
AryanGrutto Oct 7, 2025
7cccc2f
make the download avalibale.
AryanGrutto Oct 10, 2025
39da5fd
Merge branch 'Tencent-Hunyuan:main' into main
AryanGrutto Oct 24, 2025
2510105
upload to storage
AryanGrutto Nov 19, 2025
b743bb7
Merge pull request #2 from AryanGrutto/upload-to-storage
AryanGrutto Nov 19, 2025
024fd42
Added the credentials
AryanGrutto Nov 20, 2025
bb149b2
Revert "Added the credentials"
AryanGrutto Nov 20, 2025
5231ebe
updated the port
AryanGrutto Nov 30, 2025
c1bd960
small update
AryanGrutto Nov 30, 2025
3614951
Revert "updated the port"
AryanGrutto Nov 30, 2025
7b89746
latest changes
AryanGrutto Dec 1, 2025
20f04ab
removed S3 conneciton, added the initial (Mesh Only) to response
AryanGrutto Dec 1, 2025
b419c13
response API scheme update
AryanGrutto Dec 1, 2025
0406efe
add an "and"
AryanGrutto Dec 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added alpha_api.py
Empty file.
62 changes: 61 additions & 1 deletion api_models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Pydantic models for Hunyuan3D API server.
"""
from typing import Optional, Literal
from typing import Optional, Literal, Dict
from pydantic import BaseModel, Field


Expand All @@ -26,6 +26,62 @@ class GenerationRequest(BaseModel):
ge=0,
le=2**32-1
)
octree_resolution: int = Field( # Can be changed
256,
description="Resolution of the octree for mesh generation",
ge=64,
le=512
)
num_inference_steps: int = Field(
5,
description="Number of inference steps for generation",
ge=1,
le=20
)
guidance_scale: float = Field( # Can be changed
5.0,
description="Guidance scale for generation",
ge=0.1,
le=20.0
)
num_chunks: int = Field(
8000,
description="Number of chunks for processing",
ge=1000,
le=20000
)
face_count: int = Field( # Can be changed
40000,
description="Maximum number of faces for texture generation",
ge=1000,
le=100000
)


class MultiViewGenerationRequest(BaseModel):
"""Request model for multi-view 3D generation API"""
images: Dict[str, str] = Field(
...,
description="Dictionary of view images with keys: 'front', 'back', 'left', 'right'. At least one view must be provided.",
example={
"front": "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAEElEQVR4nGP8z4AATAxEcQAz0QEHOoQ+uAAAAABJRU5ErkJggg==",
"back": "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAEElEQVR4nGP8z4AATAxEcQAz0QEHOoQ+uAAAAABJRU5ErkJggg=="
}
)
remove_background: bool = Field(
True,
description="Whether to automatically remove background from input images"
)
texture: bool = Field(
False,
description="Whether to generate textures for the 3D model"
)
seed: int = Field(
1234,
description="Random seed for reproducible generation",
ge=0,
le=2**32-1
)
octree_resolution: int = Field(
256,
description="Resolution of the octree for mesh generation",
Expand Down Expand Up @@ -70,6 +126,10 @@ class StatusResponse(BaseModel):
None,
description="Base64 encoded generated model file (only when status is 'completed')"
)
initial_model_base64: Optional[str] = Field(
None,
description="Base64 encoded initial model file (only when status is 'completed')"
)
message: Optional[str] = Field(
None,
description="Error message (only when status is 'error')"
Expand Down
9 changes: 4 additions & 5 deletions api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
worker = None
model_semaphore = None


app = FastAPI(
title=API_TITLE,
description=API_DESCRIPTION,
Expand Down Expand Up @@ -171,13 +170,14 @@ async def status(uid: str):
#print(f"Checking files: {textured_file_path} ({os.path.exists(textured_file_path)}), {initial_file_path} ({os.path.exists(initial_file_path)})")

# If textured file exists, generation is complete
if os.path.exists(textured_file_path):
if os.path.exists(textured_file_path) and os.path.exists(initial_file_path):
try:
base64_str = base64.b64encode(open(textured_file_path, 'rb').read()).decode()
response = {'status': 'completed', 'model_base64': base64_str}
base64_str_initial = base64.b64encode(open(initial_file_path, 'rb').read()).decode()
response = {'status': 'completed', 'model_base64': base64_str, 'initial_model_base64': base64_str_initial}
return JSONResponse(response, status_code=200)
except Exception as e:
logger.error(f"Error reading file {textured_file_path}: {e}")
logger.error(f"{e}")
response = {'status': 'error', 'message': 'Failed to read generated file'}
return JSONResponse(response, status_code=500)

Expand Down Expand Up @@ -212,7 +212,6 @@ async def status(uid: str):
SAVE_DIR = args.cache_path
os.makedirs(SAVE_DIR, exist_ok=True)


model_semaphore = asyncio.Semaphore(args.limit_model_concurrency)

worker = ModelWorker(
Expand Down
30 changes: 23 additions & 7 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ENV PATH="/workspace/miniconda3/bin:${PATH}"
# initialize conda
RUN conda init bash


# Accept Anaconda TOS for required channels
RUN conda tos accept --channel https://repo.anaconda.com/pkgs/main && \
conda tos accept --channel https://repo.anaconda.com/pkgs/r
Expand All @@ -55,26 +56,40 @@ RUN conda install cuda -c nvidia/label/cuda-12.4.1 -y
# Update libstdcxx-ng to fix compatibility issues (auto-confirm)
RUN conda install -c conda-forge libstdcxx-ng -y

RUN apt install -y python3.10-venv python3.10-distutils python3.10-dev build-essential cmake
RUN python3.10 -m venv venv310
RUN venv310/bin/pip install --upgrade pip setuptools wheel

RUN pip install --upgrade pip setuptools wheel

RUN pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu124

# RUN pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu118

RUN pip install bpy==4.0 --extra-index-url https://download.blender.org/pypi/

# Clone Hunyuan3D-2.1 repository
RUN git clone https://github.com/Tencent-Hunyuan/Hunyuan3D-2.1.git
RUN git clone https://github.com/AryanGrutto/Hunyuan3D-2.1.git

# Install Python dependencies from modified requirements.txt
RUN pip install -r Hunyuan3D-2.1/requirements.txt

# Install custom_rasterizer
RUN cd /workspace/Hunyuan3D-2.1/hy3dpaint/custom_rasterizer && \
# Set compilation environment variables
export TORCH_CUDA_ARCH_LIST="6.0;6.1;7.0;7.5;8.0;8.6;8.9;9.0" && \
export CUDA_NVCC_FLAGS="-allow-unsupported-compiler" && \
# Install with editable mode
pip install -e .
pip install --no-build-isolation .

# Install DifferentiableRenderer
RUN cd /workspace/Hunyuan3D-2.1/hy3dpaint/DifferentiableRenderer && \
RUN cd /workspace/Hunyuan3D-2.1/hy3dpaint && \
mkdir -p hy3dpaint/DifferentiableRenderer && \
python3 DifferentiableRenderer/setup.py build_ext --inplace && \
cd DifferentiableRenderer && \
bash compile_mesh_painter.sh

RUN wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P hy3dpaint/ckpt


# Create ckpt folder in hy3dpaint and download RealESRGAN model
RUN cd /workspace/Hunyuan3D-2.1/hy3dpaint && \
mkdir -p ckpt && \
Expand All @@ -100,14 +115,15 @@ RUN apt-get install -y libxi6 libgconf-2-4 libxkbcommon-x11-0 libsm6 libxext6 li
RUN echo "conda activate hunyuan3d21" >> ~/.bashrc
SHELL ["/bin/bash", "--login", "-c"]

#exposing 7860 port
EXPOSE 7860
#exposing 8081 port for API server
EXPOSE 8081

# Cleanup
RUN rm -f /workspace/*.zip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*


# Set default command
WORKDIR /workspace/Hunyuan3D-2.1
RUN mkdir gradio_cache
Expand Down
27 changes: 15 additions & 12 deletions gradio_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,13 +452,13 @@ def shape_generation(


def build_app():
title = 'Hunyuan3D-2: High Resolution Textured 3D Assets Generation'
title = 'Introducing Alpha 2.0 Image to 3D Generation'
if MV_MODE:
title = 'Hunyuan3D-2mv: Image to 3D Generation with 1-4 Views'
title = 'Alpha3D-2-mv: Image to 3D Generation with 1-4 Views'
if 'mini' in args.subfolder:
title = 'Hunyuan3D-2mini: Strong 0.6B Image to Shape Generator'
title = 'Alpha3D-2mini: Strong 0.6B Image to Shape Generator'

title = 'Hunyuan-3D-2.1'
title = 'Alpha3D-2'

if TURBO_MODE:
title = title.replace(':', '-Turbo: Fast ')
Expand All @@ -469,7 +469,7 @@ def build_app():
{title}
</div>
<div align="center">
Tencent Hunyuan3D Team
Alpha Intelligence Team
</div>
"""
custom_css = """
Expand All @@ -486,7 +486,7 @@ def build_app():

"""

with gr.Blocks(theme=gr.themes.Base(), title='Hunyuan-3D-2.1', analytics_enabled=False, css=custom_css) as demo:
with gr.Blocks(theme=gr.themes.Base(), title='Alpha3d 2.0', analytics_enabled=False, css=custom_css) as demo:
gr.HTML(title_html)

with gr.Row():
Expand Down Expand Up @@ -624,8 +624,9 @@ def build_app():
],
outputs=[file_out, html_gen_mesh, stats, seed]
).then(
lambda: (gr.update(visible=False, value=False), gr.update(interactive=True), gr.update(interactive=True),
gr.update(interactive=False)),
lambda file_path: (gr.update(visible=False, value=False), gr.update(interactive=True), gr.update(interactive=True),
gr.update(value=file_path, interactive=True)),
inputs=[file_out],
outputs=[export_texture, reduce_face, confirm_export, file_export],
).then(
lambda: gr.update(selected='gen_mesh_panel'),
Expand All @@ -651,8 +652,9 @@ def build_app():
],
outputs=[file_out, file_out2, html_gen_mesh, stats, seed]
).then(
lambda: (gr.update(visible=True, value=True), gr.update(interactive=False), gr.update(interactive=True),
gr.update(interactive=False)),
lambda file_path: (gr.update(visible=True, value=True), gr.update(interactive=False), gr.update(interactive=True),
gr.update(value=file_path, interactive=True)),
inputs=[file_out2],
outputs=[export_texture, reduce_face, confirm_export, file_export],
).then(
lambda: gr.update(selected='gen_mesh_panel'),
Expand Down Expand Up @@ -754,14 +756,15 @@ def on_export_click(file_out, file_out2, file_type,

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
MV_MODE = 'mv' in args.model_path
# MV_MODE = True
TURBO_MODE = 'turbo' in args.subfolder

HTML_HEIGHT = 690 if MV_MODE else 650
HTML_WIDTH = 500
HTML_OUTPUT_PLACEHOLDER = f"""
<div style='height: {650}px; width: 100%; border-radius: 8px; border-color: #e5e7eb; border-style: solid; border-width: 1px; display: flex; justify-content: center; align-items: center;'>
<div style='text-align: center; font-size: 16px; color: #6b7280;'>
<p style="color: #8d8d8d;">Welcome to Hunyuan3D!</p>
<p style="color: #8d8d8d;">Welcone to Alpha 2.0 powered by Alpha Intelligence</p>
<p style="color: #8d8d8d;">No mesh here.</p>
</div>
</div>
Expand Down Expand Up @@ -862,4 +865,4 @@ def on_export_click(file_out, file_out2, file_type,
torch.cuda.empty_cache()
demo = build_app()
app = gr.mount_gradio_app(app, demo, path="/")
uvicorn.run(app, host=args.host, port=args.port)
uvicorn.run(app, host=args.host, port=args.port)
22 changes: 22 additions & 0 deletions hy3dpaint/DifferentiableRenderer/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
from setuptools import setup
from pybind11.setup_helpers import Pybind11Extension, build_ext
import pybind11
import numpy

this_dir = os.path.dirname(__file__)
source_file = os.path.join(this_dir, "mesh_inpaint_processor.cpp")

ext = Pybind11Extension(
"hy3dpaint.DifferentiableRenderer.mesh_inpaint_processor",
[source_file],
include_dirs=[pybind11.get_include(), numpy.get_include()],
language="c++",
extra_compile_args=["-O3", "-std=c++17"],
)

setup(
name="mesh_inpaint_processor_build",
ext_modules=[ext],
cmdclass={"build_ext": build_ext},
)
Loading