I want to draw a propeller in 3D for my fluid dynamics lecture. I found a 3D model of a propeller that can be downloaded as a stl file.

I found a python library numpy-stl that can read and draw, with the help of matplotlib, the propeller.

enter image description here

My question is: how can I do to import and draw the polygons in asymptote (a python intermediate step is not a problem: no need to implement a stl parser in asymptote!).

  • 1
    Look at this previous question: tex.stackexchange.com/questions/195210/… Dec 8, 2015 at 14:32
  • 1
    @Arianna Indeed. Thanks! The asymtote obj library is the answer, provided you can convert stl file to obj file. Feel free to anwser here. I'll try to come with the whole figure when finished.
    – cjorssen
    Dec 8, 2015 at 14:43
  • You're welcome. I'm sorry, but now I can't figure out how to convert the .stl file in the requested format. Probably you have to use a pre-processing tool or write some code. Dec 8, 2015 at 15:09
  • When I download the stl file you link to, it renders as a propellor with only three blades. Dec 10, 2015 at 5:11

1 Answer 1


Actually, an ascii stl file is so simple it's easy to write an Asymptote script to read it directly. Note, however, that the code below is too simple to offer useful feedback in case the stl file has errors.

settings.outformat = "png";
settings.render = 8;
import three;

struct stringpointer { string s; }

surface readstlfile(string filename, stringpointer returnsurfacename=null, bool ascii=true) {
  assert(ascii, "Reading binary stl files not implemented.");
  file stlfile = input(filename).word();  // Set up a file to read whitespace-delimited items.
  string nextword;
  real x, y, z;
  nextword = stlfile;  // Reading from a file is done by assignment in Asymptote.
  assert(nextword == "solid", filename + " is not a well-formed stl file.");
  string name = stlfile;
  if (returnsurfacename != null) returnsurfacename.s = name;

  surface toreturn;

  while (!eof(stlfile)) {
    nextword = stlfile;
    if (nextword == "endsolid") break;
    else if (nextword == "facet") {

      nextword = stlfile;
      assert(nextword == "normal");

      x = stlfile; y = stlfile; z = stlfile;
      triple normal = (x, y, z);

      nextword = stlfile; assert(nextword == "outer");
      nextword = stlfile; assert(nextword == "loop");
      triple[] vertices = new triple[3];
      for (int i = 0; i < 3; ++i) {
        nextword = stlfile; assert(nextword == "vertex");
        x = stlfile; y = stlfile; z = stlfile;
        vertices[i] = (x,y,z);
      nextword = stlfile; assert(nextword == "endloop");
      nextword = stlfile; assert(nextword == "endfacet");

      patch triangle = patch(vertices[0] -- vertices[1] -- vertices[2] -- cycle);
      triangle.normals = array(4, value=normal);
    } else assert(false, filename + " is not a well-formed stl file.");
  assert(nextword == "endsolid", filename + " does not end correctly.");
  nextword = stlfile;
  assert(nextword == name, filename + " does not end with the solid's correct name " + name);
  return toreturn;

currentprojection = perspective(-30, 10, 60);
surface propeller = readstlfile("propellerbetter.stl");
draw(propeller, blue);


  • Wow! Thanks a lot (you clearly deserve a bounty as soon as it is possible).
    – cjorssen
    Dec 10, 2015 at 7:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .