#RTCEUR Wish 2: Override element display by View Filters

To conclude this set of 3 posts showing how to override display of elements, this shows how to create a view filter for elements with a Comments instance parameter equal to “override”. The list of element ids is used to set this instance parameter. A view filter is created and set to use this rule, the view filter is applied to the view, and the graphics of this filter is overridden.


public void viewFilter()
{
    Document doc = this.ActiveUIDocument.Document;

    OverrideGraphicSettings ogs = new OverrideGraphicSettings();
    ogs.SetCutLineColor(new Color(255,255,0));
    ogs.SetCutLineWeight(6);
    ogs.SetProjectionLineColor(new Color(0,255,255));    
    ogs.SetProjectionLineWeight(6);
    
    IList<ElementId> catIds = new List<ElementId>();
    catIds.Add(doc.Settings.Categories.get_Item("Furniture").Id);
    catIds.Add(doc.Settings.Categories.get_Item("Casework").Id);
    
    IList<FilterRule> rules = new List<FilterRule>();
    ElementId commentParamId = new ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
    rules.Add(ParameterFilterRuleFactory.CreateEqualsRule(commentParamId, "override", true));
    using (Transaction t = new Transaction(doc,"View Filter"))
    {
        t.Start();
                        
        foreach (ElementId id in getIds(doc))
        {
            doc.GetElement(id).get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set("override");
        }
        
        ParameterFilterElement filter = ParameterFilterElement.Create(doc, "New Filter", catIds, rules);
        doc.ActiveView.AddFilter(filter.Id);
        doc.ActiveView.SetFilterOverrides(filter.Id, ogs);
        t.Commit();
    }
}

#RTCEUR Wish 2: Override graphics by Element

Increasing the complexity a bit from the previous post, this sample shows how to Override Graphics by Element. In this case, the cut & project line weight and color are overridden in the active view for the specified elements.

public void overrideElements()
{
    Document doc = this.ActiveUIDocument.Document;
    OverrideGraphicSettings ogs = new OverrideGraphicSettings();
    ogs.SetCutLineColor(new Color(0,255,0));
    ogs.SetCutLineWeight(6);
    ogs.SetProjectionLineColor(new Color(0,0,255));
    ogs.SetProjectionLineWeight(6);
    using (Transaction t = new Transaction(doc,"Overrides"))
    {
        t.Start();
        foreach (ElementId id in getIds(doc))
        {
            doc.ActiveView.SetElementOverrides(id, ogs);
        }
        t.Commit();
    }
}

#RTCEUR API Wish 2: Override display by element ids (isolate)

@DigDesRev asked “so clash detection gives a report w/ element IDs, can we review the report and on 1 view, override the display settings?”

The simplest way to visualize these elements is with Revit’s ‘Temporary Hide/Isolate’ tool

public void isolateElements()
{
    Document doc = this.ActiveUIDocument.Document;    
    using (Transaction t = new Transaction(doc,"Isolate"))
    {
        t.Start();
        doc.ActiveView.IsolateElementsTemporary(getIds(doc));
        t.Commit();
    }
}

getIds() can be whatever function you want to read a clash detection report from disk, find elements in the Revit model, etc.

#RTCEUR Wish #1: #Revit Change Tracking

Dieter asked “What about a tool that can help you tracking changes in your #Revit model. E.g. select elements that were affected by an indicated change. Eg after updating model from RSA. Maybe a dialog showing the history”

If you want to log every change made to your Revit model and what elements are affected by that change, the DocumentChanged event is what you need.

The code below outputs the time, user name, transaction name, and all added, modified, and deleted elements for each transaction.

For simple annotation operations, the output is relatively straightforward:

10/30/2014 3:58:43 PM,harry_000,Edit Text,ADDED,1074184(Text Notes: 2.5mm Arial),,DELETED,,MODIFIED,
10/30/2014 3:58:54 PM,harry_000,Add Left Arc Leader,ADDED,,DELETED,,MODIFIED,1074184(Text Notes: 2.5mm Arial),
10/30/2014 3:59:02 PM,harry_000,Detail Lines,ADDED,1074193(Lines: Detail Lines),,DELETED,,MODIFIED,
10/30/2014 3:59:11 PM,harry_000,Place Dimensions,ADDED,1074208(Dimensions: Feet & Inches),,DELETED,,MODIFIED,

For other transactions (such as creating a column or moving a grid), the output shows that Revit is making a whole lot of changes.

10/30/2014 4:01:05 PM,harry_000,Structural Column,ADDED,1074223(Structural Columns: L127X127X9.5),1074224(Analytical Columns),1074245(Analytical Nodes),1074246(Analytical Nodes),1074247(Analytical Nodes),1074248(Analytical Nodes),,DELETED,,MODIFIED,102467(AutoJoin Tracker Element),102521(Element to track Analytical Sets during regeneration),103632(GCS Tracker),132466(Hubs Tracker),

10/30/2014 4:01:54 PM,harry_000,Nudge Right,ADDED,,DELETED,,MODIFIED,9745(System Data),86962(System Data),102467(AutoJoin Tracker Element),103632(GCS Tracker),132466(Hubs Tracker),195239(Grids: 2),414482(Structural Columns: M_1000),414483(Analytical Columns),414562(Analytical Nodes),414564(Analytical Nodes),428588(Walls: SIP 202mm Wall – conc clad),428745(Walls: SIP 202mm Wall – conc clad),457479(Windows: Standard),485432(Windows: Standard),554066(Constraints: Alignment),554069(Constraints: Alignment),670283(Dimensions: Feet & Inches),760918(M_1000),857235(<Area Boundary>: Model Lines),857236(<Area Boundary>: Model Lines),857239(),940871(Window Tags: M_Window Tag),940919(Window Tags: M_Window Tag),941385(Dimensions: Feet & Inches),

For a real application you might want to write this data to a database instead of a text file, and build a viewer to get more info about the added and modified elements based on their element ids.

void ControlledApplication_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
{
    string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "CommandLogging.csv");
    using (StreamWriter sw = new StreamWriter(file, true))
    {
        foreach (string transactionName in e.GetTransactionNames())
        {
            sw.Write(DateTime.Now + "," + Utils.username + "," + transactionName);
            sw.Write(",ADDED," + idCollectionToString(e.GetDocument(), e.GetAddedElementIds()));
            sw.Write(",DELETED," + idCollectionToString(e.GetDocument(), e.GetDeletedElementIds()));
            sw.Write(",MODIFIED," + idCollectionToString(e.GetDocument(), e.GetModifiedElementIds()));
            sw.Write(Environment.NewLine);
        }
    }
}

private string idCollectionToString(Document doc, ICollection<ElementId> coll)
{
    string ret = "";
    foreach (ElementId id in coll)
    {
        Element e = doc.GetElement(id);
        string name = "";
        if (e != null)
        {
            string catName = "";
            if (e.Category != null)
                catName = e.Category.Name;
            if (e.Name != "" && catName != "")
                catName += ": ";
            name = "(" + catName + e.Name + ")";
        }
        ret += id.IntegerValue.ToString() + name + ",";
    }
    return ret;
}

It’s Almost #RTCEUR Wishlist Time!

RTC Europe starts tomorrow, and I’m looking forward to my class “Maintaining Order & Preventing Chaos with the Revit API” on Friday morning.

But more importantly, another RTC means another chance for you to send your RTC Wish List ideas and get some free API code written while I’m in Dublin!

So tweet your best ideas for little Revit API apps to https://twitter.com/BoostYourBIM and I look forward to seeing what you dream up. Suggestions from folks who are actually at RTC of course get first priority.

Getting linked file data w/out opening the RVT

Here’s how to get information about linked files (DWG, RVT, etc) without having to first open the file

public void GetRVTLinks()
{
    ModelPath mp = new FilePath(@"C:\Users\harry_000\Documents\testFile.rvt");
    TransmissionData td = TransmissionData.ReadTransmissionData(mp);
    string s = "ExternalFileReferenceType\tPathType\tFile Path" + Environment.NewLine;
    foreach (ElementId id in td.GetAllExternalFileReferenceIds())
    {
        ExternalFileReference extRef = td.GetLastSavedReferenceData(id);
        s += extRef.ExternalFileReferenceType.ToString() + "\t" +
             extRef.PathType.ToString() + "\t" + 
            ModelPathUtils.ConvertModelPathToUserVisiblePath(extRef.GetPath()) + Environment.NewLine;
    }
    
    string outputfile = Path.Combine(Path.GetTempPath(),"links.txt");
    using (StreamWriter sw = new StreamWriter(outputfile,false))
    {
        sw.Write(s);
    }
    
    Process.Start(outputfile);
}

Deleting (almost) all Viewport Types in 2014

A friend who is still running Revit 2014 on their Windows NT box noticed that yesterday’s post works only in 2015 because it uses the newfangled ElementType.FamilyName Property.

So that you can continue living happily in the Stone Age, here is a different way to find the Viewport Types based on the presence of the Viewport Type-specific parameters.

Also, while testing this Revit kept giving me a nonsensical “Deleting all open views in a project is not allowed” error, even though I was never trying to delete all open views in the project. It seems that Revit 2014 & 2015 really really really love Viewport 1 and don’t want it to be deleted. So I added some code to leave it alone.

public void deleteUnusedViewportTypesFor2014()
{
    Document doc = this.ActiveUIDocument.Document;
    
    // get all viewport types
    // this approach to find the Viewport Types can be used in 2014 
    // whereas the ElementType.FamilyName property exists in 2015 only
    IList<ElementType> viewportTypes = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).Cast<ElementType>()
        .Where(q =>
               q.get_Parameter("Title") != null &&
               q.get_Parameter("Show Title") != null &&
               q.get_Parameter("Show Extension Line") != null &&
               q.get_Parameter("Line Weight") != null &&
               q.get_Parameter("Color") != null &&
               q.get_Parameter("Line Pattern") != null
              ).ToList();

    // create list of ElementIds from list of ElementType objects
    IList<ElementId> viewportTypeIds = new List<ElementId>();
    foreach (Element viewportType in viewportTypes)
    {
        viewportTypeIds.Add(viewportType.Id);
    }
    
    // create list of Viewport Type Element Ids sorted by the integer value of the element ids
    List<ElementId> toDelete = viewportTypeIds.OrderBy(q => q.IntegerValue).ToList();
    
    // Remove the first element in this list so that "Viewport 1" will not be deleted.
    // There seems to be a bug in Revit that prevents deleting "Viewport 1".
    // Even if this viewport is not being used, attempting to delete it results in an error "Deleting all open views in a project is not allowed."
    toDelete.RemoveAt(0);
    
    // remove from this list all viewport types that are in use
    foreach (Element viewport in new FilteredElementCollector(doc).OfClass(typeof(Viewport)))
    {
        ElementId typeId = viewport.GetTypeId();
        toDelete.Remove(typeId);
    }
    
    // do the deletion
    using (Transaction t = new Transaction(doc,"Delete Unused Viewport Types"))
    {
        t.Start();
           doc.Delete(toDelete);
        t.Commit();
    }
}

Deleting Unused Viewport Types

If there are unused Viewport Types that you can’t get rid of with Purge Unused, here is an API approach to try. The ElementType class has many subclasses but not one for ViewportType so the FamilyName property is used instead.

public void deleteUnusedViewportTypes()
{
    Document doc = this.ActiveUIDocument.Document;
    
    // get all viewport types
    IList<ElementType> viewportTypes = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).Cast<ElementType>().Where(q => q.FamilyName == "Viewport").ToList();

    // create list of ElementIds from list of ElementType objects
    IList<ElementId> viewportTypeIds = new List<ElementId>();
    foreach (Element viewportType in viewportTypes)
    {
        viewportTypeIds.Add(viewportType.Id);
    }
    
    // remove from this list all viewport types that are in use
    foreach (Element viewport in new FilteredElementCollector(doc).OfClass(typeof(Viewport)))
    {
        ElementId typeId = viewport.GetTypeId();
        viewportTypeIds.Remove(typeId);
    }
    
    // do the deletion
    using (Transaction t = new Transaction(doc,"Delete Unused Viewport Types"))
    {
        t.Start();
        doc.Delete(viewportTypeIds);
        t.Commit();
    }
}

Thanks for voting me an #RTCNA Top 10 Speaker!

Thank you to everyone who attended my class “Maintaining order & preventing chaos with the Revit API” at RTCNA 2014. I am honored to have been voted a Top Ten speaker for the 2nd consecutive year!

If you haven’t been to RTC yet, I highly recommend attending the Europe, Australia, and/or North America editions. RTC Europe will be in Dublin at the end of October – I’m looking forward to being there and hope you will be there too.

Get room data for elements in RVT links

A Revit guru asked:

“Have you ever shared room data across Revit links successfully? If you have 10 linked projects from different authors / disciplines, and the official room data only exists in one of them (say architectural), have you figured out a way to create a cross discipline room schedule?”

For example, your walls & rooms are in rooms.rvt. Furniture is in furniture.rvt which is linked into rooms.rvt. How do you figure out the room for each piece of furniture?

With the API, of course!

Sometimes its not your code (try a different Revit version)

An API developer asked why this code didn’t work to place a face-based family instance on a face in an RVT Link.

public void PlaceFaceBasedFamilyinLink()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
    
    ReferenceIntersector ri = new ReferenceIntersector((View3D)doc.ActiveView);
    ri.FindReferencesInRevitLinks = true;
    Reference r = ri.FindNearest(XYZ.Zero,XYZ.BasisZ.Negate()).GetReference();

    Family fam = new FilteredElementCollector(doc).OfClass(typeof(Family)).Cast<Family>().FirstOrDefault(q => q.Name == "Family2");
    
    using (Transaction t = new Transaction(doc,"place instance"))
    {
        t.Start();
        doc.Create.NewFamilyInstance(r, r.GlobalPoint, XYZ.BasisY, fam.Symbols.Cast<FamilySymbol>().First());
        t.Commit();
    }        
}

After investigating for a while in 2014 and wondering why this error occurred:

Capture

I decided to try the same code in 2015 where I found it to work just fine. This doesn’t help me get it working if I need a Revit 2014 solution, but at least it lets me stop spending time looking for a problem in my code that doesn’t exist.

#RTCNA Wish 6: Save all groups to file

In response to a tweet asking to save all groups, I responded that there is no API for Save Group. That’s true, but all hope is not lost.

This video shows how the API can be used to generate a text file listing all model groups. Then this text file is used as input to a journal file that saves each group to its own file.

#RTCNA Wish 5: Delete (almost) all revisions

Scott sent a tweet about deleting all revisions from a project. The tricky part is that, just like how the UI grays out the Delete button when there is only one revision in the project, we can’t use the API to delete the last revision.
Capture
This code uses the Revit 2015 API because the Revision class is new to 2015.

public void DeleteRevisions()
{
    Document doc = this.ActiveUIDocument.Document;

    // get list of all revisions in the document
    ICollection<ElementId> elementIds = new FilteredElementCollector(doc)
        .OfClass(typeof(Revision))
        .ToElementIds();
    
    // Remove the first revision from the list
    // Revit must have one revision in the document, so we can't delete them all
    elementIds.Remove(elementIds.First());

    using (Transaction t = new Transaction(doc,"Delete Revisions"))
    {
        t.Start();
        doc.Delete(elementIds);
        t.Commit();
    }
}

#RTNCA Wish 4: Dimension creation

Last night at the API Open House, we talked about the power and limitations of the Dimensions API.

This example shows how to create dimensions that reference two parallel faces. The video shows running the command in a locked 3D view and selecting the end faces of beams. It is also necessary to set the view’s workplane so that the direction of the dimension lies in this plane.

More automated creation of these dimensions could be achieved by programatically getting the faces from the beams so that the user need only select the beam instead of the 3 faces shown in this sample.

public void CreateDimFromFaces()
{
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = this.ActiveUIDocument;
    Reference r1 = uidoc.Selection.PickObject(ObjectType.Face, "Pick face for dimension reference");
    Reference r2 = uidoc.Selection.PickObject(ObjectType.Face, "Pick face for dimension reference");
    Reference r3 = uidoc.Selection.PickObject(ObjectType.Face, "Pick face for view work plane");
    ReferenceArray ra = new ReferenceArray();
    ra.Append(r1);
    ra.Append(r2);
    Element e = doc.GetElement(r2);
    Location l = e.Location;
    LocationCurve lc = l as LocationCurve;
    Curve curve = lc.Curve;
    Line line = curve as Line;
    
    using (Transaction t = new Transaction(doc,"dim"))
    {
        t.Start();
        doc.ActiveView.SketchPlane = SketchPlane.Create(doc, r3);
        Dimension dim = doc.Create.NewDimension(doc.ActiveView, line, ra);
        t.Commit();
    }
}

#RTCNA Wish 3: Copy rooms from one phase to another

Matt and some others asked how to “Copy All Rooms/Spaces to all phases in project”. This example shows how we can specify a “source phase” and create new rooms for each of those rooms in a “target phase”.

public void copyRoomPhase()
{
    string sourcePhaseName = "New Construction";
    string targetPhaseName = "Existing";
    
    Document doc = this.ActiveUIDocument.Document;
    
    Phase targetPhase = new FilteredElementCollector(doc)
        .OfClass(typeof(Phase))
        .Cast<Phase>()
        .FirstOrDefault(q => q.Name == targetPhaseName);

    Phase sourcePhase = new FilteredElementCollector(doc)
        .OfClass(typeof(Phase))
        .Cast<Phase>()
        .FirstOrDefault(q => q.Name == sourcePhaseName);
    
    IList<Element> roomList = new FilteredElementCollector(doc)
        .OfClass(typeof(SpatialElement))
        .OfCategory(BuiltInCategory.OST_Rooms).ToList();
    
    PlanTopologySet planTopologies = null;
    using (Transaction t = new Transaction(doc,"get topology"))
    {
        t.Start();
        planTopologies = doc.PlanTopologies;
        t.Commit();
    }

    foreach (Element sourceRoom in roomList)
    {
        XYZ pointInSourceRoom = ((LocationPoint)(sourceRoom.Location)).Point;
        
        Parameter phaseParam = sourceRoom.get_Parameter("Phase");
        if (doc.GetElement(phaseParam.AsElementId()).Name != sourcePhaseName)
            continue;
        
        Room newRoom = null;
        using (Transaction t = new Transaction(doc,"New Room"))
        {
            t.Start();
            newRoom = doc.Create.NewRoom(targetPhase);
            t.Commit();
        }
        
        bool found = false;
        
        foreach (PlanTopology pt in planTopologies)
        {
            if (found)
                break;
            
            foreach (PlanCircuit pc in pt.Circuits.Cast<PlanCircuit>())
            {
                using (Transaction t = new Transaction(doc,"Place Room"))
                {
                    t.Start();
                    Room placedNewRoom = doc.Create.NewRoom(newRoom,pc);
                    doc.Regenerate();
                    
                    if (placedNewRoom.IsPointInRoom(pointInSourceRoom))
                    {
                        t.Commit();
                        found = true;
                        break;
                    }
                    else
                    {
                        t.RollBack();
                    }
                }
            }
        }
    }
}

#RTCNA Wish 2 granted: Find pinned elements

Steve wishes for an easy way to use the API to find pinned elements. Wish granted!

public void findPinned()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = this.ActiveUIDocument.Document;
    
    // create new SelElementSet to store elements that will be selected
    SelElementSet selSet = SelElementSet.Create();
    
    // find all elements in the active view that are pinned
    foreach (Element e in new FilteredElementCollector(doc, doc.ActiveView.Id).WhereElementIsNotElementType().Where(q => q.Pinned))
    {
        // add each of these elements to the set
        selSet.Add(e);
    }
    
    // select all elements in the set
    uidoc.Selection.Elements = selSet;
    
    // refresh the view so that the newly selected elements are highlighted
    uidoc.RefreshActiveView();
    
    TaskDialog.Show("Elements Pinned","Elements pinned in view '" + doc.ActiveView.Name + "' = " + selSet.Size.ToString());
}

RTCNA Wish #1: Replace detail groups with detail components

Michael McCune sent a wish via Twitter to “replace detail group instances with a detail component”.

That’s a good wish, and one that can almost be completely granted via the API as shown in this video.

The limitation is that the API provides no way to identify the rotation angle of a group instance. For any element in a subclass of the Instance class (such as a family instance, import instance, or Revit link instance) the API provides GetTransform() which contains the data needed to determine the instance’s rotation angle. The AssemblyInstance class also implements GetTransform().

Unfortunately, the Group class has no such method. As a result, while we could rotate the newly created detail components, there is no way to query the detail group instance to determine how much each detail component should be rotated.

public void detailGroupToComponent()
{
    Document doc = this.ActiveUIDocument.Document;
    
    // create a dictionary to store the mapping between detail groups and detail component
    // the NewLine character is used to delimit the family name and family type name
    Dictionary<string, string> groupComponentDict = new Dictionary<string, string>();
    groupComponentDict.Add("DG1","DetailComponent1" + Environment.NewLine + "Type 1");
    groupComponentDict.Add("filled regions","DetailComponent2" + Environment.NewLine + "Type 2");
    
    using (Transaction t = new Transaction(doc,"Detail Groups -> Detail Components"))
    {
        t.Start();    
        
        // find all group instances in the document with the Detail Groups category
        IEnumerable<ElementId> groups =  new FilteredElementCollector(doc)
            .OfClass(typeof(Group))
            .OfCategory(BuiltInCategory.OST_IOSDetailGroups).ToElementIds();
        
        foreach (ElementId id in groups)
        {
            Group g = doc.GetElement(id) as Group;
            
            // get the XYZ location of the group instance
            Location location = g.Location;
            LocationPoint lp = location as LocationPoint;
            XYZ xyz = lp.Point;
            
            // get the view that owns the group instance
            ElementId ownerviewId = g.OwnerViewId;
            View ownerview = doc.GetElement(ownerviewId) as View;
            
            // lookup the name of the family that will replace this group instance
            string familyNameType = groupComponentDict[g.Name];
            
            // split the family name / family type string
            string[] split = familyNameType.Split(new string[] {Environment.NewLine}, StringSplitOptions.None);
            string famName = split[0];
            string typeName = split[1];
            
            // find the FamilySymbol (which is the API name for the Family Type)
            FamilySymbol fs = new FilteredElementCollector(doc)
                .OfClass(typeof(FamilySymbol))
                .Cast<FamilySymbol>()
                .FirstOrDefault(q => q.Family.Name == famName && q.Name == typeName);

            // delete the group instance
            doc.Delete(g.Id);
            
            // create an instance of the detail component
            doc.Create.NewFamilyInstance(xyz, fs, ownerview);
        }
        t.Commit();
    }
}

Get your #RTCNA Revit API Wishes Ready!

Like last year, during the upcoming few days of Revit Technology Conference North America, please tweet your Revit API questions and wishes to me at twitter.com/BoostYourBIM. I will do my best to reply to as many as possible with code, videos, and blog posts showing how we can use the API to make Revit better.

Revit disappears after startup with a Windows 8.1 Clean Boot

Has anyone ever seen something like this?

I was having some problems with Windows (like Windows Explorer freezing when I try to create a new folder). So I did a Clean Boot and used shexview.exe to disable the non-Microsoft entries.

These changes seem to have fixed the problems I was having with Chrome and Windows Explorer, but now I can’t run Revit. Revit starts, the startup page briefly appears, then the Revit session dissapears. Does anyone know what might be happening? I’d really appreciate your help!

The last lines of the journal file are:

Jrn.Command “Internal” , “Show or hide recent files , ID_STARTUP_PAGE”
‘ 0:< ::1:: Delta VM: Avail -26 -> 134216371 MB, Used 217 MB; RAM: Avail -3 -> 5496 MB, Used +2 -> 310 MB
‘C 09-Jun-2014 22:19:25.709; 0:< <-processShellCommand
‘ 0:< ->DesktopMFCApp::doStartupWarnings
‘C 09-Jun-2014 22:19:25.710; 0:< manage licensing
‘ 0:< ::1:: Delta VM: Avail -85 -> 134216287 MB, Used +8 -> 226 MB, Peak +0 -> 226 MB; RAM: Avail -47 -> 5450 MB, Used +34 -> 345 MB, Peak +29 -> 345 MB
‘C 09-Jun-2014 22:19:28.617; 0:< License checkout failed: 20
‘C 09-Jun-2014 22:19:28.618; 0:< License cleanup skipped

Process Monitor shows:

Capture

UPDATE:  This checkbox for FLEXnet needed to be turned back on. Problem solved thanks to the suggestion from Luke Johnson.

Capture