Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

browsing model files in the cloud (A360 C4R)

65 REPLIES 65
Reply
Message 1 of 66
Sherbs
3261 Views, 65 Replies

browsing model files in the cloud (A360 C4R)

Hi Folks,

 

A new client of ours is using A360 C4R to store their model files in the cloud.

 

Configuration of our add-in requires that we indicate which model files are to be "managed" by our application.  At present, we pop up a file chooser dialog to allow the user to select which model files are managed.

 

With A360, however, the built-in wpf file chooser dialog doesn't seem to give us what we need to select model files that reside in the cloud.  It seems to be completely unaware of any cloud based storage.

 

Does A360 expose any of what it provides via an API?  Or is there some other means by which we can present model files stored in the cloud so that the user can indicate which models are to be managed by our add in?

 

As well, once the UNC path is known, is there anything particular to be aware of if/when our addin attempts to open those documents?  Or is that handled fairly seamlessly?

 

I'm not well versed in working with cloud storage so forgive if my questions seem naive.  I've also searched for quite a while today and have not found much on API integration of A360 and/or C4R.  If this has been asked and answered, a link would be very much appreciated.

 

 

Thanks much!

-G

65 REPLIES 65
Message 41 of 66
ali.talebi
in reply to: jeremytammik

Hi Jeremy,

 

since we couldn't find a way to directly access the model in C4R via api, I tried to find a way to remove the manual step of publishing to cloud after model sync. below are the calls required to do this:

// get cloud document/model and project name
string docName = CollaborateUtils.DocumentFileName(e.Document);
string modelName = null;
string projectName = null;
var docNameSplit = docName.Split(new char[1] { '/' }, StringSplitOptions.RemoveEmptyEntries);
modelName = docNameSplit.Last();
projectName = docNameSplit[1];
// find the current project and model id
var cloudProjects = CollaborateUtils.GetCloudProjects(e.Document);
var currProject = cloudProjects.FirstOrDefault(cp => String.Equals(cp.Name, projectName, StringComparison.CurrentCultureIgnoreCase));
var models = SynchronousManagementClientAccess.GetModels(currProject.Id);
var currModel = models.FirstOrDefault(m => String.Equals(m.Name, modelName, StringComparison.CurrentCultureIgnoreCase));
// publish to BIM360 cloud
VersioningClientFactory versioningClientFac = new VersioningClientFactory();
IVersioningClient versioningClient = versioningClientFac.CreateVersioningClient();
var publishTaskAsync = versioningClient.PublishModelLatestVersionAsync(currProject.Id, currModel.Id, new Func<string, int, string>(ManageSSO.getSignedUrl), default(CancellationToken));
publishTaskAsync.Wait();

above code is run in doc_synced event so it automatically publishes model to cloud for forge api access. below dlls are used as references:

CollaborateDB.dll

RSCloudClient.dll

Autodesk.RevitServer.Versioning.Client.dll

DBManagedServices.dll

Message 42 of 66
jeremytammik
in reply to: ali.talebi

Dear Ali,

 

Thank you for sharing that!

 

I am asking the developers once again where we are with the effort to provide a Revit API to open and initiate C4R models. By the way, regarding that, here are two actions recommended for all interested partners:

 

  • Vote on the Revit idea
  • Join Revit Preview and review the what's new documentation

 

I also added your workaround description to ask what they think about that, and underline the urgent need for a solid solution.

 

Cheers,

 

Jeremy



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

Message 43 of 66
callumf
in reply to: jeremytammik

Hi guys, 

 

We have programatically worked with C4R models by searching through local Journal files to link the GUIDs of the collaboration cache to Model names. This enables us to use the API to open the 'hidden' local files rather than the BIM:360 central file, sync to central, then export, run routines, etc.

 

  •  This isnt really opening the C4R model directly, but has enabled us to keep our Addins working.
  •  I doubt this is recommended by Autodesk, but until we have a dedicated API for this it works fine
Tags (1)
Message 44 of 66
Anonymous
in reply to: jeremytammik

Hi, Does Revit 2018 API have functionalities to allow and connect to cloud services like Insight - Green Building Studio and export IDF file ?

Message 45 of 66
jeremytammik
in reply to: Anonymous

The Revit API is a .NET API, and yes, the .NET programming environment enables connection to any cloud service you like.

 

Cheers,

 

Jeremy



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

Message 46 of 66
WM_Ron_Allen
in reply to: Anonymous

Once in insight the data can be exported in a number of formats.


Ron Allen
Ware Malcomb Bim
Message 47 of 66
Anonymous
in reply to: jeremytammik

I'm late to a cool discussion here. Nice to meet you Sherbs and Jeremy. Good to see you Ron. Josh from BIM Earth here. Let's cut to the chase. Sherbs, can you write an api to send/receive Revit cloud data to BIM Earth servers? Jeremy, let's run this by Anagnost - go see bimearth.com to see how easy, simple a 'funnel' for 'bim' plays can/should be. I'm all ears, flexible, open to our ideas, assistance, introductions, investment... and ready to act... R, Josh

Tags (1)
Message 48 of 66
WM_Ron_Allen
in reply to: Anonymous

In the new GEN2 interface with Forge you can probably push from there : ) Look to Autodesk for some announcements coming 'soon'


Ron Allen
Ware Malcomb Bim
Message 49 of 66
michael_coffey
in reply to: callumf

Can you share your code to get the model or is it IP?  I'm trying to write an app that makes a copy of the BIM 360 model to a folder (for archiving purposes).  Thanks.

Message 50 of 66
callumf
in reply to: michael_coffey

Hi Michael, all my code is Python but the essence is that your Local Journals contain a record of the C4R projects you open and their GUIDs. Here are the steps to retrieve them:

 

1. First, have a look at your Local AppData folder:

"...\AppData\Local\Autodesk\Revit\Autodesk Revit 2017\CollaborationCache"

 

You will find a multi-lettered folder, jump into that and see the folders titled with GUIDs. This is the Folder GUID we need from the journal file.  Inside these folders are one (or more) RVT project files with different GUIDs, one of these will be the Local copy of your C4R model. This is the RVT File GUID we need from the journal file

 

2. So with code, loop through all Journal files (sorted by most recent first), and look for a line line this:

 

' 1:< ModelPath Created: Is server path = True, Central server = "https://model15.skyscraper.autodesk.com:443/ModelService2015/ModelService.svc/basichttpbuffer", Path = "CLD:\\{532ebf04-fe65-463b-91f9-0859ff7f354c}Project%20Folder\{0cde3035-f9f4-4bbd-835f-fb58cac0689f}Name%20of%20project.rvt" 

 

A few things to note:

- "ModelPath Created: Is server path = True, Central server = " is the string to search for in the lines of the journal

- This line contains the name of your C4R project 'Document.Title'

- There are two GUIDs, the first one is Folder GUID, the second is the RVT File GUID

 

3. Using these two GUIDs you can find both the Folder and Filename of your Local C4R model in your Local AppData folder "...\AppData\Local\Autodesk\Revit\Autodesk Revit 2017\CollaborationCache"

 

A couple of comments:

- Journal files are huge, and there are alot of them. Make sure your loops break out once they have found the GUIDs they need otherwise you will always be scanning through every journal.

- This process has worked well for us so far, but I can think of quite a few risks (Autodesk changing how this line in the Journals is written, Incorrect Journal entries, project files not yet opened, GUIDs changing etc)

 

Any questions let me know, Hope this helps

Message 51 of 66
WM_Ron_Allen
in reply to: WM_Ron_Allen

''this was as far as I got... Someone want to add on and post the rest back here? 
Attribute VB_Name = "RevitJournalCache" Public fso 'as New FileSystemObject Public oUsrFolder 'as Folder Public oRvtFolder 'as Folder Public rvers 'as Integer Public ifp 'as String Public sfp Sub LinkToJournalFiles() Set fso = CreateObject("Scripting.FileSystemObject") ''Current user (Or all users?) For Each oUsrFolder In fso.GetFolder("C:\users").subfolders ''Scan for versions of Revit ifp = oUsrFolder.Path & "\AppData\Local\Autodesk\revit" If fso.FolderExists(ifp) Then For Each oRvtFolder In fso.GetFolder(ifp).subfolders Set sfp = regexp(oRvtFolder.Path, ".*\\(Autodesk Revit .*)\\{0,1}") If sfp.count > 0 Then ParseRevitFolder (oRvtFolder) Next End If Next oUsrFolder End Sub Sub ParseRevitFolder(RevitFolder) FilePath = RevitFolder & "\Journals\" Set RevitFolder = fso.GetFolder(FilePath) Dim ofile Dim subfolders 'as Folder Dim rfile Dim fstr ''As String ''scan the folders ''Gather GUIDs ''Create MKlinks or shortcuts to the GUIDs based on the file names For Each ofile In RevitFolder.Files If regexp(ofile.Name, "(journal\.\d{4}\.txt)").count > 0 Then ''match Set rfile = fso.OpenTextFile(ofile.Path, ForReading) fstr = rfile.ReadAll rfile.Close Set pgroups = regexp(fstr, "(IDOK.+CLD.+\.rvt\" & Chr(34) & ")") ''find groups If pgroups.count > 0 Then For Each cslid_fn_groups In pgroups Set pairsearch = regexp(cslid_fn_groups.Value, "\:\/\/(\{.+\})(.+)\/(\{.+\})(.+)").Item(0).SubMatches ''each item in pairsearch ''n(0)=CSLID Project ''n(1)=Project Name ''n(2)=CSLID model file '''<<<<<<<<<<<<<<<Gather CSLIDs ''n(3)=MODEL File name '''<<<<<<<<<<<<<<<Gather File Names Next cslid_fn_groups End If ''use regex to search multipline file ot return values End If Next ofile End Sub Function regexp(strSource, strPattern 'as String) 'as Variant Dim objRegEx 'as New regexp Dim result ''As String Dim allMatches ''As Object Set objRegEx = CreateObject("vbscript.regexp") On Error Resume Next objRegEx.Pattern = strPattern ''objRegEx.Global = True objRegEx.IgnoreCase = True Set allMatches = objRegEx.Execute(strSource) Set regexp = allMatches End Function
Ron Allen
Ware Malcomb Bim
Message 52 of 66
michael_coffey
in reply to: callumf

I think I may have solved this in a simpler way and maybe less prone to Autodesk changes to journal files, because I'm not using them.  Essentially, I'm getting the CollaborationCache folder for the Revit version, getting all the project files in order by modified date, then checking if the centralPath matches the current open model.  This is untested on actual project (just a test one) but let me know if you think there is any potential issues.  Thanks for the info!

 

if (centralPath.StartsWith("BIM 360:"))
{
      string localappDatapath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
      string revitCollabPath = Path.Combine(localappDatapath, $"Autodesk\\Revit\\Autodesk Revit {uiApp.Application.VersionNumber}\\CollaborationCache");
      if (Directory.Exists(revitCollabPath))
      {
             var files = Directory.GetFiles(revitCollabPath, "*.rvt", SearchOption.AllDirectories).OrderByDescending(d => new FileInfo(d).LastWriteTime);
             foreach (string filePath in files)
             {
                   BasicFileInfo bfi = BasicFileInfo.Extract(filePath);
                   if (bfi.CentralPath == doc.PathName)
                   {
                          File.Copy(filePath, newCentraltoRename, true);
                          break;
                   }
             }
      }
      else
           TaskDialog.Show("Error", "Could not locate local model folder.");
}
Message 53 of 66
callumf
in reply to: michael_coffey

Thats a very elegant solution Michael, much better than scanning journals. Only curveball is that there seems to be two Local models, one inside a folder called 'CentralCache' with the same timestamp etc.

 

Here is your solution in Python (with an exclusion of the 'CentralCache' folder):

import os
doc = __revit__.ActiveUIDocument.Document

collaborationPath = os.path.expanduser('~')+r'\AppData\Local\Autodesk\Revit\Autodesk Revit '+app.VersionNumber+r'\CollaborationCache'
for (dirpath, dirnames, filenames) in os.walk(collaborationPath):
	for file in filenames:
		if file[-4:] == '.rvt' and 'CentralCache' not in dirpath:
			fileInfo = BasicFileInfo.Extract(dirpath+'\\'+file)
			if fileInfo.CentralPath == doc.PathName:
				print 'Found your Local file'
				print fileInfo.CentralPath
				print dirpath+'\\'+file
Message 54 of 66
ali.talebi
in reply to: callumf

I have found another solution. I need to confirm with Jeremy but its related to the work on how to publish to BIM 360 I posted few months back here:

 

It doesn't need to have model previously checked out on the machine. it goes like this:

 

var prjName = "<enter your project name>";
var modelName = "<enter your model name>.rvt";

var cloudProjects = CollaborateUtils.GetCloudProjects(RevitUIApp.ActiveUIDocument.Document);
var project = cloudProjects.FirstOrDefault(cp => String.Equals(cp.Name, prjName, StringComparison.CurrentCultureIgnoreCase));
var models = SynchronousManagementClientAccess.GetModels(project.Id);
var model = models.FirstOrDefault(m => String.Equals(m.Name, modelName, StringComparison.CurrentCultureIgnoreCase));

string text = "Unknown";
string loginUserName = ManageSSO.getLoginUserName();
string accessToken = ManageSSO.getAccessToken();
string strUserName = text;
string strSSO_UserName = loginUserName;
string strSSO_AccessToken = accessToken;
string machineName = Environment.MachineName;
var guid = Guid.NewGuid();
ModelLocation ml = new ModelLocation(String.Empty, String.Empty, ModelLocationType.Server);

string pathToCollaborationCache = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 
@"Autodesk\Revit\Autodesk Revit " + RevitUIApp.Application.VersionNumber + @"\CollaborationCache\SOMEFOLDER");
string strDestinationPathFolder = System.IO.Path.Combine(pathToCollaborationCache, project.Id.ToString());
if (!System.IO.Directory.Exists(strDestinationPathFolder)) { System.IO.Directory.CreateDirectory(strDestinationPathFolder); }
string strDestinationPath = System.IO.Path.Combine(strDestinationPathFolder, model.Name);
DataStorageClient.DataStorageToolClient.CreateRvtFileFromCentralModel(project.Id.ToString(), model.Id.ToString(), ml, strDestinationPath, strUserName, 
strSSO_UserName, strSSO_AccessToken, true, true, string.Empty);

var modelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath(strDestinationPath);
var openOptions = new OpenOptions();
var document = RevitUIApp.OpenAndActivateDocument(modelPath, openOptions, false);

 

This will create a Revit model inside "%localappdata%\Autodesk\Revit\Autodesk Revit <version>\CollaborationCache\SOMEFOLDER" folder and then hopefully the rest is readable 🙂

 

below dlls are used as references:

CollaborateDB.dll

RSCloudClient.dll

Autodesk.C4R.Model.Common.dll

DBManagedServices.dll

Message 55 of 66
michael_coffey
in reply to: ali.talebi

Hi,

Where does the CollobarateDB.dll come from?  I can't find it in the Revit 2019 install folder.  Also what using statements do you have?  I'm getting 7 errors, but can't find that dll.  Errors are from:

CollaborateUtils

SynchronousManagementClientAccess

ManageSSO

ModelLocation

ModelLocationType

 

Thanks.

Message 56 of 66
ali.talebi
in reply to: michael_coffey

I have tested this on 2018 but missing dlls should be under:

C:\Program Files\Autodesk\Collaboration for Revit <version>\

 

 

Message 57 of 66
Anonymous
in reply to: ali.talebi

Thanks for your sharing @ali.talebi.

I tested this code but I just get projects on BIM team not BIM 360.

var cloudProjects = CollaborateUtils.GetCloudProjects(RevitUIApp.ActiveUIDocument.Document);

So, is this code possible with BIM 360?

Thanks for your support!


Message 58 of 66
ali.talebi
in reply to: Anonymous

Thanks minh. This can be used to open C4R models directly via API where it was not possible via Forge. I think Forge API can already help with BIM 360 part if I'm right.

Message 59 of 66
michael_coffey
in reply to: Anonymous

Is there documentation on this API?  Why would you need an active document to get the cloud projects you have access to?

Message 60 of 66
ali.talebi
in reply to: michael_coffey

I think this is a question for Revit API team. It seems to be working for me but Jeremy can confirm if this is the right approach or not.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community