I have posted before explaining how I use a StreamDeck with Rhino 8 Mac to standardize my process of creating construction logistics. I choose to use a pair of StreamDeck devices but this process could easily migrate to a programmable keyboard or auxiliary keypad.
I have also researched this topic within the discourse but haven’t really found my direct answer.
Situation:
I have an ever increasing library of blocks (>500 and growing) that I insert depending upon the story I’m trying to tell. I also have a very strict layering and export logic that I use in every one of my compositions. I have a master Python script I run that populates the layer structure automatically each time I start a new deliverable. The script eliminates the need to create/modify a template file if I need to add a new layer in my process as I can just add another layer to the code and it will become my new standard.
The “robotic” component of my block insertion consists of setting the appropriate layer and then inserting the appropriate block (I may do this numerous times per hour). After insertion, I position said block to support the point I am making.
Currently to support this part of my process I have an alias defined for each block insertion and all my blocks are in a global path so I don’t define a specific path per block. Currently when I need new master blocks, I have an external Alias library file that I edit to add the logic to insert new blocks, and then reimport it to override the current production copy. Then I create a new “button” to call that alias within StreamDeck. This permits me to retain a recovery copy in the event of some catastrophic failure within Rhino. As you can imaging my Alias file is quite long and at some point I fear it will impact Rhino’s performance or I may run into some limit for the Alias function. It’s also a real pain to edit/update.
In the past (other Cad softwares) I could construct a “library sub routine” that I could call from the command line which made use of 2 arguments. “Arg1” could be the name of the block to insert and “Arg2” could be the layer of insertion.
This would look like (ins_block “Block_Name” “Layer_to_place_block_on”). I could assign this to a device key for each block I needed.
Is this even doable in Rhino Mac?
Can you run an external Python script and pass it arguments from the command line without using an Alias?
Thanks Martin but I really don’t want (don’t want to take time) to deal with or learn Grasshopper. I have extensive coding experience with other languages but I’ve done it so long I’m sick of it and only code to the minimum effort needed. I’ll leave that to the younger and more enthusiastic folks like yourself. I was hoping to pass args to Rhino python using my StreamDeck to the command line.
If I can get this to work I can expand it to do things like coding the automation of my export process to generate each of the individual context elements so I can stack them in my composition/annotation software.
I do appreciate your response to this and my older StreamDeck post though.
You’ve mapped your catalogue of Rhino aliases to keys on your StreamDeck device. And each alias places a block it references at a target point that you define manually in a Rhino viewport.
Now you want to be able to define a custom name and layer for the block to be placed with maybe an external Python script.
Is that about right or have I misunderstood something?
That is correct. I’d like to pass the sub-routine and the arguments to the Rhino 8 Mac command line in a concatenated command string as if I typed it directly with the keyboard.
What I imagine is to construct something like:
! _-RunPythonScript “Ins_Block” “Blockname” “Layer_to_Insert_On”
“Ins_Block” would be the external Python script
“Blockname” would be the first argument passed
“Layer_to_Insert_On” would be the second argument passed
Examples:
! _-RunPythonScript “Ins_Block” “BarJoist” “Structural_Framing”
Would insert the BarJoist block on the Structural_Framing layer
! _-RunPythonScript “Ins_Block” “Concrete_Form” “FormWork”
Would insert the Concrete_Form block on the Formwork layer
Python script and blocks are in a global path already established for each new file.
I would assign this to a StreamDeck button by copying an existing button and simply modifying the block and the layer name in the new button. This permits me to simply reuse the core code and substitute a new block name and the target layer each time I integrate new blocks. I have messed around with this and can’t seem to get it to work but I am fairly new to Python scripting and what Rhino permits you to do in a command line. I also don’t know if GrassHopper will permit this type of external automation.
My goal is to eliminate the need to create/maintain hundreds of alias.
In the code you supplied if I try to run it as-is (before I modify/expand it) from within the script editor, as expected I’m prompted for the block_name and the layer_name, When supplied they show up in the command history as I would expect.
If I try to send it down the Rhino Mac command throat via a StreamDeck button:
-RunPythonScript “~/Ins_Block.py” 0CautionBoard Target
Ins_Block.py is the script in the global python directory
0CautionBoard is the block argument
Target is the layer name
When I run it from StreamDeck the command history looks like:
Or at least make sure you don’t get the ‘intelligent’ inverted double quotes the Mac likes to put in there. They need to be straight double quotes " and ". In your post you have “ and ”.
What happens when I run it is that the finder search window pops up for me to select the python script to run. The script does reside within the directory and is of the proper name.
I experimented with the launch string removing the quotes and have modified it to pass:
RhinoApp.RunScript(“-ScriptEditor R Ins_Block.py BlockName LayerName”, true);
The command history now shows the following but fails on argument 1, ignores layer name and fails on True. I will experiment with different combinations of quotes to see if I can find the right syntax.
It seems like we are making some progress as it’s not hanging within the command line.
You enter the command/string you want the button to pass (macro) and when you hit the button this is what is typed to the command line.
Sorry I didn’t explain this. Basically when you create a button/macro, you define the button as some standard function like in this instance text. It’s similar to the Alias in Rhino in that it passes this just like it was typed and adds a return if specified.
I remember you have used a programmable keyboard in the past. Have you ever programmed/tested a similar sequence into one of the keys? I would assume it would operate in a similar fashion on the Mac.
It’s really only preloading everything and then sending it as a string.