I previously posted about how to quickly repath links based on some control mechanisms. Enter BIM 360, and the wild world of Revit cloud worksharing… I expect that it will be commonplace now for existing projects and datasets to move across to BIM360 ‘mid project’. But that creates some interesting problems, like creating folders, dealing with the initiation process, and replacing local Revit Links with their cloud versions.

This post is focused on that process of changing all of the Revit link paths to link to the BIM 360 models. Unfortunately, the previous method I used (TransmissionData, like eTransmit) is not available for cloud hosted models. So how do we automate this process?

We went about it this way:

  1. Initiate all Revit models on the BIM 360 Document Management cloud (manually, for now)
  2. Create one federated model on the BIM 360 cloud that links in all the other cloud hosted Revit models. You might do this one manually, using Reload From in the Manage Links dialog box.
  3. Once you have that one ‘super host model’, use a batch process to harvest all of the cloud model data
  4. Using the harvested data, create a script that implements a Reload From method to batch reload local models from their cloud counterpart

On the journey to solving step 3, I experimented with a few different methods. I discovered that you need to use the ExternalResource class to get information about BIM 360 cloud models (not ExternalReference).

I also realised that I had to deal with Reference Information, which appears to be a .NET dictionary per link that stores some funky Forge IDs and so on. But I want to store all this data in our VirtualBuiltApp BIM Management system, so I had to serialise the Reference Information to a string that could be stored in a database VARCHAR field (or push to Excel if you are still doing things the old way). Dimitar Venkov gave me a few tips about using JSON with IronPython in Dynamo (thanks mate!), so after that all the harvesting pieces were in place!

Here is some of the harvesting and JSON code. Notice that I played around with using a container class to pass data between Dynamo nodes. In the end, JSON string was the answer:

 data = []
for u in unwraps:
    data.append(u.GetExternalResourceReference(linkresource))

class dummy(object):
    def ToString(self):
        return 'container'
container = dummy()

sdicts = []

for y in data:
    dictinfo = ExternalResourceReference.GetReferenceInformation(y)
    container.dictinfo = dictinfo
    infos.append(container)
    shortnames.append(ExternalResourceReference.GetResourceShortDisplayName(y))
    versionstatus.append(ExternalResourceReference.GetResourceVersionStatus(y))
    insessionpaths.append(y.InSessionPath)
    serverids.append(y.ServerId)
    versions.append(y.Version)
    sdicts.append(json.dumps(dict(dictinfo)))

The next step was to create the ‘batch reload from’ tool. Now that we had the necessary data, we just had to use it to grab the matching cloud path information (from our database) and apply it to each Revit link.

I created a node that essentially built a new reference path from the JSON and other data that we had harvested. Here is some of that code:

 des = []
for x in referencesInfo:
    des.append(json.loads((x)))
newdicts = []
for y in des:
    newdicts.append(Dictionary[str, str](y))

serverGuids = []
for g in serverIdsIn:
    tempguid = Guid(g)
    serverGuids.append(tempguid)

newrefs = []
for z in range(len(referencesInfo)):
    serverIdIn = serverGuids[z]
    referenceInfo = newdicts[z]
    versionInfo = versionsInfo[z]
    sessionPathIn = sessionsPathIn[z]
    tempRef = ExternalResourceReference(serverIdIn, referenceInfo, versionInfo, sessionPathIn)
    newrefs.append(tempRef)

OUT = newrefs

The final step was to get a RevitLinkType and a matching ReferenceInformation and apply them to each other. I stored the data in our cloud based BIM Management Application, VirtualBuiltApp. Then I could easily just pull the data into Dynamo with a suitable database connector, and match up the RevitLinkType in the current file with its associated cloud identity. For that genuine 90s feel, you could use Excel to store the data as it is just a JSON string and some other strings:

Here is the key bit of code that actually changes the link path (without all of my other error checking bits and pieces):

     try:
        newCloudPath = newCloudPaths[l]
        reloaded = fileToChange.LoadFrom(newCloudPath, defaultconfig)
        successlist.append(reloaded.LoadResult)
        TransactionManager.Instance.ForceCloseTransaction()
    except:
        successlist.append("Failure, not top level link or workset closed")

To actually implement the script and get productive, I opened 4 instances of Revit, and then used this process in each instance:

  1. Open the Revit file from BIM 360, with Specify… all worksets closed
  2. Unload all links
  3. Open all worksets
  4. Run the Reloader Script
  5. Confirm link status in Manage Links
  6. Optional: Add ‘bim 360 links loaded’ text to Start View (just for tracking purposes)
  7. Optional: Add comment to VirtualBuiltApp (optional, for tracking purposes)
  8. Close and Sync

In this way I can have 4 or more sessions operating concurrently, fixing all the link paths automatically, and I just need to gently monitor the process.

One nice thing is that I set the script up to immediately Unload a link after it had obtained and applied the new Path information. This means that the Revit instance does not get bogged down with many gigs of link data in memory, and in fact this is way faster than trying to use Manage Links for a similar process.

Ideally I would like to fully automate this, to the point where it opens each file, runs the script, and syncs. Unfortunately, time didn’t allow me to get all the code together for that (for now).

Finally, because we are using our custom built schema and validation tools, we can easily create visuals like this:

Modified versions of the Dynamo graphs can be found on the Bakery Github here:

dyn folder

At Virtual Built, we typically create a federated Revit model for every project we work on. This allows us to run a host of automated processes on the links, right from the federated file.

Recently we received a dataset for a high rise building. The Architect had used 5 typical linked ‘module’ files, copied throughout a master file.

Initially, I used a Dynamo script to collect all the link instances into a saved selection set. I could then copy / paste aligned the link instances into our federated Revit model:

Link Instances to Selection Set

 

The Problem

This works fine, but in this models there were also nested consultant links inside the Architectural linked modules. So we have:

Architectural container file -> Architectural module files -> Consultant nested links

 

We want:

Federated Central file -> Everything else (no nested links)

 

Next challenge: how can we quickly promote those nested links into our federated model? Well, we currently have the module files populated, so how can we leverage those positions to promote the nested links?

 

Promoting Nested Links

It is a bit hacky, but here is how I went about it. For each module file:

  1. Create an empty proxy file (New Revit project, no template)
  2. Open the Module file and resolve all link paths (so they are loaded)
  3. Set links to Attachment
  4. Copy / paste the link Instances from the module file (Level 0 or Base Level) into the empty file (Level 1, default level). You can use Dynamo graph above.
  5. Save the new proxy file as ‘ModuleContainer’ or similar. We know have a file that only has link instances in it.
  6. Open a detached copy of the Federated Central file (you can save as temporary copy if you like)
  7. Manage Links
    • Select the current Module file,
    • Reload From,
    • replace with the ModuleContainer you created. Once you have done all the modules, you are ready for binding as described below.

After populating the detached Federated Central file, we just need to Bind and then Copy / Paste the free instances:

  1. After load, Bind the ModuleContainer files to the detached Federated Central model
    1. To do this, right-click on the file in Revit Links in Project Browser

    2. Select All Instances – In Entire Project
    3. In the Ribbon, click Bind Link
    4. Untick Attached Details, Levels, Grids
    5. Click Remove Link when prompted
    6. Your nested links are now promoted!
  2. Optional: Ungroup all of those bound free instances (select all from Project Browser, Ungroup in Ribbon)
  3. Open the real Federated Central file
  4. Copy / paste the populated free instances from the detached Federated Model to the real Federated Model. Use the Dynamo script to collect them.
    Tip: Paste into a closed workset for better performance.
  5. Close the detached one, and sync the real one

The only thing we technically ‘broke’ or lost in this process is the module link->nested link relationship. So if someone decides to move one of the nested links in the module link, obviously that won’t replicate into the Federated Central file.

Hope this helps some of you out there building or dealing with large federated models.

 

This hotfix corrects an issue with non-English languages where the PnID Modeler functionality did not load correctly after appling Revit 2018.3 Update.

Some notes from readme below…

Additional software applied by this update

Collaboration for Revit 2018.3.1 Update, Dynamo Core 1.3.2.2480 and Dynamo Revit 1.3.2.2480

With this install the following will be updated: Revit 2018, Collaboration for Revit 2018, and Dynamo. The updated version of the Dynamo Revit add-in does not include a desktop shortcut and can be accessed from the Visual Programming panel found on the Manage ribbon tab. If multiple versions of the Dynamo Revit add-in are installed, a dialog will prompt you to select which version to launch.

After this update is applied, there will be two versions of Dynamo Core installed, 1.2.2.373 and 1.3.2.2480.

Known Issues with applying the update.

  • During the installation of the hotfix you may be prompted to exit revit.exe. If you do not have a visible session open of Revit, please open Windows Task Manger, switch to the Processes tab, click “revit.exe” and the option “End Process”.
  • For BIM 360 Design (formerly Collaboration for Revit), if the Modified date for the revit.exe.config file is newer than the Created date, the patch installer will fail to update it and Revit may not launch correctly. Consult Collaboration for Revit: Synchronize process starts failing for C4R.

Autodesk Uninstall Tool

After this update is applied, attempts to uninstall Revit 2018 using the Autodesk Uninstall Tool may become unresponsive during the Dynamo Revit uninstall process. To avoid this problem, uninstall Dynamo Revit first and then continue with the uninstall of Revit 2018.

After a new version of Revit comes out, we all take some time to catch up. Revit API developers often have to get up and running really quickly so they can upgrade their apps for Revit 2019 compatibility. The first few things you will need are: the Revit 2019 SDK and help file, RevitLookup installed, and an understanding of What’s New in the Revit 2019 API.

To install RevitLookup for Revit 2019, head over to this page and grab the latest version, currently 2019.0.0.1. Put RevitLookup.addin and RevitLookup.dll into one of your Revit Addins folders, like:

%appdata%\Roaming\Autodesk\Revit\Addins\2019\

To install the Revit SDK, follow these steps:

  • Install Revit 2019 (or access the install media)
  • Look in the installation folder
  • In the Utilities subfolder, you will find the Revit 2019 SDK installer – RevitSDK.exe

This will basically unzip a whole heap of Revit API samples and goodness into a folder of your choosing. The key thing I look for initially is the RevitAPI.chm help file. I put this somewhere I can get to it easily (like OneDrive).

Until http://www.revitapidocs.com/ is updated for Revit 2019, the help files is the best way to access information about the Revit 2019 API.

 

Useful links, mostly from Jeremy over at The Builder Coder:

My Revit API 2019 Notes:

  • Building site export removed from API and Revit 2019
  • Project browser organisation for schedules added
  • Can now read the Phase Map parameter for the link. The phase map is a correspondence between phases in the host document and phases in the linked document…

On install of Revit 2019, you will have the following install choices:

There are no changes in the Options dialog from Revit 2018 to 2019, except for the new Steel tab and tools ribbon option (under Structure tab and tools):

This is what the Steel ribbon looks like:

Clicking Help will take you to Help content pages that don’t exist yet (oops). I’m sure this will be rectified soon.

Build numbers are 19.0.0.405 and 20180216_1515(x64)

Launching Dynamo from Revit 2019 will reveal that the Dynamo version has been upgraded to 1.3.3.4111. As some have mentioned, this version does not run on Revit 2016. So you will have to run multiple Dynamo versions and be aware of any file incompatibility if you want to use Dynamo on Revit 2016 and Revit 2019 simultaneously. The installation process should pick up your custom package paths and any Recent Files too.

Add-ins tab reveals that the following items previously considered Subscription Enhancements are included and installed out of the box:

  • Batch Print
  • eTransmit
  • Model Review
  • Worksharing Monitor

 

The biggest change you are likely to notice is that you now have Tabbed Views, and an updated interface for controlling docked panels.

I compared the built in category list from Revit 2018 and Revit 2019, and these are the new Categories in Revit 2019:

API Name Visible Name
OST_StructConnectionHoleTags Hole Tags
OST_StructConnectionShearStudTags Shear Stud Tags
OST_StructConnectionProfilesTags Profile Tags
OST_StructConnectionBoltTags Bolt Tags
OST_MechanicalEquipmentSetTags Mechanical Equipment Set Tags
OST_StructConnectionAnchorTags Anchor Tags
OST_MechanicalEquipmentSetBoundaryLines Mechanical Equipment Set Boundary Lines
OST_StructConnectionWeldTags Weld Tags
OST_StructConnectionPlateTags Plate Tags
OST_MechanicalEquipmentSet Mechanical Equipment Sets

 

On a final note… the Revit icon hasn’t changed for the last couple of years, so I made this Revit 2019 icon for you 🙂 Just download it and set as the icon for Revit 2019. Also, I’m sure you can do better than my attempt if you spend more than 30 seconds in Windows Paint:

Let’s say you have a family that has shape handles for instance dimensions (Length Parameters). What if you want to use it for quick prototyping, and then switch that same family into a version that uses Type based parameters?

Here’s how I went about it:

  • Change all existing Reference Planes to “Not a Reference”

  • Create new Reference Planes
  • Create new instance parameters bound to those Reference Planes

  • Lock one of the planes on each Dimension to existing origin planes
  • Create a corresponding set of Type dimensions
  • Create a set of Yes / No parameters for “Use Type for …”

  • Create formula like:
    if(Use Type for X, x type, x instance)
  • Apply it to the original parameters (the ones that are driving geometry):

How to Use:

  • Place the family
  • Resize using the shape handles (instance dimensions)
  • Then,
  • Create a Type
  • Modify the type Values and Tick the “Use Type” box

At this point, the Shape Handles are still visible, but only the Type values are used for the geometry.

Download Sample Family Here – Revit 2018:

AR_Generic_Placeholder_DC_FMP

Note: A future development of this family could be to make an inverse visibility parameter that switches off the Shape Handles once the Type Value is enforced.

Sometimes, What Revit Wants is a specific Annotation Tag family of a unique Family Category, like View Reference. When you go to create a new Family, you probably won’t find a Family Template for ‘Metric View Reference’ or similar. You need to create a family with the Generic Annotation template, and then change the Family Category.

Here’s how:

  1. Create a new Family -> Generic Annotation template
  2. Change the Family Category to the desired Category (like View Reference)

Save the family, then go ahead and add the Text, Labels and Lines as desired. Load into your project and you can then select it in the relevant dialog box:

Keep in mind that you can use a View Reference to “Go to View”, such as for an adjoining Floor Plan:

If you have gone through a process of saving Central models, and you have forgotten to ‘Synchronize with Central’ before closing them for the first time, you may find that your user has all User Created Worksets checked out in those files. A quick recap:

  • Workshared Revit files use a persons Revit user name (sometimes linked to an Autodesk SSO login) to determine if things are checked out
  • If someone has a User Workset checked out, you won’t be able to edit it until they Relinquish. (Note: you can Detach and recreate the file but that is dangerous if you have multiple people working on something)

Basically I had a bunch of Revit files that had all User Worksets from certain usernames checked out. They were upgraded and they were Central files. All that was needed was a simple Open and Relinquish. As I didn’t want to do this manually, I sourced some macro code from here and adapted it for my situation.

What does it do?

This Application level macro starts with a dialog box where you can select files. After you select them, it then loops over each file and Opens it, then does a Relinquish All Mine on User Created Worksets, and then it Syncs with Central and Closes the file. The key part of the code is here:

How to set it up?

First, get the code below. Copy and paste it into a new Application Macro in Revit.

 /*
  * Created by SharpDevelop.
  * User: lukes
  * Date: 1/10/2018
  * Time: 2:54 PM
  * 
  * To change this template use Tools | Options | Coding | Edit Standard Headers.
  */
 using System;
 using Autodesk.Revit.UI;
 using Autodesk.Revit.DB;
 using Autodesk.Revit.UI.Selection;
 using System.Collections.Generic;
 using System.Linq;
 using Autodesk.Revit.ApplicationServices;
 using System.IO;
 using System.Windows.Forms;
 
 namespace relinquish
 {
     [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
     [Autodesk.Revit.DB.Macros.AddInId("30EBC375-5A4C-4917-AB07-D7212C9ED3FA")]
     public partial class ThisApplication
     {
         private void Module_Startup(object sender, EventArgs e)
         {
 
         }
 
         private void Module_Shutdown(object sender, EventArgs e)
         {
 
         }
 
         #region Revit Macros generated code
         private void InternalStartup()
         {
             this.Startup += new System.EventHandler(Module_Startup);
             this.Shutdown += new System.EventHandler(Module_Shutdown);
         }
         #endregion
         public void RelinquishMineFromFiles()
         {
             
             
 OpenFileDialog theDialogRevit = new OpenFileDialog();
 theDialogRevit.Title = "Select Revit Project Files";
 theDialogRevit.Filter = "RVT files|*.rvt";
 theDialogRevit.FilterIndex = 1;
 theDialogRevit.InitialDirectory = @"C:\";
 theDialogRevit.Multiselect = true;
 if (theDialogRevit.ShowDialog() == DialogResult.OK)    
             
     {             
 /* string mpath = "";
         string mpathOnlyFilename = "";
         FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
         folderBrowserDialog1.Description = "Select Folder Where Revit Projects to be Saved in Local";
         folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
         if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
         {
          mpath = folderBrowserDialog1.SelectedPath;*/
                 foreach (String projectPath in theDialogRevit.FileNames)
                 {
                  FileInfo filePath = new FileInfo(projectPath);
                         ModelPath mp = ModelPathUtils.ConvertUserVisiblePathToModelPath(filePath.FullName);
                         OpenOptions opt = new OpenOptions();
 /*                        opt.DetachFromCentralOption = DetachFromCentralOption.DetachAndDiscardWorksets;*/
                          WorksetConfiguration openConfig = new WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets);
                         // Set list of worksets for opening 
 /*                        openConfig.Open(worksetIds);
                         opt.SetOpenWorksetsConfiguration(openConfig);
                         mpathOnlyFilename = filePath.Name;*/
                         Document openedDoc = Application.OpenDocumentFile(mp, opt);                               
 /*                        SaveAsOptions options = new SaveAsOptions();*/
                          TransactWithCentralOptions twcOpts = new TransactWithCentralOptions();
                         SynchronizeWithCentralOptions syncopt = new SynchronizeWithCentralOptions();
                         RelinquishOptions rOptions = new RelinquishOptions(true);
                         rOptions.UserWorksets = true;
                         syncopt.SetRelinquishOptions(rOptions);
                         syncopt.SaveLocalBefore = false;
                         syncopt.SaveLocalAfter = false;
 /*                        options.OverwriteExistingFile = true;
                         ModelPath modelPathout = ModelPathUtils.ConvertUserVisiblePathToModelPath(mpath + "\\" + mpathOnlyFilename);
                         openedDoc.SaveAs(modelPathout, options);*/
                         openedDoc.SynchronizeWithCentral(twcOpts, syncopt);
                         openedDoc.Close(false);
                }
         }
 }}}

Then,

  • Add the System.Windows.Form reference and
  • Build the Solution

Note: I built and tested this on Revit 2018.2.

How to Use It?

  1. Set your Revit User Name to the user that you want to Relinquish the Worksets for…
    • You may have to logout of your own SSO first
    • Go to Revit Options
    • Input the exact user name (including @ if an email address)
  2. Start a new blank project in Revit
  3. Start the Macro Manager
  4. Select the RelinquishMineFromFiles macro that you built
  5. Click Run
  6. Select the files you want to fix
  7. Click Ok
  8. Wait for the result. The macro will step through them, Relinquish, Sync and Close the files.

 

Note:

Please use at your own risk, this has the potential to be pretty risky in a real project environment. Only use it if you understand what is going on 🙂

Also, you can refer to this Revit API Doc page.

You may have experienced this error when upgrading a file to Revit 2018:

One or more required internal settings are missing from the model. What do you want to do?

 

Autodesk Support has stated that “In R 2018 we added a “feature” that catches issues like this and repair the model for you, instead of causing problem down the line.”

 

This particular dialog may not be handled by automatic upgrading tools. The resolution of the problem is to open the file manually, and simply press “Repair and open”. You should get a success message like below:

I assume there are other things that this Revit 2018 feature looks for and tries to fix. As Project Info includes a few different things in Revit, my guess for the above error is that it appears that it will set project Location to Default? Or perhaps it reinstates a deleted Project Base Point or Survey Point.

Either way, data and model validation is a good thing. Thanks Revit 2018 🙂

 

Update: RTV Xporter Pro can define rules for dismissing dialog boxes, in the Task Dialog Settings. See below: