I’m new to Python scripting and managed to get together a few scripts that work, but I’m wondering if there might be a better way to implement them or if this is the way it should be done. If there is a better way to do things, then learning about it now would be better than writing tons of scripts in ways that could be better, so now is the time to learn.
This script is meant to export a selection to an Iges file. What I am selecting as input to this are some blocks as well as some things not in a block. The blocks are nested and there are some text objects inside one of the nested blocks that I need to explode before exporting, otherwise It doesn’t get exported because the Iges file format has no way to store text.
What I have been doing by hand is exploding 3 times, and that gets the text exploded, then exporting my file, then undoing 4 times… once to undo the export, which really does nothing, because the file has been created, and 3 more times to undo the 3 explodes.
So, I quickly found out a few things…
- Undo from inside a python script is either completely impossible, or very difficult.
- Undo after running a script undoes everything that happened in the script.
- Running anything after a script with a button doesn’t work
so my initial thought was that it would be GREAT to just undo the entire script… then I can do whatever I want, not bother to keep track of anything or make it complicated, get my file exported, then just do one undo and everything gets undone.
I do something similar in rhino all the time, I do a BlockEdit, then do whatever I want to the contents of the block to extract various geometry, and completely destroy everything in there to get what I want, copy what I want to the clipboard, then hit the X on the BlockEdit, and poof, nothing I did in there mattered at all… then Paste.
So since undoing an Export really does nothing, because the file is saved already, I can just undo my entire script, and everything is great. So I tested this out and it does work… I run the script, then run undo and it’s fine… but I want the undo to happen along with the script so I don’t have to remember to do it.
so I tried assigning it to a button like this:
! _-RunPythonScript (
import System
import Rhino
import rhinoscriptsyntax as rs
def Export_Drill():
#Restore Layer state
plugin = rs.GetPlugInObject("Rhino Bonus Tools")
if plugin is not None:
plugin.RestoreLayerState("Wall Notch")
script = "_-SelLayer \"{0}\" _Enter".format("Drill Alignment")
Rhino.RhinoApp.RunScript(script, True)
script = "_-Explode"
Rhino.RhinoApp.RunScript(script, True)
Rhino.RhinoApp.RunScript(script, True)
Rhino.RhinoApp.RunScript(script, True)
folder = r'M:\CNC_Data\Drill\2x4'
name = rs.DocumentName()
extension = ".igs"
path = System.IO.Path.Combine(folder, name)
path = System.IO.Path.ChangeExtension(path, extension)
print path
script = "_-Export _Pause \"{0}\" _Enter".format(path)
Rhino.RhinoApp.RunScript(script, True)
Export_Drill()
)
Undo
But the Undo at the end never runs… in fact nothing that I put under the script ever runs. Is there a way around this?
So, then it was suggested that I make a copy then do everything to the copy and delete the copy when I’m done, and while that is less than ideal, it does work:
import System
import Rhino
import rhinoscriptsyntax as rs
def Export_Cut():
script = "_-CopyToClipboard"
Rhino.RhinoApp.RunScript(script, True)
script = "_-SelNone"
Rhino.RhinoApp.RunScript(script, True)
script = "_-Paste"
Rhino.RhinoApp.RunScript(script, True)
script = "_-Explode"
Rhino.RhinoApp.RunScript(script, True)
Rhino.RhinoApp.RunScript(script, True)
Rhino.RhinoApp.RunScript(script, True)
folder = r'M:\CNC_Data\Cut\2x4'
name = rs.DocumentName()
extension = ".igs"
path = System.IO.Path.Combine(folder, name)
path = System.IO.Path.ChangeExtension(path, extension)
print path
script = "_-Export _Pause \"{0}\" _Enter".format(path)
Rhino.RhinoApp.RunScript(script, True)
script = "_-Delete"
Rhino.RhinoApp.RunScript(script, True)
Export_Cut()
The reason I say it is less than ideal is that after I do the paste, I have now 2 copies of everything, and if I try to do something like select by layer, I will get both copies, and if I’m not really careful with what is selected when I do the delete, I might delete some of the original geometry.
So then I thought instead of doing it that way, maybe I could have it create a block around the copy, then do a BlockEdit to do whatever to the copy, do my export, then close the BlockEdit and delete the block… this way none of my original geometry is a risk and any selections I do will only get the copy inside the block. But I tried to close the BlockEdit with a script before (not python, just commands in a button) and couldn’t figure out how to do that. I can issue the BlockEdit command… but there is no command I can give to exit BlockEdit.
So it’s starting to get complicated, the simplest solution is to just undo the entire script, but how can I accomplish that automatically?
I’m also wondering if there is a better way do make this script at all. I am basically just passing along commands to Rhino exactly the same as it would be to just stack them up in a button, except for where I am getting the document name and creating a destination for the export.
I’ve been searching though forum posts and it seems like there is some way to create geometry and work on things without commit it to the Rhino drawing, but I’m not understanding how that all works, or how I might use that to make a temporary copy that would evaporate when I end the script.
Any advice is very much appreciated.