Isolate in a macro

Hey everyone,

Sorry to bring up an old issue, but I believe it’s crucial to revisit the Isolate command’s functionality in macros. This command is extremely useful for precise selection control in macros, ensuring that only the needed objects are selected, and any unnecessary outputs can be selected and removed.

It’s been five years since this issue was first reported. The common workaround of using _invert _hide doesn’t suffice, particularly when there’s only one object in the document. Other methods like _Hide _HideSwap also have their drawbacks, as they affect the currently hidden objects in the document. So far, I haven’t found an alternative that works in all cases.

My understanding is that the Isolate command functions by running _invert _hide in the background, which is why it’s incompatible with macros. I am currently attempting to tackle this issue myself, which I hope will encourage McNeel to revisit this longstanding problem.

I studied the original Isolate and Unisolate code examples, which served as the foundational versions for these commands in Rhino. Using these examples and knowing the fact that the current versions of these commands in Rhino are simpler, I have rewritten these commands to enhance their functionality in macros.

public class IsolateCommand : Command
{
    public override string EnglishName => "IsolateCommand";
    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        var filter = new ObjectEnumeratorSettings
        {
            NormalObjects = true,
            LockedObjects = false,
            HiddenObjects = false,
            ActiveObjects = true,
            ReferenceObjects = true
        };
        var rhObjects = doc.Objects.FindByFilter(filter);
        var go = new GetObject();
        go.SetCommandPrompt(Localization.LocalizeString("Select objects to isolate", 248));
        go.GroupSelect = true;
        go.SubObjectSelect = false;
        go.GetMultiple(1, 0);
        if (go.CommandResult() != Result.Success)
            return go.CommandResult();
        if (go.ObjectCount == rhObjects.Length)
        {
            RhinoApp.WriteLine(Localization.LocalizeString("Unable to isolate, all objects were selected.", 273));
            return Result.Nothing;
        }
        foreach (var rhObj in rhObjects)
        {
            if (rhObj.IsSelected(false) != 0 || !rhObj.IsSelectable()) continue;
            if (doc.Objects.Hide(rhObj, false))
                IsolatePlugin.Instance.Bucket.Add(rhObj.Id);
        }
        if (!go.ObjectsWerePreselected)
        {
            for (var i = 0; i < go.ObjectCount; i++)
                go.Object(i).Object()?.Select(true);
        }
        doc.Views.Redraw();
        return Result.Success;
    }
}
public class UnIsolateCommand : Command
{
    public override string EnglishName => "UnisolateCommand";
    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        foreach (var id in IsolatePlugin.Instance.Bucket)
            doc.Objects.Show(id, false);
        IsolatePlugin.Instance.Bucket.Clear();
        doc.Views.Redraw();
        return Result.Success;
    }
}
public class IsolatePlugin : PlugIn
{
    public IsolatePlugin()
    {
        Instance = this;
        Bucket = new List<Guid>();
    }
    public static IsolatePlugin Instance { get; private set; }
    public List<Guid> Bucket { get; set; }
    protected override LoadReturnCode OnLoad(ref string errorMessage)
    {
        RhinoDoc.CloseDocument += (o, e) => Bucket.Clear();
        return LoadReturnCode.Success;
    }
}

IsolatePlugin.zip (163.0 KB)

@pascal @dale @wim

2 Likes

Hello- Isolate uses hide buckets - the -Hide command, with a dash in front, gets you access to this feature.

-Pascal

1 Like

Hello @pascal,

Thank you for your reply. I am aware of the hide bucket feature and tried to implement something similar in my versions of the Isolate and Unisolate commands:
IsolatePlugin.rhp (40 KB)

I reviewed previous discussions where you, @wim and others suggested using _Invert _-Hide "Isolate". But this method has a problem – it doesn’t work if the document has no other objects. Here’s a macro to show this:

_Select _Pause _Invert _Hide _SelCrv _ExtrudeCrv 1 _UnrollSrf _SelLast _SelPrev _Enter _SelSrf _Delete _Show

If there are multiple visible objects in the document, it works flawlessly:

But if there are no other visible objects, _Invert _Hide doesn’t work as expected:

This macro is just an example, and there might be better ways to write it.
The issue of isolate running scripts in the background leads to numerous problems:
https://mcneel.myjetbrains.com/youtrack/issue/RH-46090/Macros-and-Isolate
https://mcneel.myjetbrains.com/youtrack/issue/RH-58975/SelectionFilter-Single-filter-settings-and-Isolate-do-not-get-along
https://mcneel.myjetbrains.com/youtrack/issue/RH-74751/Isolate-opens-Filters
https://mcneel.myjetbrains.com/youtrack/issue/RH-72881/Panels-Isolate-makes-the-Filter-panel-appear
https://mcneel.myjetbrains.com/youtrack/issue/RH-57579/Undo-breaks-Unisolate

Interesting, learnt something new today :handshake:

1 Like