Draw Order Overview

For others who are struggling with draw order issues, below is my understanding of draw order, a potential workflow, and some helpful scripts by others. Maybe some of you will find this useful, or have better suggestions. @arcade.smith, @Tom_P , @Daniel_Krajnik , @holo, @eugen, @a.p.haythornthwaite , @cwetteskind , @silvano , @ShynnSup , @keithscadservices , …

First Principles:
This is the clearest explanation I’ve seen on the forum for draw order first principles in Rhino:

General Implementation:
My current understanding for objects outside of blocks:

  1. Draw order is taken from the layer order
  2. Within a layer, hatches display below crvs and annotations.
  3. Print preview in PDF should be most accurate–what is displayed on screen in the model is not always true to actual draw order.

I’ve found 1 to not always be true, and #2 makes things murky and cumbersome to control order between objects on the same layer.

My Workflow:
That very useful python script listed in the quote above (thanks much @Helvetosaur ) can be slightly modified to either set draw order for multiple objects simultaneously, or find a single object draw order, which gives you precise control. I found it more efficient to separate the two functions and map them to aliases.
SetDrawOrder.py (754 Bytes)
FindDrawOrder.py (722 Bytes)

Then layers can be tagged with the desired draw order.

Hacky, but it works, and you have exact control over objects inside layers. However, blocks are still a problem:

And this behavior is not consistent; sometimes block draw order displays just fine in model space and when printing.

@stevebaer , could you explain exactly how draw order works for objects inside blocks? Pascal’s explanation below is how I would expect/want it to work, but as you can see in the images above, that’s not necessarily always the case, especially for nested blocks.

Other Helpful Scripts
Matching draw order:

Feature Requests:

  1. I would prefer that blocks have no effect on draw order whatsoever.
  2. Draw order should be exposed as an additional property in the properties panel (alongside display color, linetype, etc).
  3. A full-blown panel to manage draw order with a tree structure like the layers panel would be amazing. This post has a lot to say about that.
4 Likes

Well, I’m not quite sure all of that is exactly how it now works. Since layer order has been allowed to influence draw order as well, it is often difficult to know exactly what is going on. We have both ‘implicit’ draw order (according to layer order) and ‘explicit’ draw order - where the object has an assigned a draw order number.

The implicit draw order based on layer order is not part of an object’s attributes and this cannot be directly read - one would have to get the layer order from the layers dialog - I’m not even sure where that’s exposed for scripting purposes. For me, this throws all predictability out the window.

Here is a quickie test file. There are five layers, each with a square and a hatch, the hatches are color by layer, the curves have darkened versions of the layer color assigned directly. You can see here that the display order for the hatches is indeed the layer order, but all of the curves display on top of the hatches, no matter what the layer order is. Note also that everything has draw order 0 - default, nothing has been explicitly assigned.

Below the hatches are five lines, one on each layer, drawn on top of each other but displaced along X, and assigned color by layer. You can see that curve drawing does not obey layer order and the draw order result appears random - the line on the blue layer (#4) is drawn on top. So the curves do not obey layer order display in this case.

Odd thing is if I run the script to change draw order, the lines get displayed in the correct layer order - but only while running the script… When I cancel, they go back to the way they were. Very bizarre.

So, this combination of implicit and explicit display order plus objects that may or not obey the implicit order makes it almost impossible to predict what will happen. So for me, the only way to be 100% sure of the display order is to assign a specific value. Once a display order number is explicitly assigned, it appears to override layer order and all other implicit draw order assignments.

As far as blocks go, if not specifically assigned, I would assume that draw order in block instances is determined by the layer order of the original objects before they were “blockified”. But I have not tested that.

3 Likes

I’ve also noticed that curves do not necessarily obey layer order–thanks for the much clearer explanation.

In regards to blocks: in the images I posted above every object inside the blocks has an explicit draw order already applied to it. So I really have no idea why blocks are messing with the draw order. But you think perhaps they are retaining their initial implicit draw from layer order at the time of block creation?

Feature Request:
Perhaps this would be an effective way to have WYSIWYG implicit and explicit control over display order:
Implicit:
:Draw order values between 0 and 1
:eg: Layer A =.01, Layer B =.02, Layer C =.03,…
:These are assigned automatically upon object creation, and reordered automatically when layer order is changed. They can, however, also be manually viewed and changed at any time by the user.
Explicit:
:Draw order values between 1 and infinity, eg:
:Object A =2, Object B =10.7, Object C=100, etc,…
:These are user-assigned values.

In both implicit and explicit cases, I think it’s important to allow non-integer values for the insertion of newly created objects, without reordering the entire list.

The thing is, you can re-order layers in the dialog and in theory the display draw order should update accordingly. So one cannot assign a fixed value by layer as one can with per-object.

I find myself almost wishing there was a switch to be able to turn off draw order by layer order.

My thought (not sure if I explained this clearly earlier) was that all of the automated re-ordering of layers would be accomplished with draw orders exclusively between 0 and 1. If the user wants to manually adjust order between 0 and 1, they know that order may be wiped with future layer re-ordering. If they want to control draw order totally outside of the layer re-ordering (which is how I prefer to work–I find layers much more useful for categorizing things other than draw order), they have the option to do so by entering values from 1 to infinity. Layer re-ordering would ignore objects with draw order values greater than 1.

A switch to turn off layer order might be simpler, I just want the option of knowing the exact numerical draw order of any object, whether auto or manually generated, at any time.

@pascal , @wim, can either of you weigh in on exactly how draw order works inside a block, and inside a nested block?

1 Like

Can anyone weigh in on my question about block draw-order logic? I have an entire drawing set due very soon that I can’t send out because of this issue.

Explicitly set draw order (bringforward, sendback) on objects in blocks should work.

What is the problem that is causing you to not be able to deliver your drawing set?

I can’t issue drawings with studs showing in front of windows:


And I don’t want to explode the blocks since they’re used on multiple drawing sheets. If I did explode them, my workload would massively increase any time the client wants to change something.

Here is an example file with a typical problematic area in the red circle. To my knowledge I’ve explicitly set the draw order for all objects in the window/wall blocks. Specifically, the white mask in the window block has draw order of 50, and the grey hatch for the studs in the wall block has draw order of 1. There is a parent block for the whole floorplan, and then walls and windows are each in their respective blocks within the parent block.

20230714_DrawOrder_BlockGlitch.3dm (6.9 MB)

Sometimes the draw order displays correctly, other times incorrectly, and it seems to alternate after I open/close the block for editing.