Why is my tube geometry faceless?

Hello all,

I am trying to create a very simple tube from a QuadraticBezierCurve. I get an error: “faceless geometries are not supported” and nothing is being rendered. I believe I have followed the example of documentation rigidly enough. Is there anyone who can tell me what I am doing wrong here please?

const config = {
  angle: 45, // in degrees
  curvature: 0.5, // value between 0 and 1, translates to the Y of bezier control point
  radius: 1,
  radialSegments: 32,
  lengthSegments: 100,
  length: 10, // linear distance between start and end points of the curve
  color: 0x5E2100,
  position: new THREE.Vector3(0, 0, 0)
}

// the lines below translate degrees to radians
const endPointX = Math.cos(config.angle * Math.PI / 180) * config.length;
const endPointY = Math.sin(config.angle * Math.PI / 180) * config.length;

const curve = new THREE.QuadraticBezierCurve(
  new THREE.Vector2(0, 0),
  new THREE.Vector2(0, config.length * config.curvature),
  new THREE.Vector2(endPointX, endPointY)
);

const geometry = new THREE.TubeGeometry(
  curve,
  config.lengthSegments,
  config.radius,
  config.radialSegments,
  true
);
const material = new THREE.MeshLambertMaterial({color: config.color});
const TubeObject = new THREE.Mesh(geometry, material);

scene.add( TubeObject );

Here’s a codepen where the error is reproduced:

Thank you very much for your kind help!

TubeGeometry relies on Curve.computeFrenetFrames() which only works with 3D curve definitions. So try it with QuadraticBezierCurve3 instead.

Live demo: https://jsfiddle.net/3csp7v95/2/

2 Likes

Wow, thank you for your quick response.

Yes indeed this solves the error. Any idea why the tube doesn’t look right though? It’s radius seems to change across the path, as if only one side of the circle is interpolated along the curve, while the other side just follows a straight line.

It’s because the last parameter of the tube geometry is set to true
The docs says:
closed — Boolean Is the tube open or closed, default is false
So, set this parameter to false of simply remove it.
Like this:

const geometry = new THREE.TubeBufferGeometry(
  curve,
  config.lengthSegments,
  config.radius,
  config.radialSegments
);
2 Likes

Gotcha. I believed this parameter was there to apply caps to each side of the tube, not join them with one another. My mistake.

So in order to get what I want (a tube but with caps on both ends), I will have to resort to one of the following:

  • bend a cylinder;
  • extrude a circle along a bezier curve;

Am I right? Are there better options I don’t know about yet?

Take a look at this topic: End Caps of TubeGeometry

1 Like

I’m fascinated by how responsive this community is. Thanks a million @Mugen87 @prisoner849 !

2 Likes