Multi Form Geometry

For the procedurally generated skeleton figure Pino - a procedurally generated and moved skeleton figure I created a self-defined geometry. With it, all body parts are generated and connected to the bones. Thereby I concentrated on the most necessary things.

From the completion of this approach the Multi Form Geometry was created.

It has some similarities but also clear differences to my Addon. Produces almost infinite many time-varying geometries with functions. It is much clearer in the definition, but some possibilities are missing. For example, no real 3D space curve can be generated. The center line only leads to a shear per height segment. See also How to animate curved arrows in threejs? - #3 by hofk . A torus knot can only be created flat.

In contrast to the addon there is a separate static and dynamic variant. The two functions are line by line comparable. One can choose the appropriate variant.

The geometries created with the static variant can be linked. One receives a single geometry. Each part geometry can be assigned its own material, i.e. MultiMaterial support during the formation of the mesh.

In the Collection of examples from , try it out: MultiFormGeometry

On GitHub: threejsResources/MultiFormGeometry at master · hofk/threejsResources · GitHub

The parameters, all optional

function multiFormGeometryStatic( p ) {
    //   p = { radius, height, withBottom, withTop, translateX, translateY, translateZ, 
    //         scaleX, scaleY, scaleZ, shearX, shearZ, radialSegments, heightSegments, centerline, outline, torsion, rotateX, rotateY, rotateZ }


bottom and top y … 0 → j
and outline for test

see bugfix bottom and top ( y ... 0 -> j · hofk/threejsResources@dc57096 · GitHub

1 Like

There is an extension.

Properties .cover .onTop

To be able to create 2D surfaces I used the cover in a simple way.

This is done by the new .cover property.

From the cylinder you get a rectangular surface comparable to the three.js PlaneGeometry.

With torsion, you can then create something like this. Added in the example.

About the new property .onTop.

Originally, the geometry was such that it normally stood on the xz plane. This resulted from the origin of geometry to create a figure with skeleton and bones. Pino - a procedurally generated and moved skeleton figure

However, for other applications, the standard of three.js with the center in the origin is more suitable. It is now available via dafault. To not change the appearance of the example I added onTop: true, to the properties.

I was asked if it is possible to create a flat box with the Multi Form Geometry.

You can, but if you use a texture you have to keep in mind that only the subranges (in the width) 0 to 0.25 on one side and 0.5 to 0.75 on the other side are really visible. This is not a problem if you have a tangled pattern, otherwise you can use a graphics program to create an appropriately designed texture.

Bottom and Top are distorted!

const box = multiFormGeometryStatic( {
    radius: 5,
    radialSegments: 4,
    rotateY: Math.PI / 4,
    translateX: 10,

} );

box.scale(  0.1, 1, 0.002 );
staticGeometries.push( box );

materials.push( material01 );

I have added the example in MultiFormGeometry.

I have added the creation of 2D shapes.

One specifies as parameter geometry2D: true, .

In the original example, I added 2D faces.

Additionally there is an example with 2D only.

2022-05-05 20.37.02

Instead of radius and radialSegments use width and widthSegments.

It took little effort to insert 2D.
Besides some minor changes and additions to the processing of the parameters, the calculation of the positions was quite easy to solve.

               if( g2D ) { // 2D geometry
                    x = r * fx[ i ][ j ] * ( j - rs / 2 ) / rs * scX; 
                    y = h * fh[ i ][ j ] * scY;
                    z = 0;                    
                } else  { // 3D geometry
                    x =  r * fx[ i ][ j ] * scX * Math.cos( φ( j ) );
                    y =  h * fh[ i ][ j ] * scY;
                    z = -r * fz[ i ][ j ] * scZ * Math.sin( φ( j ) );
                    if ( cover ) { // unroll cover
                        z = Math.sqrt( x * x + z * z ) - r * fx[ i ][ 0 ] * scX;
                        x = r * fx[ i ][ j ] * scX * φc( j ); // center x
1 Like