Isolate elements sequentially (bug? or pushing too far?)

Isolate elements sequentially (bug? or pushing too far?)

Anonymous
Not applicable
689 Views
9 Replies
Message 1 of 10

Isolate elements sequentially (bug? or pushing too far?)

Anonymous
Not applicable

I wanted to do something that seemed simple:

1. allow the user to select some elements

2. show those elements sequentially in isolation allowing the user to pick something on each before showing the next

 

I thought this would be a cool way to guide the user to picking something on the actual element of interest... (so much for good intentions)

 

Note, that this works great with one element only.  As soon are there are mulitple, it's not so great (after isolating the second element, it hides the first and shows all other elements in the view)

 

Am I asking too much to do successive hide/isoates within one command, is this a wish, or possibly a bug?

 

Sample Code:

 

Note: I've also tried:

1. putting a transaction group around this and committing each transaction for each isolate and disable.

2. calling regenerate just before committing the transactions

3. calling activeView.Refresh after setting isolate

4. banging rythmically on the top of the computer (/jk)

 

using System;
using System.Collections.Generic;
using System.Linq;

//Autodesk
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;


namespace ViewIsolationIssue
{
    [Transaction(TransactionMode.Automatic)]
    [Regeneration(RegenerationOption.Manual)]
    public class IsolateThingsSequentially : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Autodesk.Revit.UI.UIDocument UIDoc = commandData.Application.ActiveUIDocument;
            Autodesk.Revit.DB.Document revitDoc = UIDoc.Document;
            Autodesk.Revit.DB.View activeView = UIDoc.ActiveView;

            //Get selected instances
            IEnumerable<FamilyInstance> selectedInstances =
                new FilteredElementCollector(revitDoc, UIDoc.Selection.GetElementIds())
                    .OfClass(typeof(FamilyInstance))
                    .ToElements()
                    .Cast<FamilyInstance>();

            //For each selected assembly, sequentially isolate it for the user to pick a face
            foreach (FamilyInstance famInst in selectedInstances)
            {
                //Isolate instance
                if (activeView.CanUseTemporaryVisibilityModes())
                    activeView.IsolateElementTemporary(famInst.Id);
                //The first one works perfectly the rest... not so much...

                //Allow the user to pick Face
                Reference pickedFaceRef = UIDoc.Selection.PickObject(ObjectType.Face, "Select Face.");

                //Reset the temporary hide/isolate mode
                if (activeView.CanUseTemporaryVisibilityModes())
                    activeView.DisableTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate);
            }
            return Result.Succeeded;
        }
    }
}

 

Thoughts?

 

Happy Friday,

-Ken

690 Views
9 Replies
Replies (9)
Message 2 of 10

Anonymous
Not applicable
Try building a list of ids one at a time and then pass the full list to the isolate command at each iteration. There is either an overload or similarly named method that takes a list of ids as input.
0 Likes
Message 3 of 10

jeremytammik
Autodesk
Autodesk

Another cool trick to keep up your sleeve to regenerte an element is to move it, either by a zero vector, or back and forth by a non-zero one:

 

http://thebuildingcoder.typepad.com/blog/2011/07/refresh-element-graphics-display.html

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 10

Anonymous
Not applicable
Hi Scott,
Thanks for the idea. There is a method that takes a list of Ids and the real function actually isolates an assembly which requires getting the underlying ids. So I've tried with multiple ids as well. I just wanted to simplify this as much as possible for this discussion. The problem is still that I don't want to isolate *all* the elements in question, just one at a time so that the user is focused to the one particular element that they are supposed to do something with. (pick a face).
0 Likes
Message 5 of 10

Anonymous
Not applicable
Hi Jeremy,
This might be an interesting workaround. My first thought was that this should be something about the view but I suppose that the view might wind up in the dependency tree for an element regeneration and Revit might be trying to be smart about not actually regenerating the view (regardless of us asking it to do so) unless something serious happens like an element regen.

Forcing regen of an element seems like a bit of a sledge-hammer when it "seems" like we're really just asking the view to show something different. It smells like a bug but I'm not sure if trying to repeatedly apply temporary view modes during a command in conjunction with using the pick object method is just asking for trouble...
0 Likes
Message 6 of 10

Anonymous
Not applicable
Sorry I thought you wanted to isolate all of the elements one at a time. What about putting each isolate and reset within its own transaction?
0 Likes
Message 7 of 10

Anonymous
Not applicable
Oh nevermind just saw that you tried that already...
0 Likes
Message 8 of 10

Anonymous
Not applicable
Right, even tried calling regenerate within each and to no avail. I was hoping Aaron or Arnost would take a look at it but I may have to run it through channels as it's already been marked closed. Seems like it should work. I haven't tried the zero-move trick yet but I'm not sure that I want to do that just to get multiple isolation to work. It works the first time for sure, just not sure why it won't work the second time through the loop.
0 Likes
Message 9 of 10

Anonymous
Not applicable

how about switching to another view and then back at each iteration?

0 Likes
Message 10 of 10

jeremytammik
Autodesk
Autodesk

Here is an official Revit SDK sample that demonstrates how you can update elements and regenerate the display using a whole sequence of separate transactions within one single external command: DisplacementElementAnimation.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder