Table of contents

The basic meshes you've seen up until now have an expected shape : when you create a sphere mesh, you expect to see a spherical shape. The same goes for a box mesh, a torus, a cylinder, etc.

There is another kind of mesh whose final shapes aren't fixed. Their final shape depends upon some parameters. So we call these meshes "Parametric Shapes".

The ribbon is a very simple and versatile shape. As it is very elementary, you can model almost any shape using a ribbon or many merged ribbons.

```
CreateRibbon(name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation);
```

**name**: string.**pathArray**: an array of paths.

As explained in the Basic Elements section, the ribbon is the surface between two, or more, paths.

A path is a series of successive points in space (Vector3).

So a path can be designed by many ways : you can set points manually, import them from some set of data (json, etc), compute them with some maths function ... or even a bit of all of this.

The javascript representation of a path is simply an array of Vector3.

A path must have at least two points (four points if you provide a single path). In order to create a ribbon, you just have to pass an array of paths. This array can contain only one path and in this case, the*offset*parameter is used.**closeArray**:*default False*boolean, if true an extra set of triangles is constructed between the last path and the first path of pathArray. example : https://www.babylonjs-playground.com/#295H7U -

Here we populate an array called*paths*with many path arrays.

Each*path*array is populated itself with Vector3 along a Bézier curve. Anything else could have been chosen for this example, but I love this strange shape.

Before dealing with the ribbon, we just display each path with the*CreateLines()*method so we can figure out what these paths look like. As we can see, the curves are side by side around an incomplete circle.

If we apply this*paths*array to a ribbon mesh, we get this : https://www.babylonjs-playground.com/#295H7U#1 -

You can see that a surface is constructed between each*path*as expected.

Here is the same with a plain material ans still the*paths*displayed : https://www.babylonjs-playground.com/#295H7U#2 -

If we set*closeArray*to*true*, the missing surface between the first and the last*paths*is then constructed : https://www.babylonjs-playground.com/#295H7U#3 -

The mesh becomes then a real closed volume and the light reflects in a continuous way along its surface.

**closePath**:*default False*boolean, if true the last point of each path of*pathArray*is joined to the first point of this same path.

example : https://www.babylonjs-playground.com/#1TDTHJ -

Here is some kind of unclosed tubular ribbon. It is made with only two paths*path1*and*path2*each following an incomplete circle.

If we set the*closePath*to*true*( https://www.babylonjs-playground.com/#1TDTHJ#1 -

), you can notice that*path1*and*path2*are now closed and two triangles are added between the beginning and the end of each path.

If we give this ribbon a plain material, you can then notice it is really closed as the normals are computed to reflect the light in a continuous way : https://www.babylonjs-playground.com/#1TDTHJ#2 -

Here is the example of the former*closeArray*parameter with*closeArray*and*closePath*set to true : https://www.babylonjs-playground.com/#295H7U#4 -

**offset**:*default half size of the pathArray length*, mandatory only for pathArray containing a single path.

example : https://www.babylonjs-playground.com/#1W5VJN#14 -

Here is a single path*path1*, a simple helix. It is just shown with*CreateLines()*.

We can populate the*pathArray*with this single path :*[path1]*

In this case, the ribbon will be constructed by joining each point of the path to another point located*offset*positions further in the path. Example :*offset = 10*, the point 1 will be joined to the point 11, the point 2 to the point 12, etc.

If you don't provide an*offset*value, or if you provide a value greater than half of_path1 length, the*offset*will be set by default to half of*path1*length.

Back to our example : https://www.babylonjs-playground.com/#1W5VJN#15 -*Offset*is set to 20 here.

Let's change it to 5 : https://www.babylonjs-playground.com/#1W5VJN#16 -

So this parameter allows you to construct different meshes from a same single path.

So playing with*offset*,*closeArray*, or other parameters, you can easily get volumic shapes, even with a single path : https://www.babylonjs-playground.com/#1W5VJN#17 -

**updatable**: boolean, true if the ribbon could updated after creation**sideOrientation**:*default DEFAULTSIDE*possible other values :- BABYLON.Mesh.FRONTSIDE
- BABYLON.Mesh.BACKSIDE
- BABYLON.Mesh.DOUBLESIDE

see full explanation about*sideOrientation*parameter in`Basic elements`

If you need more details about ribbon uses, you might want to read the Ribbon Tutorial part.

Basically a tube is just a curved (or not) cylinder.

However it can be far more than just a cylinder if you consider it as a parametric shape.

Example with a simple cos/sin path : https://www.babylonjs-playground.com/#LG3GS#8 -

```
var tube = BABYLON.Mesh.CreateTube(name, path, radius, tessellation, radiusFunction, cap, scene, updatable?, sideOrientation);
```

**name**: string.**path**: an array of successive Vector3. It represents the path the tube will be constructed along. This path is the central axis of the tube. This array must have at least two Vector3. The first point is the start of the tube and the last point is the end of the tube. So having only two points, you get a simple cylinder.

This path can be filled as you like : manually, by importing Vector3 from a data set, with some maths function or even a bit of all of this. It's just an array filled with Vector3 to set where the tube axis goes into space.**radius**: a radius number value. This is the constant radius value applied along the tube. This value is taken into account only if the*radiusFunction*parameter is*null*.**tessellation**: the number of radial segments. If you set it to 3 you get a triangular tube section, if you set to 4 you get a squared section, and so on. So set it to what level of precision you need, just keep in mind the more segments, the heavier your mesh.**cap**: BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL.**radiusFunction**: a custom javascript function.

If you pass this parameter to the*CreateTube()*method, then the*radius*parameter value will be ignored.

Your custom function will be called at each point of the path while constructing the tube.

It will then be passed two arguments : the position of the current point*i*and the*distance*of this*i-th*point from the beginnig of the tube.

Your function must just return a radius value.

Example :`var myFunction = function(i, distance) { var radius = 3 * Math.cos(distance / 5); return radius; }; var tube = BABYLON.Mesh.CreateTube("lumps", path, null, 20, myFunction, scene);`

Here is an example with both an *i* sinusoidal radius function and *x* sinusoidal incrementing path :
https://www.babylonjs-playground.com/#LG3GS#9 -

Here's another example with a circular path and varying radius : https://www.babylonjs-playground.com/#LG3GS#10 -

What is extrusion ?

Extrusion is the way to transform a 2D shape into a volumic shape.

Let's imagine that you define a star shape by filling an array with successive *Vector3*. In order to have a 2D shape, you only set these points in the xOy plane, so every z coordinate is zero.

ex : https://www.babylonjs-playground.com/#RF9W9 -

Let's show the World axis so it is clearer : https://www.babylonjs-playground.com/#RF9W9#1 -

Let's now imagine you could stretch this 2D shape along the Z-axis to give it some volume... this is extrusion : https://www.babylonjs-playground.com/#RF9W9#30 -

Let's now imagine you can extrude your star along a 3D path in space, a sinus curve for example, and not only along the z-axis.

https://www.babylonjs-playground.com/#RF9W9#31 -

Extrusion can be accomplished with two different methods. A basic one and an advanced or custom one.

BASIC METHOD

```
BABYLON.Mesh.ExtrudeShape(name, shape, path, scale, rotation, cap, scene, updatable?, sideOrientation)
```

**name**: the extruded mesh name.**shape**: the shape to be extruded, an array of successive Vector3.**path**: the path to extrude the shape along, an array of successive Vector3.**scale**:*default 1*, the value to scale the initial shape.**rotation**:*default 0*, the step value to rotate the shape at each path point.**cap**: BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL.**scene**: the current scene.**updatable?**: if the mesh is updatable.**sideOrientation**: the side orientation -*front, back*or*double*.

If we change the *scale* value from 1 to 3 for example (line 84), the initial star is scaled to 3 along the curve : https://www.babylonjs-playground.com/#RF9W9#526 -

If we now change the

Of course, even if you define your 2D shape in the xOy plane as described, the extrusion still works along any path direction : https://www.babylonjs-playground.com/#RF9W9#32 -

Moreover, the shape doesn't need to be closed. You can have a simple (or complex) open shape : https://www.babylonjs-playground.com/#RF9W9#7 -

Extrusion : https://www.babylonjs-playground.com/#RF9W9#33 -

Extrusion with rotation : https://www.babylonjs-playground.com/#RF9W9#34 -

Remember that your shape doesn't need to be centered on the coordinate system either. Here is an offset simple shape : https://www.babylonjs-playground.com/#RF9W9#10 -

Extrusion (the extrusion path is shown in magenta so the offset is visible) : https://www.babylonjs-playground.com/#RF9W9#35 -

Now rotation... around the path axis : https://www.babylonjs-playground.com/#RF9W9#36 -

As you can see, this is a way to build complex curved helix meshes without handling maths or simpler ones : https://www.babylonjs-playground.com/#RF9W9#37 -

As the shape to be extruded is unpredictable, it is assumed that the cap, if want to add it one or two to your extruded mesh, is computed with its center set to the shape barycenter.

ADVANCED METHOD

```
BABYLON.Mesh.ExtrudeShapeCustom(name, shape, path, scaleFunction, rotateFunction, ribbonCloseArray, ribbonClosePath, cap, scene)
```

**name**: the extruded mesh name,**shape**: the shape to be extruded, an array of successive Vector3.**path**: the path to extrude the shape along, an array of successive Vector3.**scaleFunction**: a custom javascript function. This function is called on each path point and is given the*i*position of the point in the path and its*distance*from the begining of the path. It must return a*scale*numeric value. This value will be the scaling applied to the shape drawn at the*i-th*point.**rotationFunction**: a custom javascript function. This function is called on each path point and is given the*i*position of the point in the path and its*distance*from the begining of the path. It must return a*rotation*numeric value. This value will be the rotation applied to the shape drawn at the*i-th*point.**ribbonCloseArray**:*default false*, boolean. The underlying ribbon*closeArray*parameter. This can be used to automatically close a path with right normals computation.**ribbonClosePath**:*default false*, boolean. The underlying ribbon*closePath*parameter. This can be used to automatically close a shape with right normals computation.**cap**: BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL.**scene**: the current scene.**updatable?**: if the mesh is updatable.**sideOrientation**: the side orientation -*front, back*or*double*.

In this advanced method, the *scale* and *rotation* parameters are replaced by custom functions.

*scaleFunction*

This javascript function will be called on each path point iteration when extruding. It will be passed two parameters : *i* and *distance*.

**i**is the point position in the path, starting from zero for the first point.**distance**is the current point distance from the begining of the path.

This custom function must return a *scale* numeric value which will be applied to the shape on the *i-th* point.

Example :

```
var myScale = function(i, distance) {
var scale = 2 * Math.sin(i / 5);
return scale;
};
```

Here is an example with an unclosed un-centered simple shape whose scale evolves linearly along the path : https://www.babylonjs-playground.com/#RF9W9#38 -

Now if we use a sinus scaling function instead and as the shape isn't centered, we get interesting results : https://www.babylonjs-playground.com/#RF9W9#39 -

We can even emulate rotation by alternately scaling positive/negative : https://www.babylonjs-playground.com/#RF9W9#40 -

*rotateFunction*

This javascript function will be called on each path point iteration when extruding. It will be passed two parameters : *i* and *distance*.

**i**is the point position in the path, starting from zero for the first point.**distance**is the current point distance from the begining of the path.

This custom function must return a *rotation* numeric value which will be applied to the shape on the *i-th* point.

Example :

```
var myRotation = function(i, distance) {
var rotation = distance / 20;
return rotation;
};
```

Here is an example of constant scale and rotation evolving with the distance : https://www.babylonjs-playground.com/#RF9W9#41 -

You can set a non-linear rotation function of course, sinus here : https://www.babylonjs-playground.com/#RF9W9#42 -

**Fixed values**

This advanced method needs two custom functions. But you may want to use a custom scale function with a fixed (or no) rotation function, for example. In this case, just pass a custom rotation function returning a fixed value :

Example :

```
var noRotation = function(i, distance) {
return 0;
};
```

If you carefully read the code of this previous example, you can see in line 41 that the *scaleFunction* returns the constant 1 value : https://www.babylonjs-playground.com/#RF9W9#41 -

*ribbonCloseXXX* parameters

The extruded mesh is based on an underlying ribbon. When you extrude a shape, you actually make a particular ribbon.

This means you can also set this ribbon *closeArray* and *closePath* parameter if you need to automatically close the extruded shape.

NOTE : the *closeXXX* names are the ribbon ones. Not the extruded shape ones.

So it may be confusing because :

set to true will close your shape extrusion path,*ribbonCloseArray*set to true will close your shape itself (if unclosed).*ribbonClosePath*

Let's now do this unclosed, un-centered extruded shape : https://www.babylonjs-playground.com/#RF9W9#20 -

And this almost circular path : https://www.babylonjs-playground.com/#RF9W9#21 -

Extrusion with constant scale and no rotation : https://www.babylonjs-playground.com/#RF9W9#43 -

Now let's set the

As you can see, it closes the extrusion path. Let's set it back to false and let's set the

Now the shape is closed.

Both together : https://www.babylonjs-playground.com/#RF9W9#46 -

**Summary**

At last, the extrude custom function call would be, for example:

```
BABYLON.Mesh.ExtrudeShapeCustom("extruded", shape, path, myScale, myRotation, false, true, scene)
```

A shape is an array of successive Vector3. This means 2D or 3D shapes can be extruded as well.

The shape is to be designed in the local coordinate system knowing that the z-axis will be the extrusion path axis.

Finally, shapes don't have to be centered in the local coordinate system.

A centered shape will be extruded symmetrically centered along the path axis. An un-centered shape will be extruded offset from the path axis.

Easy way to generate strange shapes : https://www.babylonjs-playground.com/#RF9W9#47 -