Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
47 changes: 47 additions & 0 deletions .github/workflows/windows-portable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Windows portable EXE

on:
workflow_dispatch:
pull_request:
branches: [main]
push:
branches: [main]
paths:
- "desktop.py"
- "app.py"
- "imagen3d/**"
- "requirements*.txt"
- "scripts/build_windows.ps1"
- ".github/workflows/windows-portable.yml"

jobs:
windows-build:
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
architecture: x64
cache: pip
cache-dependency-path: |
requirements.txt
requirements-desktop.txt
- name: Create Python environment
shell: pwsh
run: py -3.12 -m venv .venv
- name: Build portable app
shell: pwsh
run: ./scripts/build_windows.ps1
- name: Archive portable folder
shell: pwsh
run: Compress-Archive -Path "dist/3D-Creator" -DestinationPath "3D-Creator-Windows-x64.zip"
- name: Upload executable bundle
uses: actions/upload-artifact@v4
with:
name: 3D-Creator-Windows-x64
path: 3D-Creator-Windows-x64.zip
if-no-files-found: error
retention-days: 14
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ __pycache__/
*.pyc
*.log
artifacts/
build/
dist/
*.spec
58 changes: 58 additions & 0 deletions desktop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Desktop entrypoint: local Gradio server displayed in a native window."""
import os
import sys
import traceback
import webbrowser

os.environ.setdefault("GRADIO_ANALYTICS_ENABLED", "False")

from app import CSS, create_app
from imagen3d.storage import start_cleaner


def main():
import gradio as gr
import uvicorn

start_cleaner()
demo = create_app().queue(max_size=16)
uvicorn.Config(app=demo.app, log_level="warning").load()
try:
demo.launch(
server_name="127.0.0.1",
server_port=7860,
share=False,
inbrowser=False,
prevent_thread_lock=True,
max_file_size="15mb",
theme=gr.themes.Soft(primary_hue="cyan", neutral_hue="slate"),
css=CSS,
)
url = demo.local_url or "http://127.0.0.1:7860"
try:
import webview
webview.create_window("3D Creator Studio", url, width=1360, height=900,
min_size=(850, 600))
webview.start()
except Exception as exc:
print(f"No se pudo abrir la ventana nativa: {exc}", file=sys.stderr)
print(f"Abriendo la interfaz en el navegador: {url}")
webbrowser.open(url)
input("Pulsa Intro para detener el servidor... ")
finally:
demo.close()


if __name__ == "__main__":
try:
if "--check" in sys.argv:
import trimesh
instance = create_app()
assert instance is not None
print("OK: dependencias e interfaz cargadas.")
else:
main()
except Exception:
traceback.print_exc()
input("Error al arrancar. Pulsa Intro para salir... ")
sys.exit(1)
52 changes: 52 additions & 0 deletions docs/WINDOWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Ejecutable portable de Windows

Esta es una **versión preliminar** del empaquetado de 3D Creator Studio.
No se han cambiado los motores de generación ni el flujo Python habitual.

## Descargar la compilación

Abre la pestaña **Actions** de GitHub, selecciona **Windows portable EXE**
y ejecuta **Run workflow** sobre la rama `feat/windows-portable-exe`.
Cuando termine correctamente, descarga el artefacto
`3D-Creator-Windows-x64`. Extrae el ZIP y abre
`3D-Creator/3D-Creator.exe`.

**Conserva toda la carpeta**, incluido `_internal`; el ejecutable no
funciona si se separa de sus dependencias.

## Compilar en Windows 10/11

Requiere Python 3.12 de 64 bits para compilar:

```powershell
py -3.12 -m venv .venv
.\scripts\build_windows.ps1
```

El resultado queda en `dist/3D-Creator/3D-Creator.exe`.
El script comprueba que el EXE puede importar las dependencias y construir
la interfaz, pero se debe realizar además una prueba manual de la ventana,
el visor 3D y las exportaciones STL/GLB en Windows.

## Comportamiento

- Gradio escucha únicamente en `127.0.0.1:7860`, sin enlaces públicos.
- pywebview muestra la interfaz en una ventana propia usando WebView2.
- Si pywebview falla, intenta abrir el navegador predeterminado.
- Cerrar la ventana nativa detiene el servidor. Con el navegador alternativo,
pulsa Intro en la consola para terminar.
- La consola permanece visible durante esta fase para facilitar diagnósticos.
- Si el puerto 7860 está ocupado, cierra la otra instancia.
- Windows puede requerir WebView2 y mostrar avisos para EXE sin firma.

## Limitaciones expresas

Las modalidades que no necesitan IA local (extrusión de siluetas y relieve desde
mapa de alturas) son el objetivo de este primer empaquetado. **TripoSR y Depth
Anything V2 no están incluidos**. Requieren entornos Python y pesos externos
en rutas concretas, por lo que no se garantiza que funcionen dentro del ZIP.
Para esas dos modalidades, sigue usando la instalación Python del README.

Esto no es todavía un instalador MSI, una aplicación firmada ni un sistema
de actualizaciones automáticas. Tampoco incorpora todavía el editor de mallas
interactivo; es un empaquetado de las funciones existentes.
2 changes: 2 additions & 0 deletions requirements-desktop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyinstaller==6.16.0
pywebview==6.1
12 changes: 12 additions & 0 deletions scripts/build_windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$ErrorActionPreference = "Stop"
Set-Location (Resolve-Path (Join-Path $PSScriptRoot ".."))
$python = Join-Path (Get-Location) ".venv\Scripts\python.exe"
if (-not (Test-Path $python)) { throw "Falta .venv. Ejecuta: py -3.12 -m venv .venv" }
& $python -m pip install -r requirements.txt -r requirements-desktop.txt
if ($LASTEXITCODE -ne 0) { throw "Fallo la instalacion" }
$flags = @("--noconfirm", "--clean", "--onedir", "--console", "--name", "3D-Creator", "--collect-all", "gradio", "--collect-all", "gradio_client", "--collect-all", "trimesh", "--collect-all", "shapely", "--collect-all", "cv2", "--collect-all", "manifold3d", "--collect-submodules", "webview", "--hidden-import=uvicorn.protocols.http.auto", "--hidden-import=uvicorn.lifespan.on", "desktop.py")
& $python -m PyInstaller @flags
if ($LASTEXITCODE -ne 0) { throw "Fallo la compilacion" }
& ".\dist\3D-Creator\3D-Creator.exe" --check
if ($LASTEXITCODE -ne 0) { throw "Fallo la comprobacion del ejecutable" }
Write-Host "Compilado: dist\3D-Creator\3D-Creator.exe"
Loading