Python - bring forward

python

#1

Hi,

Can anybody help me? I couldn’t find the visibility orders in Python. Shall I use Command for that?
I would like to change the order of some groups to bring them forward.


#2

@onrender, you might try setting this through obj.Attibutes.DisplayOrder

_
c.


#3

Thanks clement,

I have used the code below but got an error message;

from System.Collections.Generic import *
from System.Drawing import *
from Rhino import *
from Rhino.Commands import *
from Rhino.Display import *
from Rhino.Geometry import *
from Rhino.Input import *
from Rhino.DocObjects import *
from scriptcontext import doc
import rhinoscriptsyntax as rs

objList = []

def DisplayOrder():
    obj = rs.GetObject( "Select an object", 0, False, False, None, False)
    objList.append(obj)
    print objList
    objList[0].Attributes.DisplayOrder = 10
    objList[0].CommitChanges()
    doc.Views.Redraw()
    
DisplayOrder()

Message : ‘Guid’ object has no attribute ‘Attributes’


#4

@onrender, that is correct. The rs.GetObject() method returns object Guids, so you first need to coerce that to an rhino object before you can access the attributes. eg.

rh_obj = rs.coercerhinoobject(obj_id, True, True)

_
c.


#5

This seems like it should be fairly simple, but it’s not working reliably for me. I tested by drawing a box, changed the colour, copied in place, changed the copy to a different colour, and I can see a problem.

from System.Collections.Generic import *
from System.Drawing import *
from Rhino import *
from Rhino.Commands import *
from Rhino.Display import *
from Rhino.Geometry import *
from Rhino.Input import *
from Rhino.DocObjects import *
from scriptcontext import doc
import rhinoscriptsyntax as rs

def DisplayOrder():
    objects = rs.GetObjects("Select the objects that you want displayed on top")
    if objects:
        for object in objects:
            obj = rs.coercerhinoobject(object, True, True)
            obj.Attributes.DisplayOrder = 1
            obj.CommitChanges()
            rs.Redraw()

if __name__ == "__main__":
    DisplayOrder()


(I don’t know if all of those imports are necessary, but I copied the example in the documentation just to eliminate any chance of error)

What I’m finding is that the script above works occasionally. But so does just selecting the object with no command invoked. Here is a short video of what I see going on:

Having the ability to toggle what is displayed on top is very important for our data department. They use this functionality in V5 to look for differences in data when we are doing engineering changes on the customer’s data. Currently, they are not able to move forward to Rhino 6 because of this issue.

Thanks,

Dan


#6

Hey Dan,

I was under the impression that DrawOrder only affects basically 2D objects:

From the help:

Note: Draw order supports only hatches, curves, points, annotation (all forms of text other than dots), and details.

–Mitch


#7

They are not required and i would not suggest to use wildcard imports at all to prevent naming conflicts.

I’ve only been able to make this work reliably using curves or conincident planar solid hatches too in V5. In below example, it changes the shaded display to wireframe (V5) if i apply it to 2 indentical extrusion boxes, one in red and one in blue:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext

def DoSomething():
    
    red_id = rs.GetObject("Select red object")
    if not red_id: return
    
    blue_id = rs.GetObject("Select blue object")
    if not blue_id: return
    
    red_obj = rs.coercerhinoobject(red_id, True, True)
    blue_obj = rs.coercerhinoobject(blue_id, True, True)
    
    red_obj.Attributes.DisplayOrder = 1
    red_obj.CommitChanges()
    
    blue_obj.Attributes.DisplayOrder = -1
    blue_obj.CommitChanges()
    
    scriptcontext.doc.Views.Redraw()
    
DoSomething()

@dale, i think this is a bug. In V6, it does not change the extrusion objects to wireframe, but also does not change the display order.

If i run the above example on two overlapping curves, eg. a longer blue curve and a shorter red curve, it works as expected in V5 and V6. I therefore think the display order only works reliable with curves (or planar solid hatches).

Below shows overlapping curve objects without display order (left) and after changing it (right)

_
c.


#8

Hence the Help item I quoted above. As far as I know it has always been that way.

@dan Here is my definition of “BringToFront” - will bring selected objects in front of everything else. For this it needs to collect draw order info for all objects in the file every time you run it.

import rhinoscriptsyntax as rs
import scriptcontext as sc

def BringObjDisplayToFront(objIDs,filter):
    chgobjs=[rs.coercerhinoobject(objID) for objID in objIDs]
    norm_objs=[rs.coercerhinoobject(objID) for objID in rs.ObjectsByType(filter)]
    max_level=max([rhobj.Attributes.DisplayOrder for rhobj in norm_objs])
    #print max_level
    for chgobj in chgobjs:
        chgobj.Attributes.DisplayOrder=max_level+1
        chgobj.CommitChanges()
    sc.doc.Views.Redraw()
    
filter=1+4+512+65536
objIDs=rs.GetObjects("Select objects to bring to front",filter)
BringObjDisplayToFront(objIDs,filter)

#9

Hi @Helvetosaur, @clement,

Okay, that’s why it’s unpredictable then. I’m expecting too much from it!

In V5, I was able to get the functionality we needed by simply copying and deleting. The draw order was predictable so this worked.

import rhinoscriptsyntax as rs

def DisplayOrder():
    objects = rs.GetObjects("Select the objects that are on top", 0, None, True, True)
    if objects:
        copied = rs.CopyObjects(objects)
        if copied:
            rs.DeleteObjects(objects)
        rs.UnselectAllObjects()
        rs.Redraw()

if __name__ == "__main__":
    DisplayOrder()

I’m going to need a new solution to emulate this behaviour. This is kind of a “show-stopper” for us.

Thanks,

Dan


#10

I didn’t see your response as I posted my last one. I’ll give that a try.

Thanks,

Dan

edit: Looks like 2D only too.


#11

It will always only be that… All the script does is emulate the Rhino command. --Mitch


#12

Yeah, I think in 3D the most recent objects are drawn last (on top) if they are concurrent with something else - otherwise it’s the object closest to the camera which rules… --Mitch


#13

I was able to count on that fact. In V6, it’s not like that anymore. The video above shows no real rhyme or reason as to which of those boxes is displayed on top. They change randomly just by selecting.


#14

I guess that’s a change introduced by the new display pipeline…


#15

@Helvetosaur, same here, we where writing at the same time.

_
c.


#16

Maybe @jeff or @stevebaer have some ideas here?


(Steve Baer) #17

I guess we could key off of the display order attribute for things like extrusions and breps to sort the draw list. That wouldn’t force these objects to be on top, but they would be drawn last. Would that work for you?


#18

I was thinking that maybe I can extract the wireframe and then use the Attributes.Displayorder properties on the curves. If I keep this organized on layers created just for this purpose, the users shouldn’t complain too much. In fact I might be able to sell them on the idea that its better since we’re not manipulating the original data. To the best of my knowledge, they do the checks in a wireframe viewport already anyway, so from their perspective, this might in fact be an improvement.

Do you know if there is a more elegant way to extract the wireframe than using the Rhino command? I find the new script editor so difficult to use now when it comes to help. For example, I wanted to see what your 65536 filter was, but I couldn’t just open the GetObjects method and read it like I could in V5. Now I need to chase down something called Filter class. It seems to me that scripting has taken a step in the wrong direction for the average person.

Thanks,

Dan


#19

Hi Steve,

Yes, I think that could work for me. As long as there is a predictable order I should be able to do something with that.

Thanks,

Dan


(Steve Baer) #20

I logged this and will try to get to it soon
https://mcneel.myjetbrains.com/youtrack/issue/RH-45062

I’m not following; how did you “just open the GetObjects method” in V5? I’ll log this as a bug once I understand the problem a little more.