"Faces are sorted back-to-front in a very approximate way according to the Z centroid".
In certain cases, this can lead to showing the back face and hiding the front face because the centroid position is not sufficient for figuring out the Z order of triangles.
Other than this minor issue, it's a great implementation.
Maybe I should compare min positions rather than centroids, but I don't think that would fix those cases.
I think the only real fix involves splitting up the polygons for the failure cases, which seems complex.
Handling intersecting polygons, as you said, is a bit more complex, but for overlapping polygons it's possible to find the Z-order robustly by computing the intersections with the line of sight.
I recently ran into similar problems to be solved in Python, because I am trying to build a replacement for OpenSCAD by duct-taping together various Python packages. Shapely is quite useful for 2D geometry (like intersection and stuff). PyMesh is extremely useful for 3D meshes, but hard to build.
There are some non photorealistic rendering (NPR) options for Blender, many of them implemented in Python. I don't know if they can output SVG data currently.
ThreeJs has an SVG engine, meaning a backend that outputs SVG.
I am very interested in this.
Currently I am trying to reimplement the "construct" part with Pymesh and Shapely, but I haven't published it yet.
One of the problems for me is that I am sort of stumbling into this "CAD" thing from a coding perspective. CAD programs like Fusion 360° or FreeCAD seem a bit too complicated for me, and through my grappling with the concepts I am reinventing some concepts/tools.
Particularly I want to develop 3D printed objects the same way I would do data science: Start with Jupyter notebooks, iterate, maybe end up with parametric Python scripts.
It's not necessarily going to be as efficient (or rather, as hardware-acceleratable) as computing Z at each point and maintaining a Z-buffer, but that would assume a fixed resolution.