Processing to rhino/Grasshopper

Hi,

I was wondering if there is any way to connect Processing and Rhino/grasshopper together. I am interested to write the code and generate geometries in processing and later transfer the geometries into Rhino/Grasshopper. It could be real-time (would be nice to get that) or anything else. If there is any way to do it then would be really very appreciated if you could let me know.

Furthermore, do I need to work in Processing 3d in order to generate transferable geometries? If so then also would like to know about the procedure as well.

Thanks!

1 Like

Hi @Shruhman,

Yes, it is possible to connect Processing with Rhino/Grasshopper and the way people usually do it is by sending UDP sockets via OSC protocol. For that you will need to install:

  • OscP5 for Processing (client side)
  • gHowl for Grasshopper (server side)

However there are 3 main limitations to this kind of set-up:

  • because of the difference of format between the two environments (PVector vs Vector, PShape vs Surface, Mesh or Polyline, etc), each geometry must be broken down to a set of coordinates.

  • these coordinates can be sent via 1D arrays only. 2D arrays will automatically be flatten.

  • UDP packet length is reached very quickly and cannot allow for the transfer of large amount of coordinates (<1000 points per message).

In other words, not only the geometry you chose to send must be limited in size (coordinates data) but it also needs to be reconstructed upon reception.

First example: The vertices of a polygon (list of PVectors) are converted one by one as tuples (x and y coordinates as floats) and sent in a single message from Processing to Grasshopper. Upon reception the 1D array is transformed to a “data tree” with branches of size 2 using the Partition List component. Points are then reconstructed and used as input vertices to form a closed “polyline”.

Processing sketch (Python mode)
add_library('oscP5')

verts = [PVector(228, 131),PVector(233, 142),PVector(188, 141),PVector(280, 168),PVector(266, 149),PVector(297, 142),
         PVector(291, 163),PVector(322, 180),PVector(288, 173),PVector(325, 196),PVector(339, 225),PVector(387, 214),
         PVector(443, 169),PVector(491, 160),PVector(560, 208),PVector(608, 268),PVector(636, 270),PVector(664, 308),
         PVector(650, 446),PVector(667, 472),PVector(661, 459),PVector(676, 467),PVector(680, 450),PVector(666, 423),
         PVector(707, 447),PVector(686, 495),PVector(671, 495),PVector(731, 580),PVector(748, 584),PVector(734, 557),
         PVector(766, 560),PVector(755, 569),PVector(764, 617),PVector(789, 594),PVector(773, 624),PVector(791, 628),
         PVector(813, 700),PVector(862, 708),PVector(891, 759),PVector(922, 780),PVector(911, 788),PVector(891, 773),
         PVector(907, 799),PVector(967, 774),PVector(984, 782),PVector(998, 689),PVector(1005, 678),PVector(1010, 695),
         PVector(1004, 555),PVector(888, 338),PVector(874, 294),PVector(889, 316),PVector(907, 314),PVector(912, 366),
         PVector(915, 322),PVector(825, 196),PVector(767, 61),PVector(779, 59),PVector(773, 43),PVector(711, 33),
         PVector(703, 98),PVector(681, 72),PVector(375, 83),PVector(353, 46),PVector(55, 70),PVector(90, 144),
         PVector(70, 165),PVector(97, 154),PVector(107, 125),PVector(119, 139),PVector(126, 118),PVector(142, 139),
         PVector(109, 152),PVector(189, 124)]


def setup():

    osc = OscP5(this, 12002) 
    net = NetAddress("127.0.0.1", 12002) #remote location 
    message = OscMessage("/gHowlTest")
    for v in verts:
        message.add((v.x, v.y))
    osc.send(message, net)

Second example: At each iteration of a simple Line Growth algorithm the connectivity information of all the vertices (whole list of indices as integers, no coordinates) is sent from Processing to Grasshopper. Upon reception indices are grouped back to couples and used to construct lines. All the physics (springs + repulsive force) is then handled by the Kangaroo plugin.

Processing sketch (Python mode)
add_library('oscP5')

a = [(0, 1), (0, 2), (1, 2)] 
z = 3 

def setup():
    global osc
    osc = OscP5(this, 12001) 
    
def draw():
    global z
    
    if z <100:
        id = int(random(z)) 
        x, y = a[id] 
        del a[id] 
        a.extend([(y, z), (z, x)])
        z += 1 
        
        net = NetAddress("127.0.0.1", 12001) #remote location 
        message = OscMessage("/gHowlTest")
        message.add(sum(a,()))
        osc.send(message, net)

For the transfer and the reconstruction of meshes, see this past post of mine on a similar topic.

Grasshopper file

4 Likes

Hi @Shruhman ,

Welcome to the forum! :wink:

Basically if you want to transfer geometry data from one software to another, you will need a common file interchange format like OBJ, FBX, STL, STEP…

For this you can take a look at the 3d libraries available in Processing :

https://processing.org/reference/libraries/#3d

Also the OBJ export library :

https://n-e-r-v-o-u-s.com/tools/obj/

And as @solub said, you can instead talk to Grasshopper via the OSC protocol which remove the tedious export / import part and you can send grasshopper specific instructions rather than exporting a baked geometry from processing.

1 Like

@Shruhman I am facing same error with rhino/Grasshopper. Is anybody know where i did mistake. If anybody want to help reply. Then i send the query to him. :joy:

Hi @solub, this is great, and thanks for sharing the knowledge. Let me try the methods. I am hoping to follow the steps properly. Thanks a lot once again!

1 Like

Hi @josephh, Thanks a lot! I will also try these methods. Let me see what would be the best thing to go for. I am still exploring processing though. Thanks once again!

1 Like