New ghPython with Node-in-Code and Multi-threading

Just about anything to do with layers, object colors, blocks, opening/importing/exporting/saving files, dimensions, layouts, views, accessing the Rhino UI… just off the top of my head…

–Mitch

In addition to what Mitch pointed out, rhinoscriptsyntax is really useful for people who don’t use Grasshopper or are migrating their RhinoScript to python. We’re not “killing” rhinoscriptsyntax; it is just another library that sits on top of RhinoCommon that provides some higher level functionality. If you don’t want to use it or don’t need to then just don’t import it :smiley:

With respect to specifically writing python scripts in Grasshopper, then I can see people shifting over to just using the components module and not any rhinoscriptsyntax; but again that is their choice and they can mix and match how they please.

You could set up a display callback (conduit) and draw preview versions of the geometry in your script. That is pretty much exactly what Grasshopper does.

thanks for your reply. I forgot about those, I normally don’t use dimensions nor layouts but that’s just me.

-Miguel

I’m going to have to stop using Voronoi for examples, but just this one last time since it is so easy to expand on the first example. Here’s one that creates preview geometry

import rhinoscriptsyntax as rs
import ghpythonlib.components as ghcomp
import scriptcontext, Rhino, System

def MakeVoronoi():
    points = []
    curves = []
    color = System.Drawing.Color.Red

    def GetPointDynamicDrawFunc( sender, args ):
        if curves:
            for curve in curves:
                args.Display.DrawCurve(curve, color, 1)
        if points:
            args.Display.DrawPoints(points, Rhino.Display.PointStyle.ControlPoint, 2, color)

    gp = Rhino.Input.Custom.GetPoint()
    gp.DynamicDraw += GetPointDynamicDrawFunc
    gp.AcceptNothing(True)
    while True:
        getresult = gp.Get()
        if getresult != Rhino.Input.GetResult.Point:
            if getresult == Rhino.Input.GetResult.Cancel:
                curves = None
                points = None
            break
        points.append(gp.Point())
        curves = ghcomp.Voronoi(points)

    if curves:
        for curve in curves:
            scriptcontext.doc.Objects.AddCurve(curve)
    if points:
        for point in points:
            scriptcontext.doc.Objects.AddPoint(point)
    scriptcontext.doc.Views.Redraw()
    
if __name__ == "__main__":
    MakeVoronoi()

What’s really annoying about this is that I have this lovely script which I often use for polyline point reduction with a couple of hundred lines of code that I painstakingly wrote a few years ago - basically adapting David’s published vb.net Douglas-Peucker algorithm in Rhinoscript - and now you’ve gone and replaced it with something like 3 lines of code (calling the Reduce component)… :sob:

–Mitch

You can still write 97 lines of comments

Hi,

I think a found a small bug, I’ve been using ghcomp, and I was trying to offset a curve but apparently Grasshopper has 2 components called offset(one is for curve and the other one is for the surface). In this case ghcomp.offset() represents the surface offset.

Can someone confirm I’m right/wrong?

-Miguel
Ps. this also applies to offset loose

That’s probably correct. There is no strict unique naming for grasshopper components, so we’ll need to come up with a technique for dealing with these overlapping names. I don’t have a solution for this at the moment.

Hi Steve, Giulio,
On running your first Voronoi sample, it works (cool!) but I am getting the following error message on the command line afterwards:

<string>:1: DeprecationWarning: GH_PersistentParam[GH_Point].AddPersistentData has been obsoleted. This method has been superceded by SetPersistenData overloads

Just reporting here, don’t know what needs to be done…

–Mitch

LOL!

Yep, this warning is coming from Grasshopper and is something @DavidRutten said he would fix

Is this the right topic to ask questions on ghpythonlib.components functions, or should I open a new one in “scripting” section?

I am having difficulties with identifying the second output for “SortList” function. Autocomplete does not appear:

import ghpythonlib.components as ghc

# first output
listOfKeys = ghc.SortList(k,v).keys 

# what is the second output??
listOfKeys = ghc.SortList(k,v).?

In explanation there stands “values a”, but there is a space between “values” and “a”:

Help on function SortList in module ghpythonlib.components:

 |  SortList(*args, **kwargs) |      
 |      Sort a list of numeric keys.
 |      Input:
 |      	keys [Number] - List of sortable keys
 |      	values a (in, optional) [Generic Data] - Optional list of values to sort synchronously
 |      Returns:
 |      	keys [Number] - Sorted keys
 |      	values a [Generic Data] - Synchronous values in A

?

EDIT: Ok, just went onto Steve’s reply on this issue, here. Treat an output like a tuple.

Still I am curious what is the name of the SortList’s second output?

you can try

keys, valueA = ghc.SortList(k,v)

Thanks Miguel.
I know how to unpack a tuple.
I just want to know what is the exact name of that second output.

I cannot look it up now, but i would just check the exact full name that the gh component gives out.

“Values A”.
But neither “ValuesA”, “valuesA”,valuesa",“Values”, “values”, “v”, “a” worked.

This is probably something that Mcneel needs to fix. The names/input/output for the grasshopper components were not design for this use (getting access via scripting). As I posted before there are two different offset components (curve and surface) and at the moment you only get access to one of them. I would think part of the naming of the grasshopper components need to be changed. Hope this helps, meanwhile you can always unpack the values.

best,
Miguel

Agree. And autocomplete of outputs might be a nice feature too.

Hi Steve,

your example for “caping an open brep” does lead to the error message “Guid is not iterable traceback”

import ghpythonlib.components as ghcomp
import ghpythonlib.parallel

def add_caps_for_open_breps(brep):
return ghcomp.CapHoles(brep)

if parallel:
volumes = ghpythonlib.parallel.run(add_caps_for_open_breps, breps, True)
else:
volumes = ghcomp.CapHoles(breps)

Could you please give me a hint how to solve that?
Thanks
Thorsten