File size: 7,302 Bytes
49d1739
af8fde2
 
cbf824f
e053144
890aef1
a4209fa
49d1739
e053144
a4209fa
e053144
 
a4209fa
e053144
 
04532d1
a4209fa
e053144
 
a4209fa
e053144
 
a4209fa
 
e053144
a4209fa
e053144
a4209fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e053144
a4209fa
 
 
e053144
 
a4209fa
e053144
 
 
 
04532d1
e053144
 
 
 
 
04532d1
38be658
a4209fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e053144
04532d1
a4209fa
04532d1
 
 
 
e053144
 
a4209fa
af8fde2
e053144
 
 
 
a4209fa
e053144
953ea94
e053144
 
04532d1
 
e053144
a4209fa
e053144
 
 
af8fde2
e053144
 
 
04532d1
 
e053144
a4209fa
04532d1
e053144
 
 
 
 
 
 
890aef1
e053144
 
890aef1
e053144
 
890aef1
e053144
a4209fa
e053144
 
 
 
a4209fa
 
e053144
 
 
 
a4209fa
 
af8fde2
 
 
 
 
 
 
953ea94
e053144
953ea94
a4209fa
331812c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import gradio as gr
import subprocess
import os
import spaces
import glob
from pathlib import Path
import torch

class InfinigenManager:
    def __init__(self, base_dir="infinigen", output_dir="outputs", blender_version="4.3.2"):
        self.base_dir = Path(base_dir)
        self.output_dir = Path(output_dir)
        self.blender_version = blender_version
        self.blender_bin = None
        self.blender_python = None
        self.initialized = False
        print("Initialisiere InfinigenManager...")
        self._setup_blender()
        self._setup_infinigen()
        self._check_cuda()

    def _setup_blender(self):
        """Installiert Blender 4.3.2, falls nötig, und findet den Python-Interpreter."""
        print("Starte Blender-Setup...")
        try:
            # Prüfe vorhandene Blender-Version
            blender_bins = glob.glob("/usr/bin/blender")
            if blender_bins:
                self.blender_bin = blender_bins[0]
                version_result = subprocess.run([self.blender_bin, "-v"], capture_output=True, text=True, timeout=10)
                current_version = next((line.split()[1] for line in version_result.stdout.split("\n") if "Blender" in line and "." in line), None)
                print(f"Vorhandene Blender-Version: {current_version or 'unbekannt'}")
                if current_version and current_version >= self.blender_version:
                    print("Vorhandene Version ist aktuell genug.")
                else:
                    print("Installiere neueste Blender-Version...")
                    self._install_latest_blender()
            else:
                print("Kein Blender vorhanden, installiere neueste Version...")
                self._install_latest_blender()

            # Finde Blender-Python
            base_path = f"/home/user/blender-{self.blender_version}-linux-x64" if self.blender_bin == f"/home/user/blender-{self.blender_version}-linux-x64/blender" else "/usr/share/blender"
            python_patterns = [
                f"{base_path}/python/bin/python*",
                "/usr/share/blender/*/python/bin/python*",
                "/usr/lib/blender/*/python/bin/python*"
            ]
            for pattern in python_patterns:
                print(f"Suche nach Python mit Muster: {pattern}")
                python_bins = glob.glob(pattern, recursive=True)
                if python_bins:
                    self.blender_python = python_bins[0]
                    print(f"Blender Python gefunden: {self.blender_python}")
                    self.initialized = True
                    return
            
            raise RuntimeError("Blender Python-Interpreter nicht gefunden!")
        except Exception as e:
            print(f"Fehler bei Blender-Setup: {e}")
            self.blender_python = None

    def _install_latest_blender(self):
        """Installiert Blender 4.3.2 dynamisch zur Laufzeit."""
        try:
            print("Lade Blender 4.3.2 herunter...")
            subprocess.run([
                "wget", "https://download.blender.org/release/Blender4.3/blender-4.3.2-linux-x64.tar.xz"
            ], check=True, timeout=60)
            print("Entpacke Blender 4.3.2...")
            subprocess.run([
                "tar", "-xvf", "blender-4.3.2-linux-x64.tar.xz", "-C", "/home/user"
            ], check=True, timeout=60)
            self.blender_bin = "/home/user/blender-4.3.2-linux-x64/blender"
            print(f"Blender 4.3.2 installiert unter: {self.blender_bin}")
            os.remove("blender-4.3.2-linux-x64.tar.xz")
        except Exception as e:
            print(f"Fehler bei der Installation von Blender 4.3.2: {e}")
            raise

    def _check_cuda(self):
        """Prüft CUDA-Verfügbarkeit."""
        if torch.cuda.is_available():
            print(f"CUDA verfügbar: {torch.cuda.get_device_name(0)}")
        else:
            print("CUDA nicht verfügbar!")

    def _setup_infinigen(self):
        """Installiert Infinigen, falls möglich."""
        print("Starte Infinigen-Setup...")
        if not self.blender_python:
            print("Kann Infinigen nicht installieren: Blender Python fehlt.")
            return
        
        if not self.base_dir.exists():
            print("Klone Infinigen...")
            subprocess.run(["git", "clone", "https://github.com/princeton-vl/infinigen.git"], check=True, timeout=30)
        
        if not self._is_infinigen_installed():
            print("Installiere Infinigen...")
            subprocess.run([
                self.blender_python, "-m", "pip", "install", "-e", str(self.base_dir) + "[terrain,vis]", "--no-deps", "--user"
            ], check=True, timeout=60)
            print("Infinigen installiert.")

    def _is_infinigen_installed(self):
        """Prüft, ob Infinigen bereits installiert ist."""
        if not self.blender_python:
            return False
        try:
            subprocess.run([self.blender_python, "-c", "import infinigen"], check=True, capture_output=True, timeout=10)
            return True
        except subprocess.CalledProcessError:
            return False

    @spaces.GPU
    def generate_scene(self, seed, configs=None, pipeline_configs=None):
        """Generiert eine Szene mit Infinigen."""
        if not self.initialized or not self.blender_python:
            return "Fehler: Infinigen nicht initialisiert (Blender Python fehlt)!"
        
        print(f"Generiere Szene mit Seed: {seed}")
        self.output_dir.mkdir(exist_ok=True)
        configs = configs or ["infinigen_examples/configs/desert.gin", "infinigen_examples/configs/simple.gin"]
        pipeline_configs = pipeline_configs or [
            "infinigen_examples/configs/local_16GB.gin",
            "infinigen_examples/configs/monocular.gin",
            "infinigen_examples/configs/blender_gt.gin"
        ]
        
        command = [
            self.blender_python, "-m", "infinigen.datagen.manage_jobs",
            "--output_folder", str(self.output_dir),
            "--num_scenes", "1",
            "--specific_seed", str(int(seed))
        ] + ["--configs"] + configs + ["--pipeline_configs"] + pipeline_configs
        
        try:
            result = subprocess.run(command, capture_output=True, text=True, check=True, timeout=300)
            print(f"STDOUT: {result.stdout}")
            print(f"STDERR: {result.stderr}")
            output_path = self.output_dir / "0000000000.png"
            return str(output_path) if output_path.exists() else f"Fehler: Bild nicht gefunden. STDERR: {result.stderr}"
        except subprocess.TimeoutExpired as e:
            return f"Fehler: Timeout bei Szenengenerierung: {e.stderr}"
        except subprocess.CalledProcessError as e:
            return f"Fehler: {e.stderr}"

# Manager initialisieren
print("Starte Manager-Initialisierung...")
manager = InfinigenManager()

# Gradio-Oberfläche
with gr.Blocks(title="Infinigen Demo") as demo:
    gr.Markdown("## Infinigen Scene Generator")
    seed_input = gr.Number(label="Seed", value=0, precision=0)
    output_image = gr.Image(label="Generierte Szene")
    generate_button = gr.Button("Szene generieren")
    
    generate_button.click(fn=manager.generate_scene, inputs=[seed_input], outputs=[output_image])

print("Starte Gradio-Oberfläche...")
demo.launch()