MeshBuilder cap parameter for Cylinder & ExtrudePolygon; sides parameter for Box

Lacking any experience in Blender to create models myself currently, I’m a heavy user of the MeshBuilder helper functions. I’ve become a master at stacking Boxes, Cylinders, and the like :slight_smile: and then merging them into a single mesh. (Remember the Wooden Building Blocks toy from when you were a kid?)

I have a question about adding some more support for customizing the basic elements further. This will save me on lots of unneeded/not visible sides and faces of the basic elements meshes. And perhaps it will benefit other developers as well that like to use the MeshBuilder for basic 3D shapes.

  • For the CreateBox I’m looking for a way to give the function an argument to select which faces of the Box I want to have in the result (default all 6). For example if I pass the argument such that not to have the bottom square, then the Box would be hollow from beneath. Also I am looking for a way to set a different size of the bottom and the top (like you can do when creating Cylinders) so I can easily make Trapezium-like and Parallelogram-Like boxes etc.

  • For the CreateCylinder I’m looking for a way to omit some of the created caps (default CAP_ALL). E.g. with CAP_START I only want the bottom ring and no vertices and triangles for the top ring of the cylinder (the Cylinder becomes hollow from the top, like a trash can or bin).

  • Same for ExtrudePolygon to be able to set both, one or the other, or none of the caps. (Whether these faces/sides triangles&vertices are created or not.)

  • For the CreatePolyhedron I have a hard time finding the correct rotation to set to make the Prisms and/or Pyramids bottom plane match the world XZ-plane (‘stand firmly on the ground’). The Pyramids I create always show up by default in some tilted rotation… any ideas perhaps?

Any ideas are welcome.

Perhaps some of the solutions I can implement myself to the GitHub project - once I know how to alter the creation logic of the 3D Mesh construction properly (“which faces and vertices to comment out”).

Q

Hi QuintusHegie,

This sounds like an awesome idea, although it might be better as a separate capability (CreateAdvancedBox, or something like that) rather than a customization on the existing builders. The code for CreateBox is quite heavily specialized/optimized, and adding additional checks for use in an uncommon scenario might not be the best idea.

With that in mind, it might be easier to start from an older version of the box builder and use that as a basis for creating more advanced specializations. In the version I linked to, the vast majority of the mesh construction is done in a face-wise for loop, so hypothetically eliminating particular faces shouldn’t be much harder than skipping them in that loop. (You’d probably need to manipulate normalsSource, too, and a few other small changes, but the loop appears at a glance to be the bulk of it.) You could use a similar approach to look into specialized versions of cylinders, extrusions, etc. Again, not sure this is the sort of thing you’d want in the basic version of the mesh builder, depending on the added complexity. But as a separate utility on the side, this sounds like a pretty neat idea of how to mesh from code. :smiley:

Interesting idea and I have been given it a little thought over night. For simplicity lets consider just removing the top, bottom or both. Remove one and you have a container of some sort, remove both and you have a tube.

So side removal on basic shapes could lead you

such as CreateBoxContainer or CreateCylinderTube. The use of SINGLE or DOUBLESIDE when creating the mesh would either give you a shape without uneeded sides or a container or tube.

However without going to the trouble or writing these new shapes you can quickly build such shapes using CreateExtrudeShape, eg Babylon.js Playground

Using CreateExtrudeShapeCustom You can even have different sizes for top and bottom https://www.babylonjs-playground.com/#VH4TCJ#1 (remove DOUBLESIDE if side saving)

A wide variety of shapes are then available https://www.babylonjs-playground.com/#VH4TCJ#2

1 Like

Nice to know I’m not the only one liking the idea! Thanks @syntheticmagus :slight_smile:

Yes the CreateBox functions looks way too optimized for me to start working on as a first case.

So I started playing with the CreateCylinder helper function. Apparently the code base already contained a modular approach, in which the two cylinder caps are created by calling a helper function twice. Well, that’s excellent, right? Because then all I need to add are some lines of code to conditionally call these functions based on a cap-parameter.

So that’s what I did. Here is the playground for it:

https://playground.babylonjs.com/#FWA3TX

I code created some kind of recycle bin with an open top. But you can test out other cylinder shapes by tweaking with the options variabele and its added cap-property.

The main additions to the CreateCylinder function are:

var cap = options.cap !== undefined ? options.cap : BABYLON.Mesh.CAP_ALL;

if ((cap === BABYLON.Mesh.CAP_START)
    || (cap === BABYLON.Mesh.CAP_ALL))
    createCylinderCap(false);
if ((cap === BABYLON.Mesh.CAP_END)
    || (cap === BABYLON.Mesh.CAP_ALL))
    createCylinderCap(true);

Do we like this easy-to-add solution? And does it work for others as well? Please let me know by liking this message. Then I can officially propose them to the GitHub codebase.

Q

Actually I needed to add code to 2 files with a CreateCylinder method to support the ‘cap’ parameter in the function options:

Also made the ‘cap’ code more look similar to other existing code in the project (for conformity).

Didn’t manage to get the 2 files into one patch when using the GitHub web interface (sorry about that).

This should now show up as ‘pending review’, right?

Oopsie I made a coding mistake with the NO_CAP value for MeshBuilder.CreateCylinder.

https://playground.babylonjs.com/#ZF2UDG#1

See the left-most cylinder.

It is treated as CAP_ALL. Have to fix this to NO_CAP.

Probably caused because NO_CAP evaluates to 0 (false) and hence is ignored as a valid answer in the line:

var cap = options.cap || Mesh.CAP_ALL;

The proper logic I’m seeking for this is that if cap value is omitted from the function call, then use Mesh.CAP_ALL, but if cap value is specified in the function argument and set to NO_CAP, use that value.

Nonetheless the CAP_START and CAP_END already save me lots of vertices in my scenes :slight_smile:

Q

1 Like

I fixed the above mentioned trouble code line in MeshBuilder.CreateCylinder to

var cap = (options.cap === 0) ? 0 : options.cap || Mesh.CAP_ALL;

And created a Pull Request:

Waiting to be reviewed/approved on GitHub.

Q

merged ! Thanks a lot!

1 Like