为边缘生成3D模型/绘制圆柱体的套接字连接

时间:2014-11-10 12:54:23

标签: vector 3d processing 3d-modelling

我有这个Processing sketch,其中我正在尝试加载模型(.stl或.obj)并为每个边缘交叉点构建参数套接字连接。这些将是3D打印的,适当规格的杆将插入其孔中。

我已经能够在顶点绘制球体(在模型上的红色中),但是我无法生成绿色插座甚至棒在粉红色Low Poly Whale - How do I build the green sockets and the pink rods?

我可以得到模型边缘的坐标:

id: 0 0 {-25.805634,-23.170607,13.6315975} -> 1 {-16.868328,-10.148323,6.785455} f: 2
id: 1 1 {-16.868328,-10.148323,6.785455} -> 2 {-52.833824,-10.148322,16.799314} f: 2
....

通过这些,我可以绘制Line3D(Vec3D a, Vec3D b)toxi.geom.Line3D

但我不想要Line3D,我需要在它们之间画一个圆柱体,从而得到杆。要将线条拉伸或膨胀到3D体积,如果您要......

WETriangleMesh whale, redmesh;

[bla bla bla]
然后在void setup()内:

for(WingedEdge e : whale.edges.values()) {
    edges.add(e);
    drawSocket(e);
}

void drawSocket(WingedEdge e) {
    // draw size 2 balls at model vertices
    Sphere ball = new Sphere(e.a, 2);
    // convert to mesh at resolution 6 and add to redmesh
    ball.toMesh(redmesh, 6);
}

然后在void draw()内:

// draw the mesh with the whale
gfx.mesh(whale);
// color the next mesh red
fill(255,0,0);
// draw the mesh with the spheres
gfx.mesh(redmesh);

我发现没有3D形状类可以从Vec3D a, Vec3D b参数构造到位。也许创建一个类来使用这两个坐标?

如果构建形状太难了,那么可能是变换吗? pushMatrix() translate()popMatrix()

编辑:解决,见下文。谢谢!

Low Poly Whale - Rod-and-socketed

1 个答案:

答案 0 :(得分:1)

诀窍是将套接字转换为边缘中的一个顶点,并使它们面向相反的顶点。这是一个处理函数,它将像你的鲸鱼一样使用WETriangleMesh并返回点,插座和杆的网格。我写了一个更完整的例子here

float socketLength = 30;
float socketRadius = 6;
float rodRadius = 5;
float pointRadius = 10.0;
int resolution = 10;

WETriangleMesh[] convertMeshToRodSockets(WETriangleMesh inMesh) {
  WETriangleMesh[] meshes = new WETriangleMesh[3];

  meshes[0] = new WETriangleMesh();
  meshes[1] = new WETriangleMesh();
  meshes[2] = new WETriangleMesh();

  for (Vertex vert : inMesh.getVertices ()) {
    //Sphere points
    Sphere sphere = new Sphere(vert, pointRadius);
    WETriangleMesh sphereMesh = new WETriangleMesh();
    sphere.toMesh(sphereMesh, resolution);
    meshes[2].addMesh((WETriangleMesh)sphereMesh);
  }

  for (WingedEdge edge : inMesh.edges.values ()) {
    Vec3D pointA = edge.a;
    Vec3D pointB = edge.b;

    //Meshes to store socket shapes
    ZAxisCylinder socket;
    ZAxisCylinder rod;
    WETriangleMesh socketAMesh = new WETriangleMesh();
    WETriangleMesh socketBMesh = new WETriangleMesh();
    WETriangleMesh rodMesh = new WETriangleMesh();

    float distanceBetweenPoints = pointA.distanceTo(pointB);

    //Create sockets and point towards target
    socket = new ZAxisCylinder(new Vec3D(0.0, 0.0, 0.0), socketRadius, socketLength);
    socket.toMesh(socketAMesh, resolution, 0.0);
    socketAMesh.pointTowards(pointB.sub(pointA));

    //Translate socket to start from the center of the point
    socketAMesh.translate( offsetTranslation(pointA, pointB, socketLength ));

    //Create second socket and look in the opposite direction to face the start point
    socket.toMesh(socketBMesh, resolution, 0.0);
    socketBMesh.pointTowards(pointA.sub(pointB));
    socketBMesh.translate( offsetTranslation(pointB, pointA, socketLength ));

    //Create rod with a length matching the distance between the two points
    rod = new ZAxisCylinder(new Vec3D(0.0, 0.0, 0.0), rodRadius, distanceBetweenPoints);
    rod.toMesh(rodMesh, resolution, 0.0);
    rodMesh.pointTowards(pointB.sub(pointA));

    //Translate the rod to the midpoint of both points
    rodMesh.translate(pointA.add(pointB).scale(0.5));

    //Combine meshes together
    meshes[0].addMesh((WETriangleMesh)rodMesh);
    meshes[1].addMesh((WETriangleMesh)socketAMesh);
    meshes[1].addMesh((WETriangleMesh)socketBMesh);
  }

  return meshes;
}

//Function to return a vector that is slightly offset by a length.
Vec3D offsetTranslation(Vec3D a, Vec3D b, float l) {
  return a.interpolateTo(b, (l*0.5 / a.distanceTo(b)) );
}