This post is somewhat overdue and hence rather full of various topics, mainly due to my struggles with my MacBook slowing to an unbearable crawl in the heat last week:
My colleague Eason Kang researched how to access BIM360 file links in a Revit project and summarised the results for us:
Question: In Revit 2017, I used a method based on ExternalFileReferences
to report linked files hosted in BIM360.
In Revit 2019, this method no longer works.
TransmissionData
GetAllExternalFileReferenceIds
, used in the sample
to list linked files and TransmissionData
,
does not report links hosted in BIM360.
It reports local files that are linked only.
This is an old sample.ExternalFileUtils
GetAllExternalFileReferences
method does not return these items.Has there been a change in this area?
Is there a different method we should be using?
Answer: Neither of these two methods support cloud links in Revit 2018 or Revit 2019.
In Revit 2017, they appeared to work, because back then, the cloud links were downloaded as local copies by the Autodesk Desktop Connector before linking.
Nowadays, BIM360 cloud links are treated as external sources. This behaviour started from with Revit 2018.
Therefore, please use ExternalResourceUtils
GetAllExternalResourceReferences
instead.
Here is a working code snippet:
// Obtain all external resource references // (saying BIM360 Cloud references and local // file references this time) ISet<ElementId> xrefs = ExternalResourceUtils .GetAllExternalResourceReferences( doc ); string caption = "BIM360 Links"; try { int n = 0; var msg = string.Empty; foreach( ElementId eid in xrefs ) { var elem = doc.GetElement( eid ); if( elem == null ) continue; // Get RVT document links only this time var link = elem as RevitLinkType; if( link == null ) continue; var map = link.GetExternalResourceReferences(); var keys = map.Keys; foreach( var key in keys ) { var reference = map[key]; // Contains Forge BIM360 ProjectId // (i.e., LinkedModelModelId) and // ModelId (i.e., LinkedModelModelId) // if it's from BIM360 Docs. // They can be used in calls to // ModelPathUtils.ConvertCloudGUIDsToCloudPath. var dictinfo = reference.GetReferenceInformation(); // Link Name shown on the Manage Links dialog var displayName = reference.GetResourceShortDisplayName(); var path = reference.InSessionPath; } try { // Load model temporarily to get the model // path of the cloud link var result = link.Load(); // Link ModelPath for Revit internal use var mdPath = result.GetModelName(); link.Unload( null ); // Convert model path to user visible path, // i.e., saved Path shown on the Manage Links // dialog var path = ModelPathUtils .ConvertModelPathToUserVisiblePath( mdPath ); // Reference Type shown on the Manage Links dialog var refType = link.AttachmentType; msg += string.Format( "{0} {1}\r\n", link.AttachmentType, path ); ++n; } catch( Exception ex ) // never catch all exceptions! { TaskDialog.Show( caption, ex.Message ); } } caption = string.Format( "{0} BIM360 Link{1}", n, Util.PluralSuffix( n ) ); TaskDialog.Show( caption, msg ); } catch( Exception ex ) { TaskDialog.Show( caption, ex.Message ); }
Here are snapshots of the result:
Many thanks to Eason for this research and clear explanation!
I added this sample code to The Building Coder samples as a new external command CmdBim360Links in release 2020.0.146.0
Franco Tonutti researched and solved how to retrieve the RVT preview thumbnail image with Python in his comments on determining the RVT file version using Python
Question: Hi Jeremy, how can I get the preview image of a .rfa file?
I'm trying the following without success:
import os.path as op import olefile def get_rvt_preview(rvt_file): if op.exists(rvt_file): if olefile.isOleFile(rvt_file): rvt_ole = olefile.OleFileIO(rvt_file) bfi = rvt_ole.openstream("RevitPreview4.0") readed = bfi.read() f = open('my_file.bmp', 'w+b') f.write(readed) f.close() else: print("file does not apper to be an ole file: {}".format(rvt_file)) else: print("file not found: {}".format(rvt_file))
Answer: I have not looked into this for a while.
Please take a look at the other explorations reading RVT files without using the Revit API:
Response: Thank you very much.
I solved the problem by looking for
the PNG file signature 89504e470d0a1a0a
:
def get_rvt_preview(rvt_file, png_path): if op.exists(rvt_file): if olefile.isOleFile(rvt_file): # Open ole file rvt_ole = olefile.OleFileIO(rvt_file) bfi = rvt_ole.openstream("RevitPreview4.0") readed = bfi.read() # Find png signature readed_hex = readed.hex() pos = readed_hex.find('89504e470d0a1a0a') png_hex = readed_hex[pos:] data = bytes.fromhex(png_hex) # Save png file f = open(png_path, 'w+b') f.write(data) f.close() else: print("file does not apper to be an ole file: {}".format(rvt_file)) else: print("file not found: {}".format(rvt_file))
I already mentioned Paolo Serra's Dynamo Primer discussing Revit API versus Dynamo for Revit.
Here is another very valuable and extensive related resource of his, covering numerous aspects of Dynamo, its features, Python, the Revit API and the relationships between them.
In terms of Dynamo for Revit you can refer to my Dynamo Primer, specifically chapter 8 for the integration with Revit.
You can also check out the slide deck compendium I put together over the years that covers the basics of the Revit API and how to access it through Dynamo and Python at
It includes the following sections:
- Dynamo Overview
- User Interface
- Graphs Management
- Autodesk Standards
- Visual Programming Principles
- Filtering, Grouping & Sorting
- Dynamo-Excel Link
- Design Script
- Geometry Library
- Automation Applications
- Dynamo for Revit
- Dynamo and Python
- Object Oriented Programming
- Revit API Introduction
- Next Steps
As I mentioned in the introduction above, after three years or so, my MacBook Pro slowed down to an unusable crawl, especially when it got warm.
I looked at the results in the activity monitor, worrying about a virus, and only saw that the kernel_task
was often using several hundred percent of the CPU.
After weeks of this, I decided to upgrade OSX to the newest version to see whether that would help.
The upgrade went fine, and at least the situation was no worse.
Soon, however, the slowdown worsened still further.
Finally, I found the solution:
This description
of what kernel_task
is, and why it is running on my Mac,
explains how kernel_task
pretends to use CPU cycles to keep things cool.
That is confirmed by the Apple support thread
on kernel_task
using a large percentage of your Mac CPU.
In the next step, I looked at a helpful five-minute video on how to clean MacBook Pro fans.
Opening the MacBook is simple, but it does require the smallest screwdriver I have ever seen, a 1.2 mm Pentalobe:
I never opened the PC before myself.
Using that, however, it was easy to open and blow out the dust clogging the fans with a pressurised air spray can.
One fan was so clogged with dust it was probably not running at all.
It seems better now. Please keep your fingers crossed for me that it stays that way and continues working :-)
Turning from technical stuff to politics for a moment, Rezo's German 55-minute video about the failings of the established politicians who have been driving the planet to the brink of catastrophe, ignoring all scientifical evidence and economic indicators for several decades, caused quite a stir in the past few weeks, including affecting the recent election results:
I tested the auto-translated English subtitles for this video. Sorry to say, they do not make much sense in this case.