### Define nonconvex polyhedron in SageMath and export to STL

Here is an example of constructing a non-convex polyhedron and exporting it to STL.

Define a list of vertices given as triples for points in $\mathbb{R}^3$.

```
v = [( 1, 0, 0), ( 2, 0, -1), ( 3, 0, 0), ( 2, 0, 1),
( 0, 1, 0), ( 0, 2, -1), ( 0, 3, 0), ( 0, 2, 1),
(-1, 0, 0), (-2, 0, -1), (-3, 0, 0), (-2, 0, 1),
( 0, -1, 0), ( 0, -2, -1), ( 0, -3, 0), ( 0, -2, 1)]
```

Define a list of faces: each face is a tuple of indices
where each index refers to a vertex in the list of vertices.

```
f = [(4*k + j, 4*((k+1)%4) + j, 4*((k+1)%4) + (j+1)%4, 4*k + (j+1)%4)
for k in range(4) for j in range(4)]
```

Now define a polyhedron using the function `polygons3d`

,
which takes as arguments a list of vertices and a list of faces
as above. In addition, use `threejs_flat_shading=True`

for
correct shading in the Three.js rendering.

```
torus = polygons3d(points=v, faces=f, threejs_flat_shading=True)
```

View the polyhedron.

```
torus.show(frame=False)
```

Save it in STL format (this saves to binary STL).

```
torus.save('diamond_torus.stl')
```

To get the ascii STL:

```
torus_ascii_stl = torus.stl_ascii_string()
print(torus_ascii_stl)
```

To save the polyhedron to ascii STL, write that ascii string to a file:

```
with open('diamond_torus_ascii.stl', 'w') as f:
f.write(torus_ascii_stl)
```

Note also that Blender can be made to use SageMath's Python,
so Python scripting in Blender can use all the power of Sage.