Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
1  
Have you tried exporting in X3D formats? –  kguler Oct 7 '12 at 10:55
    
Hi! Welcome to the site! Perhaps you could provide a minimal working example of your 3d graphics. –  belisarius Oct 7 '12 at 10:55
    
You can't use NOFF? –  J. M. Oct 7 '12 at 10:57
    
Thanks for the tips! I hadn't tried X3D or NOFF before. –  Dale Roberts Oct 7 '12 at 11:03
    
Dale : NOFF Stores a collection of planar polygons with possibly shared vertices and vertex normal data. –  belisarius Oct 7 '12 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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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