Editing a Group Take Two

I am publishing this now, on November 11, 2011, at 11:11 my time, to celebrate this unique and yet completely arbitrary time and date in our calendar history.
I hope you appreciate it and celebrated that moment in your own way as well :-)

I discussed various aspects of programmatically handling Revit element groups in the past, such as how to

create
,

rename
,

edit
and

delete
them.

In a

comment
on
the discussion on editing groups, YarUnderoaker asked for further clarification on how to implement the ungrouping and recreation of a group to make changes to it:

Question: I cannot figure out how to do as stated in the recommendations:
“You can programmatically ungroup, make the change, regroup and then swap the other instances of the old group to the new group to get the same effect.”

Please, can you give a simple example?

Answer: My colleague Saikat Bhattacharya put together some sample code to answer this for you.
It performs the following steps:

  • Prompt user to select a group.
  • Ungroup it.
  • Create an element set of all its members except the first.
  • Create a new group using the element set.
  • Change the new group type to the old group type.

Here is the complete code to implement the mainline Execute method of the external command:


[Transaction( TransactionMode.Manual )]
public class Command : IExternalCommand
{
  public Result Execute(
    ExternalCommandData commandData,
    ref string message,
    ElementSet elements )
  {
    UIApplication uiapp = commandData.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Document doc = uidoc.Document;
 
    // Prompt user to select existing group
 
    Group grpExisting = doc.GetElement(
      uidoc.Selection.PickObject( ObjectType.Element,
        "Select an existing group" ) ) as Group;
 
    string name = grpExisting.Name;
 
    // Ungroup the group
 
    Transaction tx = new Transaction( doc );
    tx.Start( "Ungroup and delete" );
 
    ElementSet grpElements = grpExisting.Ungroup();
 
    // Create element set for new group
 
    ElementSet newgrpElements = new ElementSet();
 
    int counter = 0;
 
    foreach( Element e in grpElements )
    {
      if( 0 == counter )
      {
        // Delete the first group element
 
        doc.Delete( e );
      }
      else
      {
        newgrpElements.Insert( e );
      }
      ++counter;
    }
 
    tx.Commit();
 
    // Create new group
 
    tx.Start( "Group" );
 
    Group grpNew = doc.Create.NewGroup(
      newgrpElements );
 
    // Access the name of the previous group type 
    // and change the new group type to previous 
    // group type to retain the previous group 
    // configuration
 
    FilteredElementCollector coll
      = new FilteredElementCollector( doc )
        .OfClass( typeof( GroupType ) );
 
    IEnumerable<GroupType> grpTypes
      = from GroupType g in coll
        where g.Name == name select g;
 
    grpNew.GroupType = grpTypes.First<GroupType>();
 
    tx.Commit();
 
    return Result.Succeeded;
  }
}

I hope this clarifies the process.

Many thanks to Saikat for sharing this!


Comments

7 responses to “Editing a Group Take Two”

  1. HI,
    I’m triing to move several instances of a group. Before I move a group I have to ungroup and move it, but the problem is that when I do this code:
    Group grpNew = doc.Create.NewGroup(
    newgrpElements );
    // Access the name of the previous group type
    // and change the new group type to previous
    // group type to retain the previous group
    // configuration
    FilteredElementCollector coll
    = new FilteredElementCollector( doc )
    .OfClass( typeof( GroupType ) );
    IEnumerable grpTypes
    = from GroupType g in coll
    where g.Name == name select g;
    grpNew.GroupType = grpTypes.First();
    the instances of the group are move but there orientation that was different from each others before the “ungroup, move and regroup” is all return to the original orientation of the group.
    So I tried to only change the name of the group instead of the GroupType. This time the orientation of the instances is good, all the instances have kept there orientation but this time the problem is that when I want to regroup these instances after a move, instead of having one group and several instances of this group, I get a new group for each instances of this group. Do you think of a way to solve that?
    Thanks!
    Sorry for my english

  2. Dear Jf,
    Your English is just fine!
    I think that just changing the name is definitely the wrong approach.
    If you have multiple instances with different orientations, and they lose their orientation when you update their group type, then the solution is pretty obvious: iterate over all instances and make a note of their desired orientation. Then change the type, and iterate over them again to fix the orientation as required.
    Cheers, Jeremy.

  3. Hi Jeremy,
    Thanks for the tips. Your blog is very helpful!
    I have another problem:
    I tried to retrieve the rotation of the instances of my group with this code:
    double Rotati = 0;
    foreach (ElementId id in ids)
    {
    Element e = CachedDoc.GetElement(id);
    if (e.Group != null)
    {
    i++;
    LocationPoint Groupe_Emplacement = e.Group.Location as LocationPoint;
    Groupe_Emplacement = e.Group.Location as LocationPoint;
    Rotati = Groupe_Emplacement.Rotation;
    }

    But I can’t retrieve the rotation parameter? Is it possible to retrieve the rotation angle of a group? I also tried with an element of the group but same result… Each time it gives me an error.
    Since I wasn’t able to get the rotation angle I didn’t try to rotate the new groups but I suppose that I won’t be able to rotate them if it isn’t possible to move them?
    Thanks, JF

  4. Dear Jf,
    Est-ce que ça veut dire Jean-François?
    Thank you for your appreciation.
    I have not tried to access the rotation of a group, so I’ll take your word for it.
    I would tend to agree that if you can’t move them, then rotating them will not be possible either.
    For what little it is worth…
    Cheers, Jeremy.

  5. Ning Zhou Avatar
    Ning Zhou

    hi Jeremy,
    i just noticed the group instances created from array command cannot be swapped to old group type sucessfully, i mean the last step you mentioned:
    . Change the new group type to the old group type
    it simply throw exception, i can no longer have old group type like “Array Group 1”, my current workaround is to rename new types to something like “Array Group 1_1”, “Array Group 1_2”, “Array Group 1_3”, etc.
    did i miss something or is there a better solution? thanks.
    Ning

  6. Hi Jeremy, I have been playing with groups in the family editor with strange results.
    (1) I can’t seem to build a group that contains an extrusion and a model line
    (2) if i create a new group of extrusions and then select it…
    Group grpExisting = doc.GetElement(uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, “Select an existing group”)) as Group;
    string name = grpExisting.Name;
    The name ends up as “Group 1 (members excluded)” instead of Group 1

  7. Dear Christopher,
    Yes, I agree that sounds strange. Does issue (1) affect only the API, or only the user interface, or both? Does it hinder you in any way? What are you actually trying to achieve? For issue (2), I basically have the same questions. And for both, I have no answers at all off-hand.
    Cheers, Jeremy.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading