Selection Bug in GetObjects

Hi Rhino Team,

I keep running in problems selecting/deselecting objects in picking mode.
If there is any object pre-selected, it can not be altered in picking mode again without closing and re-opening picking mode. The problem appears both in Rhino 5 and Rhino 6, with the difference being Rhino 5 using “Version 1” and Rhino 6 using "Version 4"
“Version 4” is the best solution I could find till now, but it still is inconvenient not being able to see the pre-selected objects.
I’ve tried the four following codes snippets but none of them works as it should. (Only changes two parameters)

#########
Version 1
Original code
#########

 while (true)
            {
                go.GetMultiple(1, 0);
                if (go.CommandResult() != Rhino.Commands.Result.Success)
                {
                    return null;
                }

                var canBreak = true;
                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, false);
                    go.EnableClearObjectsOnEntry(false);
                    go.DeselectAllBeforePostSelect = false;
                    
                    canBreak = false;
                }


                if (!multiple && go.ObjectCount > 1)
                {
                    go.SetCommandPrompt("Please make sure you select one item: " + message);

                    canBreak = false;
                }

                if (canBreak)
                {
                    break;
                }
            }

Pre-selected objects cannot be selected/deselected at all

#########
Version 2
#########

while (true)
            {
                go.GetMultiple(1, 0);
                if (go.CommandResult() != Rhino.Commands.Result.Success)
                {
                    return null;
                }

                var canBreak = true;
                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, false);
                    go.EnableClearObjectsOnEntry(false);
                    go.DeselectAllBeforePostSelect = true;
                    

                    canBreak = false;
                }


                if (!multiple && go.ObjectCount > 1)
                {
                    go.SetCommandPrompt("Please make sure you select one item: " + message);

                    canBreak = false;
                }

                if (canBreak)
                {
                    break;
                }
            }

Pre-selection can not be selected/deselected. Only after deselecting all and selecting all again single surfaces can be selected again.

#########
Version 3
#########

while (true)
            {
                go.GetMultiple(1, 0);
                if (go.CommandResult() != Rhino.Commands.Result.Success)
                {
                    return null;
                }

                var canBreak = true;
                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, false);
                    go.EnableClearObjectsOnEntry(true);
                    go.DeselectAllBeforePostSelect = false;
                    
                    canBreak = false;
                }


                if (!multiple && go.ObjectCount > 1)
                {
                    go.SetCommandPrompt("Please make sure you select one item: " + message);

                    canBreak = false;
                }

                if (canBreak)
                {
                    break;
                }
            }

Pre-selected object can not be deselected at all in current picking mode. Deselection tool works as selection tool on deselected objects

#########
Version 4
#########

while (true)
            {
                go.GetMultiple(1, 0);
                if (go.CommandResult() != Rhino.Commands.Result.Success)
                {
                    return null;
                }

                var canBreak = true;
                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, false);
                    go.EnableClearObjectsOnEntry(true);
                    go.DeselectAllBeforePostSelect = true;
                    

                    canBreak = false;
                }


                if (!multiple && go.ObjectCount > 1)
                {
                    go.SetCommandPrompt("Please make sure you select one item: " + message);

                    canBreak = false;
                }

                if (canBreak)
                {
                    break;
                }
            }

Pre-selected objects can be selected/deselected, but every pre-selected object becomes deselected once picking mode is entered

Hi @karld,

Does this do what you want?

If not, then please describe what you want to do and why.

Thanks,

– Dale

Hi @dale,
Thanks for the quick response. I tested your sample code and added a List to store the selected objects and re-select them the next time picking mode is entered, but the problem still occurs. I am not able to select an object, that has been selected before. Instead there is no response at all from that object. Every other object that has not been selected before behaves normal.

using System;
using Rhino;
using Rhino.Commands;

namespace SampleCsCommands
{
[System.Runtime.InteropServices.Guid("ca2bbdc8-d1cf-4dcc-b085-97e94c1fba32")]
public class SampleCsCommandLineOptions : Command
{
    static SampleCsCommandLineOptions _instance;
    public SampleCsCommandLineOptions()
    {
        _instance = this;
    }

    ///<summary>The only instance of the SampleCsCommandLineOptions command.</summary>
    public static SampleCsCommandLineOptions Instance
    {
        get { return _instance; }
    }

    public override string EnglishName
    {
        get { return "SampleCsCommandLineOptions"; }
    }

    private System.Collections.Generic.List<Rhino.DocObjects.RhinoObject> preselectedObjectsList = new 
   System.Collections.Generic.List<Rhino.DocObjects.RhinoObject>();


    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        // Load and select here
        for (int i = 0; i < preselectedObjectsList.Count; i++)
        {
            preselectedObjectsList[i].Select(true);
        }

        const Rhino.DocObjects.ObjectType geometryFilter = Rhino.DocObjects.ObjectType.Surface |
                                                           Rhino.DocObjects.ObjectType.PolysrfFilter |
                                                           Rhino.DocObjects.ObjectType.Mesh;
        int integer1 = 300;
        int integer2 = 300;

        Rhino.Input.Custom.OptionInteger optionInteger1 = new Rhino.Input.Custom.OptionInteger(integer1, 200, 900);
        Rhino.Input.Custom.OptionInteger optionInteger2 = new Rhino.Input.Custom.OptionInteger(integer2, 200, 900);

        Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
        go.SetCommandPrompt("Select surfaces, polysurfaces, or meshes");
        go.GeometryFilter = geometryFilter;
        go.AddOptionInteger("Option1", ref optionInteger1);
        go.AddOptionInteger("Option2", ref optionInteger2);
        go.GroupSelect = true;
        go.SubObjectSelect = false;
        go.EnableClearObjectsOnEntry(false);
        go.EnableUnselectObjectsOnExit(false);
        go.DeselectAllBeforePostSelect = false;

        bool bHavePreselectedObjects = false;

        for (;;)
        {
            Rhino.Input.GetResult res = go.GetMultiple(1, 0);

            if (res == Rhino.Input.GetResult.Option)
            {
                go.EnablePreSelect(false, true);
                continue;
            }

            else if (res != Rhino.Input.GetResult.Object)
                return Rhino.Commands.Result.Cancel;

            if (go.ObjectsWerePreselected)
            {
                bHavePreselectedObjects = true;
                go.EnablePreSelect(false, true);
                continue;
            }

            break;
        }

        if (bHavePreselectedObjects)
        {
            // Normally, pre-selected objects will remain selected, when a
            // command finishes, and post-selected objects will be unselected.
            // This this way of picking, it is possible to have a combination
            // of pre-selected and post-selected. So, to make sure everything
            // "looks the same", lets unselect everything before finishing
            // the command.
            for (int i = 0; i < go.ObjectCount; i++)
            {
                Rhino.DocObjects.RhinoObject rhinoObject = go.Object(i).Object();
                if (null != rhinoObject)
                    rhinoObject.Select(false);
            }
            doc.Views.Redraw();
        }
        preselectedObjectsList.Clear();
        for (int i = 0; i < go.ObjectCount; i++)
        {
            // Save here
            preselectedObjectsList.Add(go.Object(i).Object());
        }
        

        int objectCount = go.ObjectCount;
        integer1 = optionInteger1.CurrentValue;
        integer2 = optionInteger2.CurrentValue;

        Rhino.RhinoApp.WriteLine("Select object count = {0}", objectCount);
        Rhino.RhinoApp.WriteLine("Value of integer1 = {0}", integer1);
        Rhino.RhinoApp.WriteLine("Value of integer2 = {0}", integer2);

        return Rhino.Commands.Result.Success;
    }
  }
}

What I want is to be able to see objects highlighted in picking mode that have been picked before. The use case is when you’ve made an error during picking and you want to correct it afterwards. Right now the selected objects become deselected and you have to pick them again manually. And with my workaround to save the objects, they cannot be deselected and selected again. This is especially inconvenient when you have to work with big numbers of objects.

Also, the problem seems to occur only with complex structures. A simple cube for example seems to be not affected by this problem.

Hi @karld

Try this:

1.) Select some surfaces, polysurfaces, or meshes
2.) Run the SampleCsCommandLineOptions

Select some additional surfaces, polysurfaces, or meshes.

You can un-selected objects by pressing and clicking.

This this what you want?

– Dale

Hi @dale

I keep running into the same problem with your “SampleCsCommandLineOptions” command. If there is a surface, poly-surface or mesh that has been selected BEFORE I run this command, it can only be deselected, but not re-selected again without rerunning the command again.
It is the same behavior as in picking mode that I had originally.

Maybe we talk about different things.

  1. Select a surface, poly-surface or mesh
  2. run “SampleCsCommandLineOptions”
  3. deselect the items from step 1
  4. try to select the items again

The same happens when entering picking mode again, after already have picked a surface, poly-surface or mesh, to add an item to the existing selection.

I just want to know whether this is a bug in Rhino or if there are some parameters that prevent the re-selection of items that I don’t know of.
If that is the case, I have to integrate my workaround to achieve the somewhat wanted result.

Yea sorry about that.

Try this:

https://github.com/mcneel/rhino-developer-samples/blob/6/rhinocommon/cs/SampleCsCommands/SampleCsPrePostSelect.cs

– Dale

@dale.
Yes that solved it. It shows preselected items in picking mode and lets me deselect/re-select them again
I had to tinker with the "have_preselected_objects and the redraw thou:

if (have_preselected_objects)
                {
                    if (!firstTime)
                    {
                        firstTime = true;
                    }
                    else
                    {
                        //Must only be executed once at the end of picking
                        for (var i = 0; i < go.ObjectCount; i++)
                        {
                            var obj = go.Object(i).Object();
                            obj?.Select(false);
                        }
                        Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
                    }

                }

Instead of your code part:

if (have_preselected_objects)
  {
    for (var i = 0; i < go.ObjectCount; i++)
    {
      var obj = go.Object(i).Object();
      obj?.Select(false);
    }

    doc.Views.Redraw();
  }