2

I have a two-part WPF App and Revit Addin that runs a series of routines to create and activate a new BIM 360 project via the FORGE BIM 360 API, launches Revit and creates and sets up a collection of Revit models from a "seed" Revit model. The primary requirement is to have zero user interaction in this process: to be fully automated.

Given that background, I am having trouble linking the newly saved BIM 360 models to one-another. I have the option to do this either in the Revit Addin with Revit API hooks (preferred) or through the manager WPF App with FORGE API REST calls after the models are created.

Is either one possible?

I have successfully linked with the cached local models as described here and here. However, this does not meet the requirement fully, since when any other user (besides the automation machine user) opens the model the links are Not Found.

Screenshot of links Not Found.

Current "sort-of-working" code:

var wId = GetWorksetId(doc, w);
if (wId != null)
{
    string localPath = settings.CloudModels.Where(x => x.ModelName == _linkModelNames[i]).Select(x => x.LocalFilePath).First();
    ModelPath path = ModelPathUtils.ConvertUserVisiblePathToModelPath(localPath);

    using (var options = new RevitLinkOptions(true))
    {
        using (var t = new Transaction(doc, w))
        {
            t.Start();
            doc.GetWorksetTable().SetActiveWorksetId(wId);

            using (var result = RevitLinkType.Create(doc, path, options))
            {
                _ = RevitLinkInstance.Create(doc, result.ElementId);
            }

            t.Commit();
            linkPlaced++;
        }
    }
}

I was able to get the correct ModelPath via the Revit API thanks to this helpful tip. I can save this value in my Addin, close the model, and access the property later after opening a different model (saved in the CloudModels class referenced in the linq statement in the code snippet above). Unfortunately for me RevitLinkType.Create() that takes a ModelPath does not accept the cloud path, so I may have hit another dead end. Unless it is possible with an ExternalResourceReference. Has anyone tried this option? If so, how do you assemble a Revit ExternalResourceReference? I am not familiar with this process, and looking over this course from AU 2017, I don't see that it necessarily applies to BIM 360 cloud models. A BIM 360 cloud example would be very helpful if this is possible.

Alternate strategy: I do not see any reference to loading links in the FORGE Data Management API or other FORGE APIs. If I have somehow missed it, please share a link.

Any help would be very much appreciated!!

EDIT: I have since found these two (1) (2) similar questions that, at least for my purposes, were not answered satisfactorily. Any updates I should be aware of?

  • please take a look at this article: https://thebuildingcoder.typepad.com/blog/2019/06/accessing-bim360-cloud-links-thumbnail-and-dynamo.html#2 – Augusto Goncalves Jan 06 '20 at 21:34
  • I have been referred to this article before, but I don't see what about this article should help. Can you be more specific please? It starts by looking at existing links. I want to create new cloud model links when the model has no links yet. I suppose I could snoop on one in a test model, get the property structure for a cloud link external reference and then try to mirror that structure in a new model. It seems unlikely to me that I could find reliable success that way, though if it's not a documented solution. Am I missing something? – Kristen Schulte Jan 06 '20 at 22:09
  • Added a new answer. – Augusto Goncalves Jan 07 '20 at 12:19

4 Answers4

1

As of now (Jan 2020), unfortunately, we do not have a Link API for cloud models. It is on the roadmap.

Augusto Goncalves
  • 8,493
  • 2
  • 17
  • 44
1

Revit API 2022 docs mention that

The methods:

  • RevitLinkType.Create(Document, ModelPath, RevitLinkOptions)
  • RevitLinkType.LoadFrom(ModelPath, WorksetConfiguration)

have been enhanced to support creation of new cloud model Revit links. You may use ModelPathUtils.ConvertCloudGUIDsToCloudPath() to create a cloud path to use as an argument to these methods.


Additional Resource:

Gangula
  • 5,193
  • 4
  • 30
  • 59
1

For Revit 2021 and below, you can use ExternalResourceReference() as a workaround, but I've noticed that this is not always reliable.

Its also mentioned in the documentation of InSessionPath property to not rely on this property:

Do not rely on this path (InSessionPath ) to look up an ExternalResourceReference, as the path is neither unique nor stable. It isn't unique because multiple servers might use the same server name and display name format. It isn't stable because some servers allow renaming, and because a server might change its name at some point.

Below is the code to do that:

var linkCloudPath = doc.GetCloudModelPath(); // the cloudpath of a BIM360 model
Guid linkedmodelguid = linkCloudPath.GetModelGUID();
Guid linkedprojectguid = linkCloudPath.GetProjectGUID();

Dictionary<string, string> Dictionary_ExternalResource = new Dictionary<string, string>(){
    {"LinkedModelModelId", modelGuid.ToString()},
    {"LinkedModelProjectId", projGuid.ToString()}
};

Dictionary<string, Guid> servers = new Dictionary<string, Guid>();

foreach (var service in ExternalServiceRegistry.GetServices())
{
    if (service.Name == "External Resource Service")
    {
        IList<Guid> server_ids = service.GetRegisteredServerIds();


        foreach (var server_id in server_ids)
        {
            servers.Add(service.GetServer(server_id).GetName(), server_id);
        }
    }
}

Guid BIM360ServerID = servers["BIM 360"];
ExternalResourceReference ERS = new ExternalResourceReference(BIM360ServerID, Dictionary_ExternalResource, "", "");
RevitLinkOptions options = new RevitLinkOptions(false);
LinkLoadResult result = RevitLinkType.Create(gcdoc, ERS, options);
RevitLinkInstance.Create(gcdoc, result.ElementId);

Please note that this seems to be working fine in Revit 2020, but not in Revit 2021.

Gangula
  • 5,193
  • 4
  • 30
  • 59
0

I believe it is possible to create links to the Cloud Models in Revit 2019 or higher (with ModelPathUtils.ConvertCloudGUIDsToCloudPath()). You'll need the ProjectGUID and ModelGUID to make the cloud model path.

Regarding the ExternalResource approach, that also works - but it's super messy - you can read the properties associated with existing BIM360 links and you'll see how an ExternalResource is defined for BIM360 links.

Finally - as of today, the Forge Design Automation for Revit approach would not work for you at all: 1. Not possible to open a live cloud workshared model (only published/uploaded models). 2. No network access while you're running in a Design Automation for Revit session.

Good luck... -Matt

Matt
  • 1,043
  • 5
  • 8
  • Thanks for the reply. It's good to know that I can eliminate Forge from my options to explore. I was unable to find any documentation for cloud model links in Revit 2020, can you provide an example? – Kristen Schulte Jan 06 '20 at 15:21
  • Made some edits to the above with the actual API call. https://www.revitapidocs.com/2019/cc284f13-a7a9-d37e-e46d-4769bf039a96.htm - also looked how I had done it before with the ExternalResource info, and it's possible - but only by coloring slightly outside the lines. – Matt Jan 06 '20 at 20:11
  • Thanks. I have been able to get the cloud `ModelPath` no problem. The problem is in using it to create a new link. `RevitLinkType.Create(Document, ModelPath, RevitLinkOptions)` does not accept a cloud `ModelPath` (triggers a `ArgumentExeption`). https://www.revitapidocs.com/2019/0dd0e8bd-5217-9a94-19bb-58dcb840e517.htm What do you use instead for creating a new Revit cloud model link? – Kristen Schulte Jan 06 '20 at 21:56