What is wrong with this model, why so slow?

Hello good people of Babylon!

I have a general problem. I am converting big STEP files to GLB.
I import them to scene like playground below:

My problem is camera rotation and position speed. When I move camera it is soo slow. Is it same for you too? Is it related to my computer gpu etc?

Is there anybody has idea how to solve this or optimize the file?

Thank you very much.

there is nothing ā€œwrongā€ with it, it is just very big, and generated more than 8000 draw calls:

image

Making the meshes not-pickable does improve things ( Model Speed Problem | Babylon.js Playground (babylonjs.com)), and there are other things you can do (like freezing the world matrix and the materials), but that depends on your use-case

1 Like

I wouldnā€™t say that looking at this object. In fact, I donā€™t understand how it can contain 12k meshes or generate 8k draw calls. I believe many of these meshes could be merged, since itā€™s unlikely that even the real object is actually made out of 12k parts. This would be four times the number of parts you can find on a car (the real one, the eng version). I cannot see this in this object.

1 Like

Thank you both .It is a file converted from STEP to GLB with opencascade library.

How can I decrease mesh number or draw calls :melting_face:

1 Like

Huh (joke) Get a real 3D edit app :wink:
Jokes apart, I donā€™t know this ā€˜thingā€™ but there might be some export options you can try.
Or try export to another format/other app.
Last, you could merge meshes in BJS but seriously, I wouldnā€™t have the patience nor time to select from 12k meshes to create merges. My limit is at around 2k (for an offroad vehicle) and already with this, I want to kill the design team from the manufacturer :wink:

I found a similar question on stackoverflow but there is no answer. :frowning:

I hope there is a solution for this somewhereā€¦

1 Like

Stackoverflow, really? :wink: If you get an answer from there that is not just a complete piece of crap, Iā€™d say itā€™s incidental.

Do you have any export options for GLB? Do you have gltf? Or obj?
Once converted, have you tried opening it in i.e. Blender, see if you can somehow find your way around groups of meshes? How many meshes do you have initially in your app? I guess no more than about 500. It really all comes from the export, so you need to focus on that.

Hope you are well.
I am sorry for yesterday (end of day) I didnā€™t really take the time to have a closer look at it and provide better insight. I shouldnā€™t work in the evening and reply to posts. It always ends up with crap or rough answers :wink: Also, I stopped just looking at the numbers thinking I will certainly not investigate 12k meshes. But then, I thought back this morning, remembering the structure of the file.
It appears that each group of meshes is attached to a transform node, which is likely to be (i checked two nodes) the mesh or group of object meshes converted all to polys. What the (sry) crap program export is doing is converting all tesselation (and likely vertices) to meshes and place all in a transformNode. Now, if you donā€™t find a way to make a proper export or re-import (i.e. in blender to remerge the children of these transformNodes), there would still be a solution, not perfect, that would drastically reduce the number of meshes and draw calls, on BJS import. But best would certainly be to preserve these meshes on export, so let me know if you managed to do that or not. If not, we can still call on all children of each transformNode, merge them and dispose of the parent. In the end we should have less than 100 meshes (from a rough count). As I said, it would not be perfect (still about 10 times higher than what it should be) but nothing compared to what you have now.

2 Likes

Hello mawa!

Not a problem at all, I apreciate your helps. I want to give more detail. Opencascade is a C++ library. I am using that library to convert uploaded STEP files by users to GLB file with GLTFWriter function. Then import to BJS.

So I am trying to reduce mesh count since you warned about this. At least I know the problem now. :slight_smile:
t
So reducing on BJS import can be my only option. Does it take long time and can you guide me on how to do it?

Itā€™s actually quite simple (but as I said not perfect). So I expect it will give a fairly good result on this object but if your scene have dozens of these, you would definetely need to find another approach that preserves the integrity of the original meshes. I am also not sure what visual result it will give on shapes like spirals. May be weā€™ll need to recreate some materials. Materials will have to be assigned anyways since some transformNodes seem to contain not just one object but a group of object.

Sure. At least for a start. I will give it a try later (in a few hours) simply selecting from all transformNodes and merge all children and if thatā€™s ok with you, weā€™ll see what this does, for a startā€¦

Actually I am only using scene.transformNodes. So these transformNodes are parts from assembly. So I only need parts not meshes. I want to make users able to attach mesh when click on a part. Since there is a ā€˜rootā€™ mesh avoids this, after importing the model I set parent of all transformNodes to ā€˜nullā€™.

So I guess merging children of these transformNodes is even better .

Hello again,
I have some news for you. Good and bad news.
The good news is it will work and we will likely not have to reassign materials. And the other good news is that you will indeed be able to make your new remerged meshes pickable.
The bad news is for now I only had little time to make a quick attempt and draft the base script. I still need to make it dynamic and run through all nodes. Problem is I donā€™t have more time right now and would only be able to do it from tomorrow morning. If you canā€™t wait you can still try yourself if you know how to create a routine on all transform nodes and build an array of child meshes and use in the contructor for merging meshes. Nothing extremely complex itā€™s just that (sry) iā€™m running out of time for today.

Edit: If you want to do yourself, the idea of mine is to

  1. create a numbered index for the 52 transform nodes (luckily they all have the same name and following number, so this should be easy.
  2. have a routine doing basically what I did hard coded; this time using the index to perform the following operations
  • get all child meshes from a transform node
  • rename them from 0 to x
  • unparent from transform node
  • merge all childs of this transformNode and assign the merge the name of the transformNode
  • dispose of parent
    For each. On end, make a promise for all or use on scene ready observable, as required.
1 Like

I will try it mawa thanks

Well, I sort of started 30min ago but LOL :grin: Iā€™m having an issue inserting either my Array or String in the merge mesh constructor.
I am getting an error. I must be doing something w :sweat_smile:rong but I donā€™t know what. May be you know? Else, I guess I will just quickly reach out to someone who will likely fix it in a minute.
This is actual state/attempt

Let me know in the next hour if you feel like taking over or if you (also) struggle with it.
Looks like I still have things to learn :student: :sweat_smile:

MergeMeshes is expecting an array of meshes, not an array of strings as its first parameter:

1 Like

THANK YOU. I guess you understand that when I said ā€˜I know a person that will fix it in a minuteā€™ I was of course thinking of you :smiley: Youā€™re just so amazing. Have an awesome day :sunny: :sunglasses:

@omerization : Are you all good with this now? The last part should be ez (hopefully :wink:
Else, let us knowā€¦

1 Like

I am working on writing a function that is going to work for any model by referencing yours . I will let you know the result!

1 Like

Cool, Iā€™m eager to see if it will do whatā€™s expected.

@mawa It definetely increased the performance! Still gets slow if there are many parts like you said.

 for (const node of scene.transformNodes) {
        if (scene.transformNodes.indexOf(node) !== 0) {
          const childMeshes = node.getChildMeshes();
          if (childMeshes.length > 0) {
            const newMesh = BABYLON.Mesh.MergeMeshes(childMeshes, true, true, undefined, false, true);
            newMesh.setParent(node);
            newMesh.isPickable = false;
          }
        }
}

MergeMeshes function takes time though and blocks other things I guess. Something happening to react, even my loading animation stops :smiley:

Thatā€™s already great progress.

Yes, I was afraid of that. Reason I would have checked with just this object first.
But I guess you could fix it (or improve it a lot) using a web worker (doing the job outside the engine/scene).
Actually multiple web workers if you have more of these in one scene.

Edit: Iā€™m not sure you can do it for merging meshes. I am not much of a backend dev, sry. Just a simple designer. But I can callin some people who will know or can may be propose some other solution for this part. Would you have a new PG to share with this new base?

1 Like