neotwin-api / models /langsplat_query.py
1qwsd's picture
deploy: NeoTwin backend v1.0 - FastAPI + Gemini AI
d1a1edf
Raw
History Blame Contribute Delete
1.35 kB
"""LangSplat Query Engine - Semantic 3D search"""
import torch
import numpy as np
from pathlib import Path
from core.config import settings
class LangSplatQuery:
def __init__(self):
self.clip_features = None
self.gaussian_positions = None
self.loaded = False
def load_scene(self, scene_path: str):
scene_file = Path(scene_path)
if not scene_file.exists():
raise FileNotFoundError(f"Scene file not found: {scene_path}")
data = torch.load(scene_file, map_location="cpu")
self.clip_features = data.get("clip_features")
self.gaussian_positions = data.get("positions")
self.loaded = True
def search(self, text_embedding: np.ndarray, top_k: int = 500):
if not self.loaded:
raise RuntimeError("Scene not loaded. Call load_scene() first.")
text_tensor = torch.from_numpy(text_embedding).float()
similarities = torch.matmul(self.clip_features, text_tensor.T).squeeze()
top_indices = similarities.topk(top_k).indices.tolist()
centroid = self.gaussian_positions[top_indices].mean(dim=0).tolist()
return {
"indices": top_indices,
"centroid": {"x": centroid[0], "y": centroid[1], "z": centroid[2]},
"count": len(top_indices)
}
langsplat_query = LangSplatQuery()