12

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/… – Arianna Angeletti Dec 8 '15 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 '15 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. – Arianna Angeletti Dec 8 '15 at 15:09
  • When I download the stl file you link to, it renders as a propellor with only three blades. – Charles Staats Dec 10 '15 at 5:11
16
+100

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;
size(20cm);

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);
      toreturn.s.push(triangle);

    } 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);

propeller

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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