在 Asymptote 中渲染 stl 文件

在 Asymptote 中渲染 stl 文件

我想为我的流体动力学讲座绘制一个 3D 螺旋桨。我找到了一个螺旋桨的 3D 模型可以下载作为一个stl文件

我找到了一个python库numpy-stl可以在 matplotlib 的帮助下读取和绘制螺旋桨。

在此处输入图片描述

我的问题是:如何在渐近线中导入和绘制多边形(python 中间步骤不是问题:不需要在渐近线中实现 stl 解析器!)。

答案1

实际上,asciistl文件非常简单,因此很容易编写 Asymptote 脚本来直接读取它。但请注意,下面的代码太简单了,无法在文件stl有错误时提供有用的反馈。

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

螺旋桨

相关内容