Supernova Prism V0.1

An experimental single-image-to-3D geometry reconstruction model.

Supernova Prism is an early research prototype that takes one RGB image and predicts a 3D voxel representation of the object shown in that image.

The project explores learning a mapping from 2D visual information to 3D geometry using a custom neural network trained from random initialization.

Status: Experimental prototype. This release is intended for research, experimentation, and development. It is not a production-ready general-purpose 3D reconstruction system.

Why was Prism created?

The goal of Supernova Prism is to investigate whether a custom-trained neural architecture can estimate an object's 3D geometry from a single photograph.

The longer-term project aims to develop an image-to-3D system that can eventually support:

  • More detailed 3D geometry.
  • Better reconstruction of unseen object categories.
  • Surface appearance and texture prediction.
  • Exportable 3D assets.
  • Efficient local inference.

V0.1 is the first experimental baseline toward those goals.

How was it made?

Prism V0.1 was trained using:

  • A custom 2D convolutional image encoder.
  • A learned 512-dimensional latent representation.
  • A 3D convolutional geometry decoder.
  • Random parameter initialization.
  • PyTorch.
  • Google Colab with an NVIDIA T4 GPU.
  • Pix3D image and voxel-model data from Hugging Face.

No pretrained vision encoder was used.

Architecture

Input RGB image (128 Γ— 128) | v Custom 2D CNN image encoder | v 512-dimensional latent vector | v 3D geometry decoder | v 32 Γ— 32 Γ— 32 voxel occupancy prediction | v Thresholded geometry | v GLB mesh export

Current evaluation

The following results were measured on the held-out test split.

Metric Result
Voxel accuracy 84.9680%
Precision 22.2508%
Recall 25.2429%
F1-score 23.6526%
Voxel IoU 13.4125%

Voxel accuracy can be misleading because most voxels in a 3D grid are empty. IoU and F1 are more useful indicators of occupied-geometry overlap.

These scores describe this particular experimental test setup. They do not establish performance on arbitrary real-world photographs.

Current features

  • Single RGB image input.
  • Custom image encoder.
  • Learned image-to-3D latent representation.
  • 3D voxel geometry prediction.
  • 32Β³ output resolution.
  • Configurable voxel threshold during inference.
  • GLB mesh export.
  • Local CPU or CUDA inference, subject to available memory.

Current limitations

  • Geometry is relatively coarse.
  • Reconstruction quality is limited.
  • The model has not demonstrated broad generalization.
  • Hidden object surfaces must be estimated from the visible photograph.
  • V0.1 does not predict realistic textures or surface colors.
  • The image preprocessing resizes photographs to a square input.
  • The model was evaluated on a limited dataset and object distribution.

A single image cannot uniquely reveal every hidden surface of an object. Prism therefore estimates unseen geometry rather than recovering guaranteed ground truth.

Repository contents

File Purpose
prism_best.pt Trained V0.1 checkpoint
model.py Neural network architecture
inference.py Image-to-3D inference and GLB export
metrics.json Evaluation metrics and model configuration
requirements.txt Python dependencies
README.md Project documentation

Installation

Python 3.10 or newer is recommended.

pip install -r requirements.txt

Usage: download the model checkpoint

The checkpoint can be downloaded directly from Hugging Face.


# =====================================================================
#                  SUPERNOVA PRISM V0.1
#          ONE-CELL PUBLIC 3D RECONSTRUCTION SYSTEM
#
# Downloads -> Loads -> Verifies -> Asks -> Uploads -> Generates
# -> Visualizes -> Reports -> Downloads
# =====================================================================

import os
import sys
import io
import subprocess
import importlib.util
import warnings

warnings.filterwarnings("ignore")

# ---------------------------------------------------------------------
# CONFIGURATION
# ---------------------------------------------------------------------

REPO_ID = "Supernova11c/Supernova-Prism-V0.1"

import torch

DEVICE = "cuda" if torch.cuda.is_available() else "cpu"

# Previously measured held-out test-set metrics.
# These are model-level results, NOT per-image accuracy.
BENCHMARK = {
    "voxel_accuracy": 84.9680,
    "precision": 22.2508,
    "recall": 25.2429,
    "f1": 23.6526,
    "iou": 13.4125
}

print("=" * 72)
print("                 SUPERNOVA PRISM V0.1")
print("              SINGLE-IMAGE 3D RECONSTRUCTION")
print("=" * 72)

# ---------------------------------------------------------------------
# 1. INSTALL LIBRARIES
# ---------------------------------------------------------------------

print("\n[1/7] Preparing libraries...")

subprocess.check_call([
    sys.executable, "-m", "pip", "install", "-q",
    "huggingface_hub",
    "scikit-image",
    "trimesh",
    "matplotlib",
    "pillow"
])

import numpy as np
import trimesh
import matplotlib.pyplot as plt

from PIL import Image, ImageOps
from huggingface_hub import hf_hub_download
from skimage.measure import marching_cubes
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from google.colab import files

print("Libraries ready.")
print("Compute device:", DEVICE)

# ---------------------------------------------------------------------
# 2. DOWNLOAD PUBLISHED MODEL FILES
# ---------------------------------------------------------------------

print("\n[2/7] Downloading published model from Hugging Face...")

checkpoint_path = hf_hub_download(
    repo_id=REPO_ID,
    filename="prism_best.pt",
    repo_type="model"
)

architecture_path = hf_hub_download(
    repo_id=REPO_ID,
    filename="model.py",
    repo_type="model"
)

print("Checkpoint downloaded: YES")
print("Architecture downloaded: YES")
print(
    "Checkpoint size:",
    round(os.path.getsize(checkpoint_path) / (1024**2), 2),
    "MB"
)

# ---------------------------------------------------------------------
# 3. LOAD ARCHITECTURE AND CHECKPOINT
# ---------------------------------------------------------------------

print("\n[3/7] Loading published architecture and checkpoint...")

spec = importlib.util.spec_from_file_location(
    "published_prism_model",
    architecture_path
)

if spec is None or spec.loader is None:
    raise RuntimeError("Could not load published model.py.")

published_module = importlib.util.module_from_spec(spec)
sys.modules["published_prism_model"] = published_module
spec.loader.exec_module(published_module)

if not hasattr(published_module, "SupernovaPrism"):
    raise RuntimeError(
        "SupernovaPrism class was not found in model.py."
    )

PublishedPrism = published_module.SupernovaPrism

model = PublishedPrism().to(DEVICE)

checkpoint = torch.load(
    checkpoint_path,
    map_location=DEVICE,
    weights_only=True
)

if "model_state_dict" not in checkpoint:
    raise RuntimeError(
        "Invalid checkpoint: model_state_dict was not found."
    )

model.load_state_dict(
    checkpoint["model_state_dict"],
    strict=True
)

model.eval()

parameter_count = sum(
    p.numel() for p in model.parameters()
)

print("Architecture loaded: YES")
print("Checkpoint loaded: YES")
print("Strict state-dictionary loading: PASSED")
print("Parameter count:", f"{parameter_count:,}")

# ---------------------------------------------------------------------
# 4. MODEL VERIFICATION
# ---------------------------------------------------------------------

print("\n[4/7] Verifying model execution...")

dummy_input = torch.zeros(
    1, 3, 128, 128,
    dtype=torch.float32,
    device=DEVICE
)

with torch.inference_mode():
    dummy_output = model(dummy_input)

# Your published model returns (B, D, H, W).
# Also allow (B, C, D, H, W) for compatibility.
valid_shapes = [
    (1, 32, 32, 32),
    (1, 1, 32, 32, 32)
]

if tuple(dummy_output.shape) not in valid_shapes:
    raise RuntimeError(
        "Unexpected model output: "
        f"{tuple(dummy_output.shape)}"
    )

if not torch.isfinite(dummy_output).all().item():
    raise RuntimeError(
        "Model produced non-finite test output."
    )

print("Test inference: PASSED")
print("Output dimensions:", tuple(dummy_output.shape))
print("Model ready for image generation.")

# ---------------------------------------------------------------------
# 5. ASK USER TO START GENERATION
# ---------------------------------------------------------------------

print("\n" + "=" * 72)
print("                   PRISM GENERATION BLOCK")
print("=" * 72)

choice = input(
    "\nDo you want to generate a 3D model? (yes/no): "
).strip().lower()

if choice not in ["yes", "y"]:

    print("\nGeneration cancelled.")
    print("Published model was downloaded and verified.")

else:

    # ---------------------------------------------------------------
    # IMAGE UPLOAD
    # ---------------------------------------------------------------

    print("\nUpload ONE image of the object.")

    uploaded = files.upload()

    if not uploaded:
        raise RuntimeError("No image was uploaded.")

    image_name = next(iter(uploaded))

    try:
        original_image = Image.open(
            io.BytesIO(uploaded[image_name])
        )

        original_image = ImageOps.exif_transpose(
            original_image
        ).convert("RGB")

    except Exception as e:
        raise RuntimeError(
            "Could not read uploaded image: " + str(e)
        )

    print("Image uploaded:", image_name)
    print("Image dimensions:", original_image.size)

    # ---------------------------------------------------------------
    # IMAGE PREPROCESSING
    # ---------------------------------------------------------------

    print("\nPreprocessing image...")

    resized_image = original_image.resize(
        (128, 128),
        Image.Resampling.BILINEAR
    )

    image_array = (
        np.asarray(resized_image, dtype=np.float32) / 255.0
    )

    image_tensor = torch.from_numpy(
        image_array.transpose(2, 0, 1)
    ).unsqueeze(0).to(DEVICE)

    # ---------------------------------------------------------------
    # IMAGE-TO-3D INFERENCE
    # ---------------------------------------------------------------

    print("\nRunning Supernova Prism inference...")

    with torch.inference_mode():
        logits = model(image_tensor)
        probabilities = torch.sigmoid(logits)

    # ---------------------------------------------------------------
    # CORRECT OUTPUT DIMENSION HANDLING
    # ---------------------------------------------------------------

    if probabilities.ndim == 5:
        # Format: (B, C, D, H, W)
        probability_grid = probabilities[0, 0].cpu().numpy()

    elif probabilities.ndim == 4:
        # Actual published V0.1 format: (B, D, H, W)
        probability_grid = probabilities[0].cpu().numpy()

    else:
        raise RuntimeError(
            "Unsupported output dimensions: "
            f"{tuple(probabilities.shape)}"
        )

    if probability_grid.shape != (32, 32, 32):
        raise RuntimeError(
            "Unexpected voxel grid: "
            f"{probability_grid.shape}"
        )

    threshold = 0.5

    voxel_prediction = probability_grid >= threshold

    occupied_voxels = int(voxel_prediction.sum())
    total_voxels = int(voxel_prediction.size)

    occupancy_percent = (
        occupied_voxels / total_voxels
    ) * 100

    print("Inference completed.")
    print("Predicted grid:", probability_grid.shape)
    print("Occupied voxels:", occupied_voxels)
    print("Voxel occupancy:", f"{occupancy_percent:.2f}%")

    if occupied_voxels == 0:
        raise RuntimeError(
            "The model predicted an empty voxel grid."
        )

    if occupied_voxels == total_voxels:
        raise RuntimeError(
            "The model predicted a fully occupied voxel grid."
        )

    # ---------------------------------------------------------------
    # MARCHING CUBES: VOXELS TO 3D MESH
    # ---------------------------------------------------------------

    print("\nConverting predicted geometry into a 3D mesh...")

    vertices, faces, normals, values = marching_cubes(
        probability_grid.astype(np.float32),
        level=threshold
    )

    reconstructed_mesh = trimesh.Trimesh(
        vertices=vertices,
        faces=faces,
        vertex_normals=normals,
        process=True
    )

    if len(reconstructed_mesh.vertices) == 0:
        raise RuntimeError(
            "Generated mesh has no vertices."
        )

    if len(reconstructed_mesh.faces) == 0:
        raise RuntimeError(
            "Generated mesh has no faces."
        )

    # ---------------------------------------------------------------
    # EXPORT GLB
    # ---------------------------------------------------------------

    output_glb = (
        "/content/supernova_prism_reconstruction.glb"
    )

    output_png = (
        "/content/supernova_prism_visualization.png"
    )

    reconstructed_mesh.export(output_glb)

    glb_size = os.path.getsize(output_glb)

    print("3D reconstruction generated.")
    print("Vertices:", len(reconstructed_mesh.vertices))
    print("Faces:", len(reconstructed_mesh.faces))
    print("Watertight:", reconstructed_mesh.is_watertight)
    print("GLB size:", f"{glb_size:,}", "bytes")

    # ---------------------------------------------------------------
    # VISUALIZATION
    # ---------------------------------------------------------------

    print("\nPreparing visual representation...")

    fig = plt.figure(figsize=(14, 6))

    # Original image
    ax1 = fig.add_subplot(1, 2, 1)

    ax1.imshow(original_image)
    ax1.set_title("Original Uploaded Image")
    ax1.axis("off")

    # Reconstructed mesh
    ax2 = fig.add_subplot(1, 2, 2, projection="3d")

    triangles = reconstructed_mesh.vertices[
        reconstructed_mesh.faces
    ]

    surface = Poly3DCollection(
        triangles,
        alpha=0.85
    )

    ax2.add_collection3d(surface)

    minimum = reconstructed_mesh.vertices.min(axis=0)
    maximum = reconstructed_mesh.vertices.max(axis=0)

    center = (minimum + maximum) / 2

    radius = max(
        float((maximum - minimum).max()) / 2,
        1
    )

    ax2.set_xlim(
        center[0] - radius,
        center[0] + radius
    )

    ax2.set_ylim(
        center[1] - radius,
        center[1] + radius
    )

    ax2.set_zlim(
        center[2] - radius,
        center[2] + radius
    )

    ax2.set_box_aspect((1, 1, 1))
    ax2.set_title("Supernova Prism 3D Prediction")

    plt.tight_layout()

    plt.savefig(
        output_png,
        dpi=180,
        bbox_inches="tight"
    )

    plt.show()

    # ---------------------------------------------------------------
    # FINAL REPORT
    # ---------------------------------------------------------------

    print("\n")
    print("=" * 72)
    print("          SUPERNOVA PRISM V0.1 β€” GENERATION REPORT")
    print("=" * 72)

    print("\n[MODEL PUBLICATION VERIFICATION]")

    print("Repository:", REPO_ID)
    print("Checkpoint downloaded: YES")
    print("Architecture downloaded: YES")
    print("Checkpoint loaded: YES")
    print("Strict weight loading: PASSED")
    print("Numerical inference test: PASSED")

    print("\n[UPLOADED IMAGE]")

    print("Image:", image_name)
    print("Input resolution:", original_image.size)
    print("Model input: 128 x 128 RGB")

    print("\n[3D RECONSTRUCTION]")

    print("Inference completed: YES")
    print("3D mesh generated: YES")
    print("Voxel resolution: 32 x 32 x 32")
    print("Occupied voxels:", occupied_voxels)
    print("Voxel occupancy:", f"{occupancy_percent:.2f}%")
    print("Mesh vertices:", len(reconstructed_mesh.vertices))
    print("Mesh faces:", len(reconstructed_mesh.faces))
    print("Mesh watertight:", reconstructed_mesh.is_watertight)
    print("GLB generated: YES")
    print("GLB file size:", f"{glb_size:,}", "bytes")

    print("\n[MODEL BENCHMARK ACCURACY]")

    print("Held-out test-set results from Prism V0.1:")

    print(
        "Voxel accuracy:",
        f"{BENCHMARK['voxel_accuracy']:.4f}%"
    )

    print(
        "Precision:",
        f"{BENCHMARK['precision']:.4f}%"
    )

    print(
        "Recall:",
        f"{BENCHMARK['recall']:.4f}%"
    )

    print(
        "F1 score:",
        f"{BENCHMARK['f1']:.4f}%"
    )

    print(
        "Intersection over Union:",
        f"{BENCHMARK['iou']:.4f}%"
    )

    print("\n[IMAGE-SPECIFIC ACCURACY]")

    print("True per-image accuracy: NOT AVAILABLE")

    print(
        "Reason: no paired ground-truth 3D model "
        "was supplied for this image."
    )

    print(
        "Voxel occupancy and mesh statistics describe "
        "the prediction, not its accuracy."
    )

    print("\n[OUTPUT FILES]")

    print("3D model:", output_glb)
    print("Visualization:", output_png)

    print("\n" + "=" * 72)
    print("       SUPERNOVA PRISM β€” GENERATION COMPLETED")
    print("=" * 72)

    # ---------------------------------------------------------------
    # DOWNLOAD GENERATED FILES
    # ---------------------------------------------------------------

    print("\nDownloading generated 3D model...")

    files.download(output_glb)

    print("Downloading visualization...")

    files.download(output_png)

    print("\nBoth output files are ready.")

Usage: load the checkpoint manually

Download model.py and prism_best.pt from this repository into the same directory.

import torch
from model import SupernovaPrism

device = torch.device(
    "cuda" if torch.cuda.is_available() else "cpu"
)

checkpoint = torch.load(
    "prism_best.pt",
    map_location=device,
    weights_only=True
)

model = SupernovaPrism().to(device)

model.load_state_dict(
    checkpoint["model_state_dict"]
)

model.eval()

print("Supernova Prism V0.1 loaded.")

Usage: reconstruct an image

The easiest method is to use the included inference script. above code give a image upload directly from your code shell then the code will ask you file your upload and AI will generate 3d structure and you can download the file also full automatic

The script:

  1. Opens the input image.
  2. Resizes it to 128 Γ— 128.
  3. Loads the trained Prism network.
  4. Predicts voxel occupancy.
  5. Converts the predicted surface into a mesh.
  6. Exports a GLB file.

Threshold changes affect the extracted surface; they do not retrain the model.

Development roadmap

Planned future improvements include:

  • Improved geometry reconstruction.
  • Better foreground/background learning.
  • Higher-resolution 3D representations.
  • Evaluation on more diverse object categories.
  • Better generalization to real photographs.
  • Surface color and texture prediction.
  • More efficient model inference.
  • Future architecture scaling.

These are planned features, not capabilities of V0.1.

Dataset acknowledgement

This prototype used the Pix3D dataset:

https://huggingface.co/datasets/unstructured/pix3d

Dataset authors and source: https://pix3d.csail.mit.edu/

The dataset itself is not included in this model repository. Please consult the dataset's terms and attribution requirements before reusing its material.

Project

Supernova Prism

Version: 0.1.0
Organization: Supernova11c
Release type: Experimental research prototype

Future versions will build on this initial baseline.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support