Selecting one thing in a macro

I am trying to automate some simple repetitive tasks, and a lot of the time, I can eliminate hitting the enter key. For example, the following will select by color then wait for me to pick exactly one object to trim, then move on without me needing to hit enter.

_-SelColor
RGBA
251
203
120
0
_-Trim
_Pause
_Pause
_Enter

I need two _Pause because the first on is in the place where I would select the cutting objects. This all works fine, as long as I have some way to pre-select the cutting objects.

I’m trying to figure out how to do something similar, but I want to pick one surface myself then trim 4 surfaces to it… and not hit enter after the first surface.

I thought that this should work…

_-Trim
_Pause
_Enter
_Pause
_Pause
_Pause
_Pause
_Enter

But it doesn’t. The first pause does wait for me to pick an item, but the enter after the pause doesn’t come in until after I hit enter myself, and that’s what I am trying to avoid. It should start the trim function, let me select one cutting edge, then hit enter for me, then let me pick four things to trim, then hit enter again… Apparently _Enter only works at the end of a function, but where I put it here should have worked.

So I tried:

_-Select
_Pause
_Enter
_-Trim
_Pause
_Pause
_Pause
_Pause
_Pause
_Enter

But this doesn’t work either, _-Select waits for me to hit enter myself before moving on.

How can I select exactly X number of things and make the script move on without me hitting enter?

Why doesn’t using _Enter on the first part of the macro work the same way that it does on the second part? That seems like a bug to me, but it seems to always happen that way, no matter what function I am using so I’m guessing there is some reason for it.

This is just an example, I it comes up all the time, I want to start some random function, pick X number of things, have it hit enter for me, then pick Y number of other things, then hit enter again. I suppose a Python Script would not have this issue, but a lot of these macros I have are things that will ever only be used for a relatively small number of operations, and then they will never be needed again, it’s not worth the time it would take to write and test a python script, so it would be great to find a solution to this issue.

dear @James_Richters

… not sure what the big advantage of omitting enter pressing…

but one simple approach would be, to encapsulate the macro inside a phyton script…
the scirpt still should be finetuned with some error handling…

by encapsulating im mean calling a macro for the main functionality, but use some phyton script to do the selections…

@pascal is a great macro expert …

import rhinoscriptsyntax as rs

# prepare command string that selects num objects
num = 4
msg = "pick "+str(num)
objs = rs.GetObjects(message=msg,minimum_count=num,maximum_count=num)

selstr = ""
for id in objs:
    selstr = selstr + "_selID " + str(id) + " "
    
# prepare a lot of _pause _pause _pause....
trims = 4
trimstr = ""
for i in range(0,(trims+1)):
    trimstr = trimstr + "_pause "

# the main macro using both above
macrostr = "_selNone " + selstr + "_-Trim " + trimstr +  "_enterEnd"
# call the macro
rs.Command(macrostr)

you could also implement your own command
“select number of objects”
and then call this within a macro…

I hope i understood correctly what you re after…
my simple testscenario

image

trimming 1 to 4 surfaces with one green object (left)
trimming 1 to 4 surfaces with 4 red objects (right)

hope this helps - kind regards -tom

Hi @Tom_P

When I am able to get a script to work where I can just click on things in the sequence without hitting enter, I can get through a lot of them in a short time. but if I need to do click click click enter click click enter click click click click enter… it just l slows me way down, especially if I get out of sync and have to start all over.

Here is an example… I have a lot of these to do, the lengths and angles are all different but it’s the same thing over and over. I need to pick one surface to delete, and I need to pick one surface to trim the four to the color of the blue diagonal surface is always different but it’s on the same layer as everything else, so I just need to pick it myself.

Here is my Script for that

!_Blockedit
_Pause
_-SelColor
RGBA
251
203
120
0
_-TRim
_Pause
_Pause
_Enter
_-SelNone
_-Select
_Pause
_Enter
_-Delete
_-Select
_Pause
_Enter
_-Trim
_Pause
_Pause
_Pause
_Pause
_Pause
_Enter

Example.3dm (295.5 KB)

Again, this is just an example, sometimes I want to select 3 things and rotate them all, or select 1 thing and copy it 7 times, it could be anything.

I have some macros that work the way I want, like if I want to extend a plane in 4 directions, by specific distances, I can just pick the 4 edges in the correct sequence and have the macro enter in the distances for me, so I run the script, click on each edge once and it’s done. it’s WAY faster than if I use extend-repeat, need to click an edge, type the distance click and edge, type the distance, etc. If I had to only do 3 things, it would not be worth writing a macro for, but if I have to do 60 things, then it saves a lot of time. I’ve found that I can process these tedious tasks much faster when I can avoid the keyboard all together… and the best ones are the ones that the macro does everything, but things like trim I need to make a selection, there just isn’t an easy way around that.

That sounds like a great idea, then I could stick the selection script in wherever I need it. I will give it a try. I thought I could not run a python script in with a macro, but I think it’s only using the Rhino.RhinoApp.RunScript() in the python script that’s the problem.

I would say at this point it might just be easier to write a full script and forget trying to run a macro inside a script. Macros are useful for stringing short commands and options together, but as soon as you get even a bit more complicated, you will spend more time trying to get a macro to run correctly then writing a script.

1 Like

Hi @Helvetosaur,
I think you are right, unfortunately I’m at this intermediate point where I can do a few basic things in python scripts, so I’m still on the steep portion of the learning curve. If I just keep doing RunCommand() in python, then I really can’t do anything different than I could have done in a Macro. But I have no idea t know how to implement things like Trim with something like TrimSurface() if that even does the same thing. The example only asks to select an object to split, but doesn’t ask for a cutting object… so… ???

It seems like trimming one surface with another without resorting to RunCommand() is not as easy as just running some command that does the same thing as _Trim.

If I had the time to learn python scripting more, then I would eventually get fast enough at it, but right now every little thing takes me quite a while to figure out. It’s worth it for things that I will end up needing to do a great many times, like preparing and exporting geometry for my CAM program, the time spent figuring out a python script for that was well worth it.

Putting a Python Script in a Macro at any position other than the top doesn’t seem to work at all… it just doesn’t wait for you to do anything, it just skips over it.

Hi @Tom_P

I got your idea to work. I can’t continue with Macro commands after I start a python sctipt, but I can do rs.Command()s inside the python script easy enough. In particular I like the ability to make custom prompts!

The only command I don’t like doing with Python is BlockEdit because it puts this annoying dialog box on the screen that you must acknowledge.
image

I know it’s just telling me there is no command to close blockedit, but it seems like there would be a way to suppress this.

Anyway Doing the Blockedit before the python script doesn’t generate this message, so I just do that first.

I also saw there was an option for rs.GetObjects() to have the objects selected with select=True as an argument, so I was able to simplify things a bit by just turning that on. I see there is rs.GetObject() that just gets one object, but I left it the way it was because that way I can copy this and modify it into something else and I won’t need to look up how to select fixed numbers of things. Here is what I ended up with:

_Blockedit _Pause 
_-RunPythonScript (
import rhinoscriptsyntax as rs
rs.Command("_-Layer On Divisions::Shim _Enter")
rs.Command(" _-DupFaceBorder Pause _Enter")
rs.Command("_PlanarSrf")
rs.Command("_Delete")
rs.Command("_-Layer Off Divisions::Shim _Enter")
rs.Command("_-ExtendSrf _Pause 3 _-ExtendSrf _Pause 3")
rs.GetObjects("Select New Surface",minimum_count=1,maximum_count=1,select=True)
rs.Command("_-MatchProperties Pause  Pause Enter")
rs.Command("_-SelNone")
rs.Command("_-SelColor RGBA 251 203 120 0")
rs.Command("_-TRim _Pause _Pause _Enter")
rs.Command("_-SelNone")
rs.GetObjects("Select Old Surface to Delete",minimum_count=1,maximum_count=1,select=True)
rs.Command("_-Delete")
rs.GetObjects("Select New Surface",minimum_count=1,maximum_count=1,select=True)
rs.Command("_-Trim _Pause _Pause _Pause _Pause _Pause _Enter")
)

I’m pretty happy with how it works, the only issue with this is that I have to hit enter after _-DupFaceBorder, but at least it’s at the beginning.

I tried to duplicate that in python, hoping I could select just the one surface, but I can’t get it to work. _-DupFaceBorder is able to create boundary curves even if the selected face is inside a block, I don’t need it for this example, but I use that all the time, many times I need to extract surfaces from outside a block and leave them out of the block, and this does the job, I just wish I had a method of doing this that would let me pick a specific number of surfaces to duplicate.

I made a sample drawing demo to see how I might get this to work in python without needing to hit enter after the selection.

Extract Test.3dm (40.0 KB)

with this macro I can duplicate individual surfaces from a polysurface that is inside the block

! _-DupFaceBorder MultiPause
_PlanarSrf
_Delete

Anyone have any idea how I can do this for either one surface or a fixed number of surfaces without hitting enter when I’m done? I’ve tried all kinds of things, but I can’t figure out how to do it without editing the block, and exploding the polysurface, neither of which I need to do with _-DupFaceBorder

This only works for planar surfaces, but for now that’s all I need, but it would be nice to maybe figure out a way to duplicate a non-planar surface from inside a block without editing it.

If there was a way to close a block from a script, it would be easy, you could just do a blockedit, get whatever you want, explode things as needed, end up completely destroying the block if that’s what it takes, copy what you want to the clipboard, close the block without saving anything, then nothing you did mattered and you don’t need to keep track of anything. Then just paste the thing you want to extract. I do this kind of thing manually all the time, but I can’t automate that because you can’t close the blockedit with a script or a macro.

There needs to be 2 ways to exit blockedit from a script, one that is like hitting the X and one that is like hitting OK

Anyway, sometimes I use 2 macros back to back… so I can exit blockedit between them, but that’s kinda risky if I meant to hit the X and hit ok instead and didn’t realize it until much later. but doing this in a script would be 100% reliable, it would never hit the wrong one.

Hi James - My guess is ExtractSrf (Copy=Yes) could be made to work with block instances. I’ll get that on the pile.

-Pascal

Hi @pascal

That would be really great! I am doing this kind of thing constantly. For 3D Machining I need surfaces that are the same as the model surfaces, except they need to be extended in various ways so the cutter with some diameter can start before the part and cut past it. So, I have an export procedure where I bring in blocks with my parts and then I want to extract the surfaces from within the block without editing it to create these work surfaces. I need to do something similar to create containment contours as well.
The point of explaining this is that for me, this is not a one-off situation, I need to do this constantly for every project that requires 3D machining, so putting it on the list is VERY much appreciated!

Dear @James_Richters
I think it is to much what you expect from getting out of a macro…
feels a bit like “bricolage automatisation” vs. programming.
you will spend to much time, and in the end you have some toolbars that are hard to maintain / reuse / deploy / document…
develop a set of phyton scripts or your own plug-in - or pay somebody do it for you would be the right approach i recommend.

kind regards -tom