1 Reply Latest reply on Feb 18, 2016 4:46 AM by Johannes Kronberger

    How to select all objects returned by IMacroFeatureData:GetSelections3

    Johannes Kronberger

      When one calls InsertMacroFeature3 all the current selections are stored in the created feature data automatically. However when modifying a feature I need to call

       

                          SwFeatureData.GetSelections3(out objects, out objectTypes, out marks, out drViews, out componentXForms);

       

      and then reselect all the objects. However I can't figure out a general way of doing this. There are about 100 types of objects that could be returned by GetSelections3 and all have a different API for making them selected with their marks. Is there an API call that can reconstruct the selection from the outputs of GetSelections3 without having to write specialized code for every addin?

       

      We tried the following code.

       

                      {

                          object objects;

                          object objectTypes;

                          object marks;

                          object drViews;

                          object componentXForms;

                          SwFeatureData.GetSelections3(out objects, out objectTypes, out marks, out drViews, out componentXForms);

       

                          var objectsArray = (object[]) objects;

                          var typesArray = (swSelectType_e[]) objectTypes;

                          var marksArray = (int[]) marks;

                          //var viewsArray = (IView[]) drViews;

                          //var xformsArray = (IMathTransform[]) componentXForms;

       

                          var selections = objectsArray.Select((o, i) =>

                          new {o,

                              t = typesArray[i],

                              m = marksArray[i]

                              }).ToList();

                          var selectionsByMark = selections.GroupBy(s => s.m);

       

                          foreach (var s in selectionsByMark)

                          {

                              var selectionData = SelectionMgr.CreateSelectData();

                              selectionData.Mark = s.Key;

                              var array = s.Select(o=>o.o).ToArray();

                              var count = ModelDoc.Extension.MultiSelect2(array, true, selectionData);

                              if (array.Length != count)

                              {

                                  MessageBox.Show("Unable to select objects");

                              }

                          }

                      }

       

      But MultiSelect2 always returns 0.

        • Re: How to select all objects returned by IMacroFeatureData:GetSelections3
          Johannes Kronberger

          The solution is ugly. I read somewhere about problem with COM and passing arrays of objects that may have different types. The solution is to wrap each object in a DispatchWrapper. So the code changes to

           

                              foreach (var s in selectionsByMark)

                              {

                                  var selectionData = SelectionMgr.CreateSelectData();

                                  selectionData.Mark = s.Key;

                                  var array = s.Select(o=>o.o).ToArray();

                                  var count = ModelDoc.Extension.MultiSelect2( ComWangling.ObjectArrayToDispatchWrapper(array), true, selectionData);

                                  if (array.Length != count)

                                  {

                                      MessageBox.Show("Unable to select objects");

                                  }

                              }

           

          where I have written

           

                  public static DispatchWrapper[] ObjectArrayToDispatchWrapper(IEnumerable<object> objects)

                  {

                      return objects.Select(o => new DispatchWrapper(o)).ToArray();

                  }

           

          Don't ask me exactly what DispatchWrapper does. It's evil magic.