File size: 2,409 Bytes
b40f1ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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;
  }
}