Onbox, DirectContext Jig and No CDN

Today is rainy, grey and dreary... autumn is here for real. Here are some autumnal topics for this week to cheer us all up:

The Onbox Cross-Platform Revit API Framework

Thiago Almeida of Blackbird Industries shares some exciting news in his Revit API discussion forum thread introducing a Revit API framework, saying:

I have been programming Revit API for at least 8 years now and always tried to find ways to make my work easier. I have always wanted to have data-rich apps that communicate with the cloud. With the introduction of Autodesk Forge a few years back, I had the need to share even more code between various projects and assemblies.

Today, I'm thrilled to introduce the Onbox Framework, a free and open-source (MIT) to help us build cross-platform Revit Apps in a similar fashion to Angular and ASP.Net Core. It is designed to make it easier to create a jump between these environments without workflow disruptions. It introduces several features out-of-the-box, like dependency injection (IOC Container), state management, asynchronous Revit calls, a component-based MVC library made on top of WPF, and much more!

Here is the reference of the libraries that compose the framework and their NuGet packages, notice that most of the libraries are targeting .Net Standard to be used both on .Net Framework and .Net Core:

We have built parts of several applications using some of these libraries. Our current working project, Shedmate app, is the one that relies on it the most. I would say parts of it because only some libraries existed when we started coding the app. Shedmate is a web-based 3d configurator that needs to process the same data models in different places: Revit, our ASPNet Cloud server, and our front end Angular app. The cool thing here is that we can share services between the Revit and ASP and even run a script to generate our data models in typescript for Angular!

Simplicity: None of the features that Onbox provides out of the box are really trying to be the best ones in the industry. The framework is made with simplicity in mind, we tried to simplify the implementations as much as we could, even when we wanted to provide more functionality, we tried to make it easy to consume simpler versions of the APIs.

Modularity: The framework aims for modularity, so the idea here is that you can introduce new functionality by yourself. Our libraries, e.g. Container, Mapper, State Management, Async are tiny and are not trying to solve every single problem or implement every single feature, also they can always be replaced by more mature ones out there.

Flexible: The framework also aims to be flexible, if you have an existing Revit plugin and want to give Onbox a try, you would just swap the implementation for your external application and then for the external command implementations you want the container to be injected on. You are good to go!

Testability: With the loosely coupled architecture that the framework helps you to build, you can then use any unit testing frameworks like Dynamo's Revit Tester Framework or Geberit's Revit Test Runner. We are even using Design Automation on Forge to unit test our Revit Apps. That way, everything can be integrated into a CI/CD pipeline.

Documentation: Documentation is in its early stages, (yeah I know.. documentation is important). We have a simple Getting Started Guide here and the complete API documentation here. The written tutorials explaining the main concepts are still of the libraries are still in the works, and we will be doing constant updates on it from now on (now that AU recordings are finally over).

Usage and Collaboration: Everyone is welcome to use it and collaborate! Being MIT licensed, you can take any parts of the framework and modify it to your usage, this is simple, because the libraries are tiny. The same thing for eventual bugs, you can step in and fix them yourself or log an issue on GitHub. We would appreciate any code pull requests, contributions to the documentation, and publications you make for it. The idea is to have a mature Framework so everyone can collect the benefits.

AU 2020: I'm teaching two classes on AU this year. One is an industry talk (Lessons Learned in Three Years of Forge Dev – SD468705) that talks about our 3 years of Experience using Forge, the issues and problems we faced, and some tips and tricks for you do not waste so much time as we did try to solve them. During the class we explain the benefits of using a loosely coupled architecture for building Revit applications. The other one is a lab (The Cross-Platform Revit – SD468797-L). This one goes through an overview process of building multi-platform Revit apps, we show how to share base code for Revit plugins, Dynamo (Zero touch) nodes, and Design Automation for Revit, and we use the framework do help us to do so. If you are interested in the framework, please attend these classes next month on AU.

Onbox framework

Many thanks to Thiago for sharing and documenting this powerful framework!

DirectContext Rectangle Jig

The DuplicateGraphics SDK sample demonstrates basic usage of the IDirectContext3DServer interface for displaying arbitrary 3D graphics in Revit introduced in Revit 2018, also discussed in the Revit API discussion forum thread on how to draw or render over the active view.

So far, I have not seen any other examples making use of this, so I was very glad to see Kailas Dhage's sample to implement a plan view rectangle input jig in his recent comment, saying:

I am working with a feature in which user would like to pick two corner points of rectangle and would like to see jig of rectangle while picking points. It works correctly in structural plan views like Level 1 and Level 2, but does not work correctly in a 3D view.


Can you please suggest changes to the following function, so that it returns correct mouse position in Revit model coordinates in a 3D view?

  XYZ GetMousePoint()
    var view = this.HostApplication.ActiveUIDocument.ActiveView;
    var uiView = GetActiveUiView( this.HostApplication.ActiveUIDocument );
    var corners = uiView.GetZoomCorners();
    var rect = uiView.GetWindowRectangle();
    var p = Cursor.Position;
    var dx = (double) (p.X - rect.Left) / (rect.Right - rect.Left);
    var dy = (double) (p.Y - rect.Bottom) / (rect.Top - rect.Bottom);
    var a = corners[ 0 ];
    var b = corners[ 1 ];
    var v = b - a;
    var q = a
      + dx * v.X * XYZ.BasisX
      + dy * v.Y * XYZ.BasisY;
    return q;

Answer: To handle the 3D view projection, you will have to apply the appropriate 3D view orientation transform to the mouse input coordinates. That is not completely trivial...

In any case, here is RevitJigSample.zip with the 2D sample code for your reference.

The code is based on the IDirectContext3DServer, in which we push graphics to the Revit graphics pipeline and remove when done.

Many thanks to Kailas for sharing this useful demo!

Creating Reports from AutoCAD and Revit

Quick end user oriented Q & A on AEC reports and dashboards:

Question: I am searching a product to create reports and insights from data generated by AutoCAD and Revit to bridge between construction engineering and business divisions. Where can I look?

Answer: Construction.Autodesk.com has information about the entire Autodesk portfolio of products for the construction space. Specifically, you can take a look at Assemblesystems.com. Assemble is capable of aggregating data from AutoCAD, Revit and Navisworks. After that, you can use Power BI integration to create a Dashboard to share results with stakeholders.

RevitApiDocs Statistics

Gui Talarico has put in a lot of work in recent years providing and maintaining the Revit API documentation online:

I just asked him about support for the Revit 2021 API and future releases, and it seems like Gui is happy to help with that.

In the process, he shared some usage statistics from the revitapidocs web site that may be of interest to others as well:

RevitApiDocs statistics

Many thanks to Gui for all his work providing us with these invaluable online API docs!

Stop Using JavaScript CDN

Terence Eden presents some very valid reasons against using a third party Content Delivery Network in his encouragement to please stop using CDNs for external JavaScript libraries.