I would like to export an arbitrary Graphics3D object as a text file containing:

  • list of vertices
  • vertex normals
  • triangle faces

Export["foo.obj", g], Export["foo.pov", g], and Export["foo.stl", g] are all unsatisfactory as they lack the VertexNormal data.

I started writing my own exporter but it's getting a bit painful as it seems there is no easy way to convert GraphicsComplex object containing Polygons of order greater than 3 and converting them to triangles without recreating a triangle tessellation from scratch.

Has anyone done this before and would like to share their code? Or is there an undocumented function I could use?

Here is an example Graphics3D:

g = RegionPlot3D[(x^2 + y^4 + z^4) - (x^3 + y^2 + z) > 1/2, {x, -1, 1}, {y, -1, 1}, {z, -1, 1}]

Mathematica graphics

  • 1
    $\begingroup$ Have you tried exporting in X3D formats? $\endgroup$
    – kglr
    Oct 7, 2012 at 10:55
  • $\begingroup$ Hi! Welcome to the site! Perhaps you could provide a minimal working example of your 3d graphics. $\endgroup$ Oct 7, 2012 at 10:55
  • $\begingroup$ You can't use NOFF? $\endgroup$ Oct 7, 2012 at 10:57
  • $\begingroup$ Thanks for the tips! I hadn't tried X3D or NOFF before. $\endgroup$ Oct 7, 2012 at 11:03
  • $\begingroup$ Dale : NOFF Stores a collection of planar polygons with possibly shared vertices and vertex normal data. $\endgroup$ Oct 7, 2012 at 11:06

1 Answer 1


As already stated in the comments, you can surely find a 3d export format which stores the normals too. On the other hand, I believe the only information you are missing is, that there is a function Normal (which has nothing to do with the normals).

This function transforms a GraphicsComplex back to a form where all polygons are stored explicitly. Therefore, you take you Graphics3D, apply Normal and then you can via e.g. Cases and some rules extract all information you like.

OK, let's make this answer worth many upvotes: The triangle faces of your graphics are the first argument in all the Polygon calls after you applied Normal. The vertices are just in the first argument to GraphicsComplex. The normals are supplied as optional argument to Polygon.

Using TagSet to build a simple access to those information

Faces /: gr_Graphics3D.Faces := 
 Cases[Normal[gr], Polygon[__], Infinity] /. Polygon[pts_, ___] :> pts;
Vertices /: gr_Graphics3D.Vertices := 
  gr[[1, 1]] /; gr[[1, 0]] === GraphicsComplex;
Normals /: gr_Graphics3D.Normals := 
 Cases[Normal[gr], Polygon[__], Infinity] /. 
  Polygon[pts_, VertexNormals -> normals_] :> {pts, normals}

This should work in basic examples. Please don't try to draw this with a full detailed graphics. Your system may explode.

gr = RegionPlot3D[(x^2 + y^4 + z^4) - (x^3 + y^2 + z) > 1/2, {x, -1, 
   1}, {y, -1, 1}, {z, -1, 1}, MaxRecursion -> 0, PlotPoints -> 5, 
  Mesh -> All];
drawNormals[{pts_, normals_}] := {Arrow[Tube[#, 0.01]] & /@ 
   Transpose[{pts, pts + .5 normals}]};

(* And here comes the simple access: *)
Graphics3D[{Polygon /@ (gr.Faces), Red, drawNormals /@ (gr.Normals), 
  Blue, Sphere[#, 0.05] & /@ (gr.Vertices)}]

Mathematica graphics


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.