Giter Club home page Giter Club logo

bim-net-interactive's Introduction

BIM Interactive Notebooks

This project explores the possibility run live Revit API C# code bundled with visualizations and explanatory text.

Amazing for rapid prototyping ๐Ÿš€- preferably powered by LLM. It is perfect for knowledge sharing, teaching BIM concepts and API development. The variable-sharing feature in NET Interactive lets us code C# against Revit and then use Python in another kernel. It is the missing data-analysis tool for Autodesk Revit!

Installation

A preview release of the addin is available under releases. Revit 2023 and 2024 is supported.

  • Download file msi or zip of the last release
  • Install the Revit addin and open Revit
  • "Interactive Revit Kernel" will show up in the Add-Ins tab
  • Click on the button to show the Kernel UI.

You will also need a notebook environment. I recommend Polyglot Notebooks, an extension to Visual Studio Code but it is also possible to use Jupyter Notebooks.

  • Install Visual Studio Code
  • Goto extensions -> Install Polyglot Notebooks
  • Polyglot Notebooks requires .NET 7 SDK

My first notebook

  • Create a new notebook in VS Code.
  • In Autodesk Revit, click start in the kernel UI

Add a new C#-code cell and install the revit kernel extension.

#r "nuget:RevitInteractive"

In another cell, use the #connect-directive to establish live connection to revit. Make sure to start the kernel first and specify the revit version.

#!connect revit --kernel-name revit --revit-version 2024

From now you'll be able to send code to Revit by starting the c#-cell with #!revit:

#!revit
var collector = new FilteredElementCollector( doc, uidoc.ActiveView.Id);

var query = collector
        .WhereElementIsNotElementType()
        .WhereElementIsViewIndependent()
        .ToElements();

var result = query.GroupBy(x => x.Category.Name).Select(y => new {
    Id = y.Key,
    Count = y.Count()
}).ToList();

display(result);
result

If you open a new model, you need to restart kernels in both notebook and in revit.

System Prompting LLM

When using LLMs such as ChatGPT to write revit API Code for use in the notebook you would probably want to steer it's behaviour to minimize editing the code for use in an interactive context. See System Promts for some initial drafts.

Begin conversation by:

[SYSTEM] {System prompt text}

Examples

I will try to collect som fun examples. There is also a collection of tutorials in the folder. Extracting profile geometry from floor and export to shapefile for GIS-visualization using C# and Python (with Shapely and Geopandas).

See samples/GIS/GIS Visualization Building Footprint.ipynb

Limitations

The Revit API is tightly coupled with the Revit UI and the Revit document data structures and operates on the assumption that it's being called within the same process where the UI and the document are loaded. This prevents you from calling the API from for example a polyglot notebook without some kind of middle-man or dispatcher.

Current solution

NET interactive operates with kernels. A kernel is simply a process that receives execution instructions from clients and communicates the results back to them. The decopuled two-process model where you separate execution from evaluation allows for an approach where an evaluator can live inside Autodesk Revit as an addin and receives code from frontend clients such as Polyglot Notebook, Azure Data Studio or Jupyter.

In .NET Interactive a proxy kernel is a concept that describes a subkernel that proxies a remote kernel. We can add a proxy kernel to the composite kernel that routes commands to the actual implementation written as a Revit Addin. The revit addin implements a NET Interactive kernel process and executes code in the Revit API thread using external events(check Jeremy Tammik's arcticle External Access to the Revit API for more info on this topic).

However, due to the issues with third-party conflicts regarding the Roslyn API:s it was a hurdle to compile the code in the Revit addin so I tested to move the compilation before the code is sent to the embedded kernel in Revit. Technically, it is done using a registered middleware on the proxykernel that compiles the code and then send the path to the compiled assembly to the revit addin which loads it into memory and executes a method defined in a common interface with a list of common variables.

Resources

Aknowledgements and third-party dependencies

License

MIT

bim-net-interactive's People

Contributors

chuongmep avatar jowsy avatar sweco-sejsau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

bim-net-interactive's Issues

Issue System.TypeLoadException: Method 'WriteTo' in type .. does not have an implementation

I saw a issue when try debug from my side, so it is same issue with your side ? I guess have some addin conflict here :

return new FormattedValue(mimeType, value.ToDisplayString(mimeType));

And here :

Formatter.SetPreferredMimeTypesFor(typeof(Element), "text/html");
//It's common for object graphs to contain reference cycles.
//The .NET Interactive formatter will traverse object graphs but in order to avoid both oversized outputs and possible
//infinite recursion when there is a reference cycle, the formatter will only recurse to a specific depth.
Formatter.RecursionLimit = 3;

System : Windows 11
Revit Version : 2024
Visual Studio Code : Latest
Extenstion Visual Code : Beta Latest
Details :
System.TypeInitializationException: The type initializer for 'Microsoft.DotNet.Interactive.Formatting.Formatter' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Microsoft.DotNet.Interactive.Formatting.HtmlFormatter' threw an exception. ---> System.TypeLoadException: Method 'WriteTo' in type 'Microsoft.DotNet.Interactive.Formatting.PocketView' from assembly 'Microsoft.DotNet.Interactive.Formatting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
at Microsoft.DotNet.Interactive.Formatting.HtmlFormatter..cctor()
--- End of inner exception stack trace ---
at Microsoft.DotNet.Interactive.Formatting.Formatter.ResetToDefault()
at Microsoft.DotNet.Interactive.Formatting.Formatter..cctor()
--- End of inner exception stack trace ---
at Microsoft.DotNet.Interactive.Formatting.Formatter.ToDisplayString(Object obj, String mimeType)
at Jowsy.Revit.KernelAddin.Core.RevitKernel.CreateSingleFromObject(Object value, String mimeType)
at Jowsy.Revit.KernelAddin.Core.RevitKernel.<>c.b__4_0(KeyValuePair2 v) at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Jowsy.Revit.KernelAddin.Core.RevitKernel.HandleAsync(RequestValueInfos command, KernelInvocationContext context) at Microsoft.DotNet.Interactive.Kernel.<>c__DisplayClass82_01.b__0(KernelCommand _, KernelInvocationContext context)
at Microsoft.DotNet.Interactive.Commands.KernelCommand.InvokeAsync(KernelInvocationContext context)
at Microsoft.DotNet.Interactive.Kernel.d__56.MoveNext()

Inline functions with return fails

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Start a new notebook
  2. Connect to Revit
  3. Add new cell with following code:
#!revit

Func<int, int, int> add = (int x, int y) => { return x + y };

display(add(5,5));
  1. Run it and following error appears:
Error: System.NullReferenceException: Object reference not set to an instance of an object.
at Jowsy.CSharp.SyntaxUtils.FixReturn(CompilationUnitSyntax root)
at Jowsy.CSharp.RoslynCompilerService.CompileRevitAddin(String script, Boolean toAssemblyFile, Func`1 KernelValueInfosResolver)
at Jowsy.DotNet.Interactive.Extensions.ConnectRevitKernelCommand.<>c__DisplayClass5_0.<<ConnectKernelsAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.DotNet.Interactive.KernelCommandPipeline.<>c__DisplayClass6_0.<<BuildPipeline>g__Combine|2>d.MoveNext() in D:\a\_work\1\s\src\Microsoft.DotNet.Interactive\KernelCommandPipeline.cs:line 73
--- End of stack trace from previous location ---
at Microsoft.DotNet.Interactive.KernelCommandPipeline.SendAsync(KernelCommand command, KernelInvocationContext context) in D:\a\_work\1\s\src\Microsoft.DotNet.Interactive\KernelCommandPipeline.cs:line 41

Expected behavior
Should return "10".

Desktop (please complete the following information):

  • OS: Win10
  • Revit version: 2024
  • VS Code Polyglot version: v1.0.5115021 (pre-release)
  • RevitInteractive package version: 0.1.0

Happy when have same idea

Just message with you that I have same idea before and very interesting with your project : https://github.com/chuongmep/JupyterBIM
My idea before is extend support for Navisworks, Autocad , Revit,... and the interactive not only write code with C#, it also support write with python script.
Can I know your roadmap are working on ?

Regard !

System.TypeLoadException: Conflict with System.Diagnostics.DiagnosticSource

There seem to a conflict with System.Diagnostics.DiagnosticSource. This happens when I start the kernel in the UI.

'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'Microsoft.DotNet.Interactive'. Symbol loading disabled by Include/Exclude setting.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'System.Reactive'. Symbol loading disabled by Include/Exclude setting.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'System.CommandLine'. Symbol loading disabled by Include/Exclude setting.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'System.CommandLine.NamingConventionBinder'. Symbol loading disabled by Include/Exclude setting.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Program Files\Autodesk\Revit 2024\AddIns\DynamoForRevit\System.Diagnostics.DiagnosticSource.dll'. Symbol loading disabled by Include/Exclude setting.
Exception thrown: 'System.TypeLoadException' in Microsoft.DotNet.Interactive
Exception thrown: 'System.TypeLoadException' in mscorlib.dll
Exception thrown: 'System.TypeLoadException' in mscorlib.dll

System : Windows 11
Revit Version : 2024

Setting list expansion limit

Is your feature request related to a problem? Please describe.
When outputting a IEnueramble the formatter will limit the output size. It will show ."..(more)"
See https://stackoverflow.com/questions/71972148/net-interactive-how-to-change-collection-output-size#:~:text=You%20can%20use%20Formatter%20from%20Microsoft.DotNet.Interactive.Formatting%20namespace%20to,of%20the%20output%3A%20using%20Microsoft.DotNet.Interactive.Formatting%3B%20Formatter.ListExpansionLimit%20%3D%2025%3B

Describe the solution you'd like
A option for changing Formatter.ListExpansionLimit.

Describe alternatives you've considered

Additional context

Namespace Imports

Is your feature request related to a problem? Please describe.
If you want to use types that is not part of the default list of usings you need to specify the full namespace for that class. You would for instance want to call Path without its full namespace System.IO.Path.

Describe the solution you'd like
At minimum it would be usable to at least be able to specify additional namespaces as settings. For instance, a list with using on separate lines.
If one could set additional namespaces and make it default that could be really useful also.

Describe alternatives you've considered
Even better, one would be able to specify using directly in a script and then it would be imported automatically for that session.

Additional context
Add any other context or screenshots about the feature request here.

Reference an external assembly

Is your feature request related to a problem? Please describe.
Allowing external references would allow you to use helper libraries in the code or third-part libraries.

Describe the solution you'd like
Implement the C#-scripting feature of referencing external assemblies using #r-directive.
The reference should be used for all cells in the current connection.

Following cell should add the reference for use in all cells.

#!revit
#r "c:\path\to\assembly.dll"

Error message points to incorrect line numbers

Describe the bug
Line number comes out wrong from the Roslyn-compiler.

To Reproduce
Steps to reproduce the behavior:
In Polyglot Notebook, run code with compile-time errors:

Expected behavior
From the errror text, one should be able to find the line in the code.
In the below case, the error should point to line 2, not 22.

Screenshots
image

Desktop (please complete the following information):

  • OS: Win10
  • Revit version: 2024
  • VS Code Polyglot version:
  • RevitInteractive Nuget version: 0.1.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.