is it possible to switch somewhere so that the heavy geometry objects are represented by a bounding box?
Thanks Willem, unfortunately is still slow, I have 12000 mesh grass blocks scattered over the surface. I made a comparative test with 12000 solid boxes and it’s way faster to navigate.
In fact when I turn off the BBox Display it is a bit faster in wireframe mode.
Furthermore when I exploded the block and arrayed the mesh x12000 it flies in the viewport.
Is this a bug with the block BBox representation?
Here is a simple sample file, try to navigate and turn on/off the BBox Display option: BBox Display block problem.zip(487.7 KB)
Did somebody checked this, is this a bug?
I think this is related, not to the use for BBox Display, but to the use of Blocks.
If I’m not mistaken, Blocks are an advantage when it comes to file size; repeating geometry only has to be stored once in the file and it’s instances only need to contain the information for position, orientation, and scale of that geometry.
However as I understand it, this causes the display to slow down as for each change in the view, all block instances have to be re-calculated. I guess the same applies to the BBox Display.
@jeff is this something you can shed some light on? Does Dynamic Display suffer from the same slowdown of displaying blocks. Or am I missing a point while misinterpreting/over-simplifying?
Willem is mostly correct. The issue isn’t in drawing all 12k instances as Boxes… The issue is drawing 12k instances period. When it comes down to it, drawing the geometry (especially boxes) happens in a nano second because Rhino uses the GPU extensively to draw. It’s getting to the point of drawing is where things get complicated, and if you have nested blocks it gets even more complicated.
I’m not making excuses here, I’m only explaining how blocks work so that you can understand why/how things work the way they do. This is going to be a long ride, so buckle up
Blocks do not occupy space in the world…they simply represent geometry that could, at some point exist somewhere in the scene. Therefore, in order to see a block you need to create an “instance” of it, and place it somewhere in the scene. The position you place the instance is all relative to the base-point you defined in the block. Keep in mind, that the instance does not exist at all, anywhere…not in memory and not in your scene… The only thing that does is exist is the point in space at which you chose to place the instance. So when you actually see the instance, remember, it’s not really there…Rhino only tricks you into thinking it’s there…You can see it, you can pick it, you can transform it…but only because Rhino continues to trick you into thinking that something is really there…but in fact, it is not.
Well, how does all of this trickery work? In a word, transforms…more specifically, model transforms. As I said, the only thing Rhino keeps track of for instances is a single point in space…and when it comes time to trick you into thinking something is there, Rhino takes that point in space, and constructs a matrix transform that is a based on and relative to the Block’s base-point…and applies that transform to all of the geometry within the block, and then draws everything in the block, so that the block then appears to exist at the transformed position in space (note: it must do this each and every time it comes time to draw the instance).
Again, so what?
Given that, when Rhino is drawing its stuff, it always maintains a current model transform so that all other geometry is drawn correctly. However, when it comes time to draw an instance, it must:
- Save the current model transform
- Set the new transform constructed for the instance
- Draw the block
- Restore the current model transform.
…and if you have nested blocks, steps 1-3 become recursive.
This is pretty expensive in terms of display speed and performance, and it’s ALL done on the CPU not the GPU.
So… As I mentioned in my first paragraph…the problem isn’t in drawing the block (step #3 above), that all happens very quickly…The problem and issue is in the other steps needed to save and restore the model transform(s). So even though you’re only drawing the bounding box (again, that’s really fast), the transforms still need to be done so that the box lands in the correct position in space. Thus, most likely not providing much in performance increase (mainly because the performance problem is not related to the actual drawing of the geometry).
In short…The problem is in the way Rhino manages instances and not in the way it uses the GPU. Many users confuse Rhino’s display performance with not utilizing the GPU, I assure you that couldn’t be further from the truth. Rhino (V5) utilizes the GPU quite extensively when it comes to drawing geometry. Most (if not all) performance issues in Rhino are related to “object management”. And when you have poor object management, then performance really starts to suffer the more objects you have…and instance objects magnify the problem. Your example of 12000 blocks, means there will be at least 36000 model transform save/restores per frame… That’s 36000 more than there would be if you had no blocks (i.e. none).
Another big mistake users make with blocks is in their perception of what they are and how they should be used (note: You’re using them correctly here)… Some users think blocks are a form of hierarchical modeling…however, that’s probably mostly McNeel’s fault because of the way they’ve been used to represent other object types found in other 3rd party file formats…for example: Solidworks’ “Assemblies”. When Rhino reads in SW files with assemblies, it turns the assemblies into blocks and then creates instances…so immediately you think: “Hey, blocks are assemblies in Rhino”… Some might disagree, but IMO, that is an incorrect usage of blocks, and is not what they were designed for… So what ends up happening is that you get some users complaining about how slow Rhino is displaying a SW file when compared to SW displaying the same file…and then cry foul and complain that Rhino isn’t using the GPU as well as SW is…when in fact what they’re really seeing and comparing is how SW can display their native file format using assemblies much better than Rhino can using blocks and instances…All CPU based and all object management issues.
Sorry for the long winded response…especially since it doesn’t help your current issue…but I hope it was at least informative…and again, I’m not making excuses here, I’m only explaining why Rhino is so bad at displaying blocks… A problem I really hope to fix in V6.
Something you can try just so you can see that drawing time isn’t really the issue (Note: This assumes logical grouping of instances…i.e. all instances look the same and use the same materials/colors):
- Place all your instances
- Select all of them (or some logical grouping of them)
- Run “ExtractRenderMesh”
- Unselect everything
- Select all extracted render meshes in #3
- Run “Join” to create one, single disjoint mesh
- Hide all instances (selected in #2)
…now see how fast your display speeds are…And if I do my job right, then this should be similar to how V6’s display speeds will be…fingers crossed.
Looking forward to that.
Thanks for the explanation again Jeff.
Jeff, thank you very much for an exhaustive explanation, i really hope you will make it work that way.
I’m curious for the v6 betas. Will the new code enhance the speed of models like the bike model?
Can something be done at v5 to reorganize the model for faster display? I get models from client as STEP and after import I have the block situation. After I exploded the block back to solids, can the model structure be optimized by a trick?
Thank you for the insight. Good luck for programming.
Any good news for V6 regarding this?