0

When I get the download link for a Revit Model obtained in the cloud as shown here. I found that sometimes the link returns a Revit file and sometimes a zip file. I am passing this URL to Design Automation so it sometimes fails (in case the link downloads a zip file). How can I differentiate between the two items when in both cases item.data.attributes.displayName returns *.rvt. And what should be done to obtain rvt file in all cases?

This question discusses the same problem but there is no solution (it was 2 years old, hopefully something changed).

Rahul Bhobe
  • 4,165
  • 4
  • 17
  • 32
Mostafa abdo
  • 616
  • 1
  • 8
  • 21

1 Answers1

0

Revit 4 worksharing, publishes a file to BIM360.

This file is named as a .rvt file (ie. 'mybigrevitproject.rvt'), but in fact, it's really a zip file in disguise. If you rename it to zip, download it, and unzip it, you'll find lots of .RVT inside the zip.

There's a neat trick to figuring this out, without downloading the entire file.

Use a range GET on the first 16 bytes, and check for the magic header.

For full details, check out this repo: https://github.com/wallabyway

Here's a snippet of the code that will help: https://github.com/wallabyway/bim360-zip-extract/blob/master/server.js#L167


UPDATE: I meant to say this repo: https://github.com/wallabyway/bim360-zip-extract

You can find the magic header signature, based on this pkzip info here: https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html

The signature of the local file header. This is always '\x50\x4b\x03\x04'.

The code for the range get is:

const chunksize = 16 * 1024; // only need 16k bytes of data
const buffSignature = await this._fetchWrite(0, chunksize); // fetch/write header   

// something like this...
if (buffSignature.slice(0,3) === \x50\x4b\x03\x04)  {
   console.log("this is a zip file, not a Revit file...");
}


async _fetchWrite( offset, length ) {
        const res = await fetch( this.URL, { headers: {
            'range': `bytes=${offset}-${offset+length}`,
            'Authorization': `Bearer ${this.token}`
        }});
        if (res.status != 206) 
            throw(`error:${res.statusText}, bytes=${offset}-${offset+length}`)
        const buff = await res.buffer();
        return buff;
}
michael beale
  • 1,014
  • 1
  • 6
  • 5
  • I was able to extract the file using your suggestion. However, for some reason I can't use this https://forge.autodesk.com/blog/check-version-revit-file-hosted-cloud to determine Revit version on files from zip. It does work with normal files. – Mostafa abdo Feb 05 '22 at 03:16
  • that's correct. when the Model Derivative API extracts out a Revit into SVF format, it can see what Revit version it's processing, and adds it to the manifest. However, in this case, a zip file is being processed, which is not a Revit file, hence the special version parameter is not added into a manifest, like the blog post suggests. You would have to extract out the Revit file from the zip, then upload it to Model Dev. and then see the version number. Makes sense ? – michael beale Feb 08 '22 at 20:20
  • The post (original part) shows how to extract the version from encoded bytes and this is what I tried. It would be easier than uploading to Model Dev. Is it possible to extract info from encoded bytes? – Mostafa abdo Feb 09 '22 at 14:24
  • Yes, you are right. You will use the same 4 steps in the GitHub repo. The nodejs code will download the header bytes, footer bytes, locate byte offset to your master.rvt file, grab bytes at offset and length to your Revit file, then perform zip uncompress of entire revit file to find magic header. You could test for magic header in its compressed form as a gamble. Or.. hack the zip library to uncompress the magic header (but that’s ninja territory) - ain’t worth the effort, for little gain. – michael beale Feb 10 '22 at 20:08