Skip to content

mlx3d.utils

mlx3d.utils

cube(size=2.0)

Axis-aligned cube centered at the origin with edge length size.

Source code in src/mlx3d/utils/primitives.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def cube(size: float = 2.0) -> Meshes:
    """Axis-aligned cube centered at the origin with edge length ``size``."""
    s = size / 2.0
    verts = mx.array(
        [
            [-s, -s, -s],
            [s, -s, -s],
            [s, s, -s],
            [-s, s, -s],
            [-s, -s, s],
            [s, -s, s],
            [s, s, s],
            [-s, s, s],
        ]
    )
    faces = mx.array(
        [
            [0, 2, 1],
            [0, 3, 2],
            [4, 5, 6],
            [4, 6, 7],
            [0, 1, 5],
            [0, 5, 4],
            [2, 3, 7],
            [2, 7, 6],
            [1, 2, 6],
            [1, 6, 5],
            [3, 0, 4],
            [3, 4, 7],
        ],
        dtype=mx.int32,
    )
    return Meshes([verts], [faces])

ico_sphere(level=2, radius=1.0)

Unit icosphere obtained by subdividing an icosahedron level times.

Source code in src/mlx3d/utils/primitives.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def ico_sphere(level: int = 2, radius: float = 1.0) -> Meshes:
    """Unit icosphere obtained by subdividing an icosahedron ``level`` times."""
    verts, faces = _icosahedron()
    for _ in range(level):
        edge_mid: dict[tuple[int, int], int] = {}
        new_faces = []
        verts_list = verts.tolist()

        def midpoint(a: int, b: int) -> int:
            key = (min(a, b), max(a, b))
            if key not in edge_mid:
                m = (np.array(verts_list[a]) + np.array(verts_list[b])) / 2.0
                m /= np.linalg.norm(m)
                edge_mid[key] = len(verts_list)
                verts_list.append(m.tolist())
            return edge_mid[key]

        for a, b, c in faces:
            ab, bc, ca = midpoint(a, b), midpoint(b, c), midpoint(c, a)
            new_faces += [[a, ab, ca], [b, bc, ab], [c, ca, bc], [ab, bc, ca]]
        verts = np.array(verts_list)
        faces = np.array(new_faces, dtype=np.int64)

    return Meshes(
        [mx.array((verts * radius).astype(np.float32))],
        [mx.array(faces.astype(np.int32))],
    )

torus(r=0.5, R=1.0, sides=16, rings=32)

Torus with tube radius r and center radius R.

Source code in src/mlx3d/utils/primitives.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def torus(r: float = 0.5, R: float = 1.0, sides: int = 16, rings: int = 32) -> Meshes:
    """Torus with tube radius ``r`` and center radius ``R``."""
    verts = []
    for i in range(rings):
        phi = 2.0 * math.pi * i / rings
        for j in range(sides):
            theta = 2.0 * math.pi * j / sides
            x = (R + r * math.cos(theta)) * math.cos(phi)
            y = r * math.sin(theta)
            z = (R + r * math.cos(theta)) * math.sin(phi)
            verts.append([x, y, z])
    faces = []
    for i in range(rings):
        for j in range(sides):
            a = i * sides + j
            b = i * sides + (j + 1) % sides
            c = ((i + 1) % rings) * sides + j
            d = ((i + 1) % rings) * sides + (j + 1) % sides
            faces += [[a, c, b], [b, c, d]]
    return Meshes(
        [mx.array(np.asarray(verts, dtype=np.float32))],
        [mx.array(np.asarray(faces, dtype=np.int32))],
    )