DA4R, FindInserts, Deployment and SplitButton

As usual, I am all too busy on the Revit API discussion forum. So many interesting things going on there. Also, the newest DA4R recording is now available online:

Forge Design Automation API for Revit Recording

Sasha Crotty, Senior Product Manager, Revit Platform & Services, gives a 77-minute overview and demos of the Design Automation API for Revit on Forge:

To learn more on this topic, visit the Forge Design Automation API docs and The Building Coder DA4R topic group.

Design Automation for Revit Supports IFC

As we already mentioned briefly last month, DA4R now supports both FBX and IFC. Once again:

Question: Does Revit Design Automation support IFC import and export?

We also use Tekla and LargeIFC models (1GB) for concrete pre-construction. Importing these IFC models takes a long time, and we are looking at Design Automation to speed this up.

Answer: Yes, Design Automation for Revit supports IFC.

Revit 2018 supports Open IFC and Export IFC functionality.

Revit 2019-2020 supports Open IFC, Export IFC and Link IFC functionality.

You can check it out for yourself in the design automation tutorial task 7, submit a workitem, towards the bottom of the page.

What Does the FindInserts IncludeShadows Flag Do?

A quick clarification prompted by the Revit API discussion forum thread on FindInserts and what does includeShadows flag do:

Question: Curious what does the includeShadows flag do in THE FindInserts method of the HostObject class.

FindInserts

The documentation says "True if shadows should be included in the return." But this doesn't make any sense to me.

Could anyone possibly shine some light on this?

Answer: Good question. I see two more of the same in the revitapidocs page on FindInserts.

I asked the development team and they replied:

An internal WallShadowCutoutGStep is created when 2 walls are joined, e.g., by Modify → Geometry → Join, and then a window is placed on one wall.

In that case, Revit will cut an opening on the other joined wall, as you can see in this picture:

Wall shadow cutout

For this API – FindInserts, here is a short demo recording – i try to find the inserts on the joined wall but not the wall with the window:

FindInserts demo

The window instance with element id 354965 is returned if includeShadows is true, and nothing returned for false.

Many thanks to Phil Xia for this detailed explanation!

Response: Thank you for bringing light into the shadow   :-)

Makes much sense now.

Easiest Solution to Deploy Add-In

A simple deployment of Revit add-ins is sought in the Revit API discussion forum thread on easiest solution to deploy add-in in office:

Question: I'm kind of new to this whole API but I have prepared some small codes to be used throughout office.

I know this question has been asked previously but I didn't see any easy solution. I just want to ask if there is an easy way to push an add-in to the other users at my office. Considering possible updates that might need to be implemented later, is it better to have them on network?

Could it be easier to change the code for a macro and push that to individual projects or each user's Revit?

How are you deploying them in your office?

We have a small office size with around 12 Revit users.

So, I have 10+ machines, each with 3 versions of Revit, and the fact that I don't want to copy files for each of them manually. I don't know in the long run how I will be able to update the code for these machines ,and I can't rely on individuals to do it themselves. This part is important, since I'm not a professional coder.

Answer: All you need to deploy an add-in is to copy the add-in manifest .ADDIN file and the .NET assembly .DLL to a specific location on the target machine.

To deploy a macro, all you need is to copy an RVT. For an application macro, I imagine it would be a handful of files.

You could also consider deploying your code as a Dynamo package or a RevitPythonShell script.

The RevitPythonShell installer is available as source code and demonstrates how you can deploy an add-in to any machine with a single click.

Response: Macro seems a good idea if I can import them into our template file or just open each ongoing project and copy it in the project. Still, I will need to rewrite the add-in code for macro.

Dynamo would be great! But I'm writing code in C# as add-in. Is there an easy way to convert them to Dynamo nodes? As I have heard, there are some differences between code for Dynamo node and add-in.

Answer: I'm facing the same problem as you. As said, you need to copy compiled files (.dll, .addin and maybe .pbd) to the target machine.

I found a fairly easy way to achieve this using a batch file. It copies these file from a server to user's Revit addin directory:

@echo off
rem --------------------------------------------COPY FILE TO TARGET MACHINE-------------------------------------------
rem /i option is needed to avoid the batch file asking you whether destination folder is a file or a folder
rem /e option is needed to copy also all folders and subfolders
rem /y option is needed to overwrite existing files without prompt 
if not exist "%USERPROFILE%\AppData\Roaming\Autodesk\Revit\Addins\2019\" mkdir "%USERPROFILE%\AppData\Roaming\Autodesk\Revit\Addins\2019\"
DEL /F/Q/S "%USERPROFILE%\AppData\Roaming\Autodesk\Revit\Addins\2019\" > NUl   
xcopy "YOUR ADDIN DIRECTORY" "%USERPROFILE%\AppData\Roaming\Autodesk\Revit\Addins\2019" /i /e /y
pause

del %SCRIPT%

In my case, it does require the individual user to click on the batch file to download/update, but I reckon you could modify the code so that it copies to everyone's machine by one click from you.

Response: I am also interested in this.

What I have done in my office is to put the .dll in a read-only location in the server and I created a BATCH file to copy the .addin to each person's computer. This way, I just need to go to their computer and click on the BATCH file. And if I want to make changes to the tools, I just have to overwrite the .dll in the server and everybody gets the update.

However, I am not sure if this a good practice as many people are reading the same dll.

Answer: Why not also copy the .dll file? I copy my .addin and .dll files from a location on our server to all BIM modellers' workstations using Group Policy, so I know that everyone will get an updated version if I just change the file on the server.

Response: That is, in fact, a good idea. When I started my strategy I was new in the office and didn't know about the group policy.

I will have a chat with the IT managers and ask them to do this.

Thanks!

Always Show the same Button in SplitButton

Rikard Nilsson, Solution Architect at Cadcraft, read the manuals more carefully than I did and suggests a much simpler and better solution in his thread on how to always show the same button on SplitButton:

Question: I created some buttons and placed them inside a SplitButton.

The problem I have is that I want have the same effect that Revit has in their buttons.

I want to show the same button always, even if I choose one further down in a SplitButton.

When I choose a button below in mySplitButton, it will always become the new default that shows on the SplitButton.

Answer: That is easy to achieve.

I show you how in my HoloLens Escape Path Waypoint JSON Exporter.

The add-in displays the following ribbon panel:

ExportWaypointsJson ribbon panel

You can either click the main button, which is always displayed at the top as the current option, to trigger the main command, or drop down the rest of the stacked button contents to display the option button:

ExportWaypointsJson main command and settings buttons

You can grab the entire Visual Studio solution and project from the ExportWaypointsJson GitHub repository.

Response: This was my simple solution, using the SplitButton.IsSynchronizedWithCurrentItem property:

Indicates whether the top PushButton on the SplitButton changes based on the CurrentButton property.

If this property is true the SplitButton uses the current PushButton's properties to display the image, text, tooltip, etc. and executes the current item when clicked. If it is false the first listed PushButton in the GetItems() return is shown, and executes this PushButton when clicked. If it is false the items in drop down list can only be executed by opening the drop down list and clicking an item in the list. The default value is true.

  splitButtonClearLoads.IsSynchronizedWithCurrentItem = false;

Many thanks to Rikard for pointing out this obvious solution, and happy advent to all!