Spaces:
Running
Running
| import { Pattern, CreaseDef } from './patterns'; | |
| export function parseFoldFile(jsonStr: string, filename: string): Pattern | null { | |
| try { | |
| const data = JSON.parse(jsonStr); | |
| if (!data.vertices_coords || !data.faces_vertices) { | |
| throw new Error("Missing required FOLD fields (vertices_coords, faces_vertices)"); | |
| } | |
| // Extract vertices and find bounding box for normalization | |
| let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity; | |
| const rawVertices: [number, number][] = data.vertices_coords.map((v: number[]) => { | |
| const x = v[0]; | |
| const y = v[1]; | |
| minX = Math.min(minX, x); | |
| maxX = Math.max(maxX, x); | |
| minY = Math.min(minY, y); | |
| maxY = Math.max(maxY, y); | |
| return [x, y]; | |
| }); | |
| const width = maxX - minX; | |
| const height = maxY - minY; | |
| // Scale to fit nicely in the view (from -1 to 1) | |
| const scale = 2 / Math.max(width, height, 0.001); | |
| const cx = (minX + maxX) / 2; | |
| const cy = (minY + maxY) / 2; | |
| const vertices: [number, number][] = rawVertices.map(v => [ | |
| (v[0] - cx) * scale, | |
| (v[1] - cy) * scale | |
| ]); | |
| // Extract and triangulate faces | |
| const faces: [number, number, number][] = []; | |
| data.faces_vertices.forEach((face: number[]) => { | |
| if (face.length === 3) { | |
| faces.push([face[0], face[1], face[2]]); | |
| } else if (face.length > 3) { | |
| // Simple fan triangulation for convex polygons | |
| for (let i = 1; i < face.length - 1; i++) { | |
| faces.push([face[0], face[i], face[i + 1]]); | |
| } | |
| } | |
| }); | |
| // Extract creases | |
| const creases: CreaseDef[] = []; | |
| if (data.edges_vertices && data.edges_assignment) { | |
| data.edges_vertices.forEach((edge: [number, number], i: number) => { | |
| const assignment = data.edges_assignment[i]; | |
| if (assignment === 'M' || assignment === 'm') { | |
| creases.push({ edge, type: 'mountain' }); | |
| } else if (assignment === 'V' || assignment === 'v') { | |
| creases.push({ edge, type: 'valley' }); | |
| } else if (assignment === 'F' || assignment === 'f') { | |
| creases.push({ edge, type: 'flat' }); | |
| } | |
| }); | |
| } | |
| return { | |
| id: 'custom-' + Date.now(), | |
| name: filename.replace('.fold', ''), | |
| vertices, | |
| faces, | |
| creases | |
| }; | |
| } catch (e) { | |
| console.error("Error parsing FOLD file:", e); | |
| return null; | |
| } | |
| } | |