import type { Dataset, DataItem, FullComparisonResult, FullComparisonSourceItem, Modality } from '../types'; /** * Mocks the backend's full comparison process for client-side dataset generation. * This creates plausible cross-modal matches for a given dataset. * @param dataset The dataset to process. * @returns A FullComparisonResult object with mock data. */ const performFullComparison = (dataset: Omit): FullComparisonResult => { const result: FullComparisonResult = { images: [], texts: [], meshes: [], }; const allItems: { item: DataItem, modality: Modality }[] = [ ...dataset.data.images.map(item => ({ item, modality: 'image' as Modality })), ...dataset.data.texts.map(item => ({ item, modality: 'text' as Modality })), ...dataset.data.meshes.map(item => ({ item, modality: 'mesh' as Modality })), ]; const generateMatches = (sourceItem: DataItem): FullComparisonSourceItem['matches'] => { const matches: FullComparisonSourceItem['matches'] = { image: [], text: [], mesh: [], }; const sourceIndex = parseInt(sourceItem.id.split('_')[1]); allItems.forEach(({ item: targetItem, modality }) => { if (sourceItem.id === targetItem.id) { return; // Don't match an item to itself } const targetIndex = parseInt(targetItem.id.split('_')[1]); let confidence = 0; if (sourceIndex === targetIndex) { // High confidence for corresponding items confidence = 0.9 + Math.random() * 0.09; } else if (Math.abs(sourceIndex - targetIndex) <= 3) { // Lower confidence for nearby items confidence = 0.2 + Math.random() * 0.2; } else { // Very low confidence for distant items confidence = Math.random() * 0.1; } if (confidence > 0.05 && matches[modality]) { matches[modality]!.push({ item: targetItem.name, confidence: confidence, }); } }); // Sort and take top 5 for each modality for (const key in matches) { const modality = key as Modality; if (matches[modality]) { matches[modality] = matches[modality]! .sort((a, b) => b.confidence - a.confidence) .slice(0, 5); } } return matches; }; result.images = dataset.data.images.map(item => ({ source: item.name, matches: generateMatches(item), })); result.texts = dataset.data.texts.map(item => ({ source: item.name, matches: generateMatches(item), })); result.meshes = dataset.data.meshes.map(item => ({ source: item.name, matches: generateMatches(item), })); return result; }; const generateCubeStl = (): string => `solid cube facet normal 0 0 -1 outer loop vertex 0 0 0 vertex 1 0 0 vertex 0 1 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 1 1 0 vertex 0 1 0 vertex 1 0 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 0 1 vertex 0 1 1 vertex 1 0 1 endloop endfacet facet normal 0 0 1 outer loop vertex 1 1 1 vertex 1 0 1 vertex 0 1 1 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 0 0 vertex 0 0 1 vertex 1 0 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 1 0 1 vertex 1 0 0 vertex 0 0 1 endloop endfacet facet normal 0 1 0 outer loop vertex 0 1 0 vertex 1 1 0 vertex 0 1 1 endloop endfacet facet normal 0 1 0 outer loop vertex 1 1 1 vertex 0 1 1 vertex 1 1 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 0 0 vertex 0 1 0 vertex 0 0 1 endloop endfacet facet normal -1 0 0 outer loop vertex 0 1 1 vertex 0 0 1 vertex 0 1 0 endloop endfacet facet normal 1 0 0 outer loop vertex 1 0 0 vertex 1 0 1 vertex 1 1 0 endloop endfacet facet normal 1 0 0 outer loop vertex 1 1 1 vertex 1 1 0 vertex 1 0 1 endloop endfacet endsolid cube`; const generateItems = (type: 'image' | 'text' | 'mesh', count: number): DataItem[] => { const items: DataItem[] = []; for (let i = 1; i <= count; i++) { const id = `${type}_${String(i).padStart(3, '0')}`; let content = ''; let name = ''; switch (type) { case 'image': name = `${id}.jpg`; content = `https://picsum.photos/seed/${id}/400/300`; break; case 'text': name = `${id}.txt`; content = `This is the text description for object number ${i}. It details the visual characteristics, material properties, and potential use cases of the corresponding 3D model and image.`; break; case 'mesh': name = `${id}.stl`; content = generateCubeStl(); break; } items.push({ id, name, content }); } return items; }; export const generateMockDataset = (name: string, fileCount: number): Dataset => { const baseDataset: Omit = { id: crypto.randomUUID(), name, uploadDate: new Date(), data: { images: generateItems('image', fileCount), texts: generateItems('text', fileCount), meshes: generateItems('mesh', fileCount), }, }; // Pre-compute the full comparison results for the mock dataset const fullComparison = performFullComparison(baseDataset); return { ...baseDataset, fullComparison, processingState: 'processed', processingProgress: 100, }; };