Modify Python Script to Ignore Groups and Scribble from Selected Objects

Hi everyone,

I have been using this Python Script to manage wire display in GH. I usually always use Default, as David manifested many times, hiding wires is no ideal. Despite this, I sometimes have to deal with definitions that have ALL wires hidden, yes globally, thanks to a VB script.

The cool thing about the Python script is that lets me revert wire display locally, (only selected objects).


from Grasshopper.Kernel import GH_ParamWireDisplay
from Grasshopper.Kernel import GH_RuntimeMessageLevel 

# A dictionary of wire types 
wire_display = {'0':GH_ParamWireDisplay.default, 
                '1':GH_ParamWireDisplay.faint,
                '2':GH_ParamWireDisplay.hidden}

# Get selected components and change the wire display
if on:
    doc = ghenv.Component.OnPingDocument()
    sel_objs = doc.SelectedObjects()
    if not len(sel_objs):
        ghenv.Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, 'Nothing was selected')
    for sel_obj  in sel_objs:
        if hasattr(sel_obj, 'Params'):
            for p in sel_obj.Params.Input:
                p.WireDisplay = wire_display[wire_type]
        else:
                sel_obj.WireDisplay = wire_display[wire_type]

It has one flaw though.

Runtime error (MissingMemberException): ‘GH_Group’ object has no attribute ‘WireDisplay’

Traceback:
line 20, in script

When you select a group, it fails completely. Same happens with a Scribble.

I have been trying to add conditionals to the IF statement, but I in this past 2 hours I was not able to find out the proper methods to test whether an object is a group or not.


Can someone point me to the correct documentation?

I first went here and nothing was useful.

“RhinoScriptSyntax in Python” link that takes you to an article that does not have the Rhino Script Syntax API anywhere not a link to it. I had to google “rhino script syntax” to get there.

Regarding Grasshopper, it was all a pain:

Grasshopper’s link to its API is nowhere to be found except the one and only

While in here, there are no Python examples, its all C# and VB…

Then, where is the documentation that explains all the name spaces??

There is:

Grasshopper.Kernel
Grasshopper
ghpythonlib.components

Least but not least, what is ghenv??

I would greatly appreciate anyone that can clarify these concepts for me.
Shynn.

You can check if the object has WireDisplay attribute or not:

from Grasshopper.Kernel import GH_ParamWireDisplay
from Grasshopper.Kernel import GH_RuntimeMessageLevel 

# A dictionary of wire types 
wire_display = [GH_ParamWireDisplay.default, GH_ParamWireDisplay.faint, GH_ParamWireDisplay.hidden]

# Get selected components and change the wire display
if on:
    doc = ghenv.Component.OnPingDocument()
    sel_objs = doc.SelectedObjects()
    if not len(sel_objs):
        ghenv.Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, 'Nothing was selected')
    for sel_obj  in sel_objs:
        if hasattr(sel_obj, 'Params'):
            for p in sel_obj.Params.Input:
                p.WireDisplay = wire_display[wire_type]
        elif hasattr(sel_obj, 'WireDisplay'):
            sel_obj.WireDisplay = wire_display[wire_type]

Wire.gh (14.5 KB)

import Grasshopper
if on:
    doc = ghenv.Component.OnPingDocument()
    sel_objs = doc.SelectedObjects()
    for sel_obj  in sel_objs:
        if type(sel_obj) is Grasshopper.Kernel.Special.GH_Group:
            print 'A group has been selected'
2 Likes

You can also change the code in order to control wire display of objects in a group:

from Grasshopper.Kernel import GH_ParamWireDisplay
from Grasshopper.Kernel import GH_RuntimeMessageLevel 
from Grasshopper.Kernel import Special
# A dictionary of wire types 
wire_display = [GH_ParamWireDisplay.default, GH_ParamWireDisplay.faint, GH_ParamWireDisplay.hidden]

# Get selected components and change the wire display
if on:
    doc = ghenv.Component.OnPingDocument()
    sel_objs = doc.SelectedObjects()
    if not len(sel_objs):
        ghenv.Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, 'Nothing was selected')

    objects = []
    for i in range(len(sel_objs)):
        if type(sel_objs[i]) is Special.GH_Group:
            objects.extend(sel_objs[i].Objects())
        else:
            objects.append(sel_objs[i])

    for obj  in objects:
        if hasattr(obj, 'Params'):
            for p in obj.Params.Input:
                p.WireDisplay = wire_display[wire_type]
        elif hasattr(obj, 'WireDisplay'):
            obj.WireDisplay = wire_display[wire_type]

Wire.gh (21.4 KB)

3 Likes

Complete OT, but scanning thru topics, I keep reading this one like… :smile:

image

2 Likes

Hi @Mahdiyar thank you. That was simple.

Could you maybe clarify some of my other doubts? And more just keep popping up.

What is the difference between IGH and GH?

IGH_DocumentObject.OnPingDocument Method
GH_DocumentObject.OnPingDocument Method

Why in the script is ghenv.Component.OnPingDocument()

ghenv used instead? I can’t find a reference to ghenv anywhere. @piac

Any object holding a reference of an Interface (I…) does not need a concrete implementation. All its says is: Give me any object which has a OnPingDocument implementation and run this. So any class containing reference to other objects only by interfaces is automatically a decoupled class. If you like to you could create an ShynnSup_DocumentObject implementing the IGH_DocumentObject interface and inject it to the GH ecosystem without actually breaking things (in theory). “Design-by-contract” is this concept called.

ghenv is just a instance of an object holding other useful instances, such as the underlying Component instance below the script instance.

1 Like

Hi Tom, thanks for the explanation. I missed most of it, but I can use your words as a launching pad to read about: “Implementation”, “decoupled classes”, “inject” “design-by-contract”.

What I keep not understanding is what is ghenv.

What does it mean? “gh” for grasshopper? “env” for environment?
Is it a keyword? A data type? Method? Class? Where is the documentation for it? The GH API has no mention of the word.

The OnPingDocument method belongs to the GH_DocumentObject Class as well as the “IGH_DocumentObject Interface” for some reason it is named “Interface” instead of “class”.

Anyways, why is the line not written: GH_DocumentObject.OnPingDocument() ?
This makes sense: You initiate a class (GH_DocumentObject), access a member method of said class (.OnPingDocument) and invoke it ().

How am I suppose to know the line has to be ghenv.Component.OnPingDocument() instead? Where is the documentation for this?

image

image

As far as I recall it’s still not really documented (i.e. unlike ghdoc etc.). But you can have a read through this old thread:

1 Like