dfrokido commited on
Commit
6f5fd07
·
verified ·
1 Parent(s): 659b511

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -0
app.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```python
2
+
3
+ import torch
4
+ import numpy as np
5
+ from PIL import Image
6
+ import gradio as gr
7
+ import trimesh
8
+ from gsplat import GaussianModel, render
9
+
10
+ class Persistent3DCortex:
11
+ def __init__(self, grid_size=32):
12
+ self.grid_size = grid_size
13
+ self.n_voxels = grid_size ** 3
14
+ # For a fast demo, we'll skip the full GaussianModel init
15
+ # self.gaussian_model = GaussianModel(sh_degree=3)
16
+
17
+ # Initialize with esolang density (Piet-inspired)
18
+ # This is our 3D grid of information
19
+ self.colors = torch.rand(self.n_voxels, 3)
20
+ self.positions = torch.rand(self.n_voxels, 3) * 2 - 1
21
+ self.scales = torch.ones(self.n_voxels, 3) * 0.05
22
+ self.opacities = torch.ones(self.n_voxels) * 0.5
23
+
24
+ # Simple NCA update net (8k params)
25
+ self.nca_net = torch.nn.Sequential(
26
+ torch.nn.Linear(48, 128),
27
+ torch.nn.ReLU(),
28
+ torch.nn.Linear(128, 16)
29
+ )
30
+
31
+ def evolve_with_nca(self, target_image, steps=100):
32
+ """Evolve grid using NCA rules to match the target image"""
33
+ for step in range(steps):
34
+ # Perception: Sobel gradients for neighborhood info
35
+ grad_x = self._sobel_gradient(axis=0)
36
+ grad_y = self._sobel_gradient(axis=1)
37
+ grad_z = self._sobel_gradient(axis=2)
38
+
39
+ # ML update (simulates analog in-memory processing)
40
+ perception = torch.cat([
41
+ self.colors, grad_x, grad_y, grad_z
42
+ ], dim=1)
43
+
44
+ delta = self.nca_net(perception)
45
+ self.colors = torch.clamp(self.colors + delta[:, :3], 0, 1)
46
+
47
+ # Stochastic mask (a random 50% of voxels don't update)
48
+ mask = torch.rand(self.n_voxels) > 0.5
49
+ self.colors[mask] = self.colors[mask].detach()
50
+
51
+ def _sobel_gradient(self, axis):
52
+ """Calculate spatial gradients (simulates neighborhood perception)"""
53
+ sobel_kernel = torch.tensor([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
54
+ # Reshape for 3D convolution
55
+ color_grid = self.colors.reshape(1, 1, self.grid_size, self.grid_size, self.grid_size)
56
+ kernel_grid = sobel_kernel.reshape(1, 1, 3, 3, 3)
57
+ # Apply convolution
58
+ return torch.conv3d(color_grid, kernel_grid, padding=1).flatten()
59
+
60
+ def export_to_3d(self):
61
+ """Convert evolved grid to 3D mesh using a simple threshold method"""
62
+ threshold = 0.5
63
+ vertices, faces = [], []
64
+
65
+ # A simple marching cubes approximation
66
+ for i in range(self.grid_size - 1):
67
+ for j in range(self.grid_size - 1):
68
+ for k in range(self.grid_size - 1):
69
+ idx = i * self.grid_size**2 + j * self.grid_size + k
70
+ if self.colors[idx].mean() > threshold:
71
+ # Add a simple cube geometry for this voxel
72
+ v_offset = len(vertices)
73
+ vertices.extend([
74
+ [i, j, k], [i+1, j, k], [i+1, j+1, k], [i, j+1, k],
75
+ [i, j, k+1], [i+1, j, k+1], [i+1, j+1, k+1], [i, j+1, k+1]
76
+ ])
77
+ faces.extend([
78
+ [v_offset, v_offset+1, v_offset+2],
79
+ [v_offset, v_offset+2, v_offset+3]
80
+ ])
81
+
82
+ mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
83
+ return mesh.export('output.obj')
84
+
85
+ # --- This is the Gradio Interface ---
86
+
87
+ # Create one instance of our cortex
88
+ cortex = Persistent3DCortex(grid_size=32)
89
+
90
+ def process_input(image, prompt):
91
+ """The function that runs when the user clicks submit"""
92
+ print(f"User prompt: {prompt}") # Helpful for debugging
93
+
94
+ # Adapt target based on prompt (simplified for demoe)
95
+ # Here, we could use an LLM or a text-image model to adjust the target image
96
+
97
+ if "smooth" in prompt.lower():
98
+ step_count = 150
99
+ elif "blocky" in prompt.lower():
100
+ step_count = 50
101
+ else:
102
+ step_count = 100
103
+
104
+ # Evolve with NCA
105
+ img_tensor = torch.tensor(np.array(image) / 255.0).float()
106
+ cortex.evolve_with_nca(img_tensor, steps=step_count)
107
+
108
+ # Export result
109
+ obj_file = cortex.export_to_3d()
110
+
111
+ # Return the file path to the user and a success message
112
+ return 'output.obj', f"Persistent 3D cortex generated in {step_count} steps based on your: '{prompt}'!"
113
+
114
+ # Define the interface
115
+ demo = gr.Interface(
116
+ fn=process_input,
117
+ inputs=[gr.Image(type="pil", label="Upload an Image"), gr.Textbox(lines=1, label="Prompt")],
118
+ outputs=[gr.File(label="Download your 3D Model (.obj)"), gr.Text(label="Status")],
119
+ title="Persistent 3D Cortex Demo",
120
+ description="Upload an image and describe what you want. Watch a persistent, evolving 3D 'brain' generate a 3D model from your input!"
121
+ )
122
+
123
+ # This is the only line needed to run the app on Hugging Face
124
+ demo.launch()
125
+
126
+ ```python