# LearnRevitAPI
> Learn the Revit API and pyRevit, one button at a time.
LearnRevitAPI is where Erik Frits teaches the Revit API and pyRevit: how architects, engineers and BIM people automate Revit with Python and build their own tools. Below is the catalogue, generated from the site itself: every training with its courses, modules and lessons, a title and one line each, then everything else the site publishes. Lessons are read inside the platform: a free training needs an account, a paid one the training.
The Revit API reference itself is not here: it lives at https://rvtdocs.com/mcp.
## Trainings
### Free pyRevit Course: Fast-Track
https://learnrevitapi.com/fast-track/
Free pyRevit Fast-Track: 13 short lessons to set up pyRevit, build your first custom extension and start automating Revit today. (free with an account)
#### pyRevit
https://learnrevitapi.com/fast-track/01-pyrevit/
##### Setup pyRevit
https://learnrevitapi.com/fast-track/01-pyrevit/01-setup-pyrevit/
##### Create Your Own Extension
https://learnrevitapi.com/fast-track/01-pyrevit/02-create-your-own-extension/
##### Anatomy of pyRevit
https://learnrevitapi.com/fast-track/01-pyrevit/03-anatomy-of-pyrevit/
#### Code-Editor
https://learnrevitapi.com/fast-track/02-code-editor/
##### Choosing Your Code Editor
https://learnrevitapi.com/fast-track/02-code-editor/04-choosing-your-code-editor/
##### Quick-Start VS Code
https://learnrevitapi.com/fast-track/02-code-editor/05-quick-start-vs-code/
##### Quick-Start Cursor IDE
https://learnrevitapi.com/fast-track/02-code-editor/06-quick-start-cursor-ide/
##### IDE Tour for Beginners
https://learnrevitapi.com/fast-track/02-code-editor/07-ide-tour-for-beginners/
#### First Button
https://learnrevitapi.com/fast-track/03-first-button/
##### Framework for new pyRevit Tools
https://learnrevitapi.com/fast-track/03-first-button/08-framework-for-new-pyrevit-tools/
##### Create Your First Button
https://learnrevitapi.com/fast-track/03-first-button/09-create-your-first-button/
##### Refine and add more features
https://learnrevitapi.com/fast-track/03-first-button/10-refine-and-add-more-features/
##### Stress-Test your tools
https://learnrevitapi.com/fast-track/03-first-button/11-stress-test-your-tools/
##### Super-Charge with AI
https://learnrevitapi.com/fast-track/03-first-button/12-super-charge-with-ai/
##### What's Next?
https://learnrevitapi.com/fast-track/03-first-button/13-whats-next/
### 21-Day pyRevit Challenge
https://learnrevitapi.com/join-challenge/
(paid, for members of this training)
#### Week 1
https://learnrevitapi.com/pyrevit-challenge/week-1/
#### Week 2
https://learnrevitapi.com/pyrevit-challenge/week-2/
#### Week 3
https://learnrevitapi.com/pyrevit-challenge/week-3/
#### Week 4
https://learnrevitapi.com/pyrevit-challenge/week-4/
#### Bonuses
https://learnrevitapi.com/pyrevit-challenge/bonuses/
### Academy
https://learnrevitapi.com/join-ai-lab/
(paid, for members of this training)
#### LRA-Basics
https://learnrevitapi.com/academy/basics/
#### LRA-Advanced
https://learnrevitapi.com/academy/advanced/
#### LRA-Modern UI
https://learnrevitapi.com/academy/modern-ui/
### LRA AI-Lab
https://learnrevitapi.com/join-ai-lab/
(paid, for members of this training)
#### 01. Quick-Start Setup
https://learnrevitapi.com/ai-lab/01-quick-start/
#### 02. Feel the Vibes
https://learnrevitapi.com/ai-lab/02-feel-the-vibes/
#### 03. Build pyRevit AI Engine
https://learnrevitapi.com/ai-lab/03-pyrevit-ai-engine/
#### LLM Wiki
https://learnrevitapi.com/ai-lab/llm-wiki/
#### Git for BIM Developers
https://learnrevitapi.com/ai-lab/git-for-bim-developers/
#### Live Call Recordings
https://learnrevitapi.com/ai-lab/live-calls/
## Blog
### NEW pyRevit 7.0 (Fast-Engine, MCP, WebView2 + NEW UI Workflow)
https://learnrevitapi.com/blog/pyrevit-7/
What is new in pyRevit 7.0: the faster engine, the built-in MCP server for AI agents, WebView2 windows and the new UI workflow.
### pyRevit MCP: Connect ANY AI Agent to Revit (Full Setup Guide)
https://learnrevitapi.com/blog/pyrevit-mcp-setup/
Full pyRevit MCP setup guide: connect Claude, Codex or any AI agent to Revit so it can read your model and run pyRevit tools from a simple prompt.
### The Full pyRevit Course for Beginners (Setup → Your First Button)
https://learnrevitapi.com/blog/fast-track-pyrevit-course/
Free pyRevit course for beginners: install pyRevit, set up your code editor and extension, and build your first custom Revit button from scratch.
### Convert Revit Coordinates with Revit API [Internal, Project, Survey]
https://learnrevitapi.com/blog/convert-coordinate-systems-in-revit-api-draft/
## Coordinate Systems in Revit

Revit Coordinate Systems is a tricky topic!
Especially if you want to automate coordinates with Revit API…
In Revit API you need to be careful with units that you use.
Because It's so easy to use the wrong units
and then spend hours looking for an issue….
*(Yeah… I've been there multiple times)*
**But don't worry,**
**I already did the hard work for you!**
It took me couple of days,
but now I have my own Coordinate Converter
than anyone can use in in 3 lines of code.
Yeah… It's that simple.
And the best part?
I'm going to share it with you in a moment for FREE.
It will literally save you days of headache
All you'll have to do:
- Copy my code
- Understand 3 lines on how to use it
- And enjoy the simplicity of working with coordinates
But before I share my grand solution…
Let's have a quick overview of coordinate systems in Revit.
## Coordinate Systems Overview
There are **3 Coordinate Systems **in Revit:
- **Internal **(Used as the internal system of Revit, used in Revit API)
- **Project (Based on Project Base Point)**
- **Survey **(Based on Survey Point)
Also keep in mind that in Revit we can set True North rotation, which will not affect all systems similar.
- **Internal **- True North Rotation is not applied
- **Project **- True North Rotation is not applied
- **Survey **- All coordinates will be affected by True North Rotation.

##
## 💡Pro Tip
Before you begin…
I really recommend creating proper tags to easily read correct values.,

It can easily help you avoid using the wrong units or data as you create your custom tools.
You can also push it a step further
and create tags for both:
- Metric Units
- Internal Units
This way you'll instantly notice if you're exporting the wrong data.
(Trust me, it happens way too often with coordinates when we use API…)
Alright and now - let's look into API
## Revit Coordinates in Revit API
First of all you need to know that Revit API always uses Internal Coordinate System in feet.
That means that when you read XYZ values, you'll get them in **Internal System in Feet**.
And it also means that you need to prepare your XYZ values in **Internal System in Feet**.
And if you forget this, don't be surprised when your
elements are flying in the sky above your project.
Now let's look at how to convert coordinates with Code.
## My Coordinate Converter Class
I've prepared a custom class that can convert XYZ points from any
coorindate system into any other with just a few lines.
🚨**ANd Spoiler alert:** you're about to see code that might scare many of you.
But y**ou don't even have to understand anything about it.**
👉 You just copy the code below.
👉 Paste in your script
👉 Scroll to next example to undrstand how to use it
```python
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝
#==================================================
from Autodesk.Revit.DB import *
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type:Document
# ╔═╗╦ ╔═╗╔═╗╔═╗
# ║ ║ ╠═╣╚═╗╚═╗
# ╚═╝╩═╝╩ ╩╚═╝╚═╝
#==================================================
class CoordSys:
Internal = 'Internal'
Project = 'Project'
Survey = 'Survey'
class PointConverter:
pt_internal = None
pt_survey = None
pt_project = None
def __init__(self, input_pt, coord_sys=CoordSys.Internal):
"""Converte 2.0 for converting XYZ points between any Coordinate Systems.
Args:
:param input_pt: The XYZ point in Internal Coordinate System. Adjust coord_sys argument if you want to use other Cooridnate Systems.
:param coord_sys: The coordinate system chosen from CoordSys helper class (Internal, Project, Survey)
Example:
pt = elem.Location.Point
converter = PointConverter(pt, CoordSys.Internal)
pt_survey = pt_converter.pt_survey # XYZ in FEET
pt_survey_m = pt_converter.pt_survey_m # XYZ in Meters
pt_converter.print_in_metric(coord_sys=CoordSys.Survey)
"""
# type: float, float, float, CoordSys
# Get Systems Transform
srvTrans = self._GetSurveyTransform()
projTrans = self._GetProjectTransform()
#1️⃣ INPUT - INTERNAL COORDINATE SYSTEM
if coord_sys == CoordSys.Internal:
self.pt_internal = input_pt
self.pt_survey = self._ApplyInverseTransformation(srvTrans, self.pt_internal)
self.pt_project = self._ApplyInverseTransformation(projTrans, self.pt_internal)
#2️⃣ INPUT - PROJECT COORDINATE SYSTEM
elif coord_sys == CoordSys.Project:
self.pt_project = input_pt
self.pt_internal = self._ApplyTransformation(projTrans, self.pt_project)
self.pt_survey = self._ApplyInverseTransformation(srvTrans, self.pt_internal)
#3️⃣ - SURVEY COORDINATE SYSTEM
elif coord_sys == CoordSys.Survey:
self.pt_survey = input_pt
self.pt_internal = self._ApplyTransformation(srvTrans, self.pt_survey)
self.pt_project = self._ApplyInverseTransformation(projTrans, self.pt_internal)
else:
raise Exception("Wrong argument value for 'coord_sys' in PointConverter class.")
#🧮 Create Metric Points
self.pt_internal_m = self._get_metric_XYZ(CoordSys.Internal)
self.pt_project_m = self._get_metric_XYZ(CoordSys.Project)
self.pt_survey_m = self._get_metric_XYZ(CoordSys.Survey)
def print_in_metric(self, coord_sys, units=UnitTypeId.Meters):
""" Helper function to display coordinates in Metric System."""
pt_m = self._get_metric_XYZ(coord_sys, units)
print('[{}] XYZ: ({}m, {}m, {}m)'.format(coord_sys, pt_m.X, pt_m.Y, pt_m.Z))
#🚧 INTERNAL HELPING METHODS
def _get_metric_XYZ(self, coord_sys, units=UnitTypeId.Meters):
"""Convert the point into Metric XYZ System.
NB! Do not use it with Revit API as it needs internal units."""
# Get Point With Correct Coordinate System
if coord_sys == CoordSys.Internal: pt = self.pt_internal
elif coord_sys == CoordSys.Project: pt = self.pt_project
elif coord_sys == CoordSys.Survey: pt = self.pt_survey
# Convert Values to Metric
X_m = UnitUtils.ConvertFromInternalUnits(pt.X, units)
Y_m = UnitUtils.ConvertFromInternalUnits(pt.Y, units)
Z_m = UnitUtils.ConvertFromInternalUnits(pt.Z, units)
return (XYZ(X_m, Y_m, Z_m))
def _GetSurveyTransform(self):
"""Gets the Active Project Locations Transform (Survey)."""
return doc.ActiveProjectLocation.GetTotalTransform()
def _GetProjectTransform(self):
"""Get the Project Base Points Transform."""
basePtLoc = next((l for l in FilteredElementCollector(doc) \
.OfClass(ProjectLocation) \
.WhereElementIsNotElementType() \
.ToElements() if l.Name == "Project"), None)
return basePtLoc.GetTotalTransform()
def _ApplyInverseTransformation(self, t, pt):
"""Applies the inverse transformation of
the given Transform to the given point."""
return t.Inverse.OfPoint(pt)
def _ApplyTransformation(self, t, pt):
"""Applies the transformation of
the given Transform to the given point."""
return t.OfPoint(pt)
```
### 🤔How to use it?
**And now, here's the gravy for your fries.**
As I mentioned:
You don't even need to understand the class I provided.
You just need to use a few methods.
💡And please **pay attention to units that you use !**
And here's an example:
Where I'll take a list of generic models ('EF_Box')
And I'm going to convert internal coordinates into Project and Survey Systems.
```python
# Get Elements
elems = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsNotElementType().ToElements()
boxes = [e for e in elems if 'EF_Box' in e.Name] # ⚠️ I use specific Type Name to filter...
# Get Coordinates
for box in boxes:
# Get Location
pt = box.Location.Point # Internal Coordinate System (defualt)
# 👉 Convert XYZ Point
pt_converter = PointConverter(pt, CoordSys.Internal)
pt_survey = pt_converter.pt_survey # XYZ - SURVEY WITH VALUES IN FEET
pt_survey_m = pt_converter.pt_survey_m # XYZ - SURVEY WITH VALUES IN METERS
pt_project = pt_converter.pt_project # XYZ - PROJECT WITH VALUES IN FEET
pt_project_m = pt_converter.pt_project_m # XYZ - PROJECT WITH VALUES IN METERS
# Extra Function To Print Correct Data Display Results
pt_converter.print_in_metric(coord_sys=CoordSys.Survey)
```
Simple right?
As you can see I've used XYZ with internal coordinates to create Survey and Project coordinates.
But I could also import some excel data of Survey coordinates, and convert it back into internal…
You get the point.
**Enjoy working with Revit API Coordinates like a Pro.**
**Feel free to mention this article to others coders!**
**They'll love you for that.**
Happy Coding.
### The Ultimate Python Course For Beginners (Learn How To Code in 2026)
https://learnrevitapi.com/blog/12hr-python-course/
Learn Python from zero in one free 12-hour course for beginners: the core concepts step by step, the foundation you need before you automate Revit.
### Revit API Course For Beginners (The Best Way To Get Started)
https://learnrevitapi.com/blog/intro-revit-api-course/
Revit API course for beginners: what the Revit API is, how to read its documentation and how to write your first scripts. The best way to get started.
### pyRevit WPF Form for Asking user for Multiple Paths
https://learnrevitapi.com/blog/pyrevit-wpf-form-for-getting-file-paths/
## EF-WPF Form
Here is the overview of the form that I will give you the code for.
It's simple, but yet very elegant to collect multiple paths. But also you can extend the functionality if you know how to work with WPF.
Happy Coding!
[EF-WPF Form overview](https://player.mediadelivery.net/embed/750622/47822ac1-930d-4e53-8d48-e0ce8e665eb6)
## Folderstructure
To create WPF forms you need to create .xaml file and then use it inside of your python script.

Let's break them down one by one.
## .XAML Script
**Xaml **- is the file format for WPF forms, which is used for designing front-end of the forms.
In this case you have to create a file `FormFolderPaths.xaml` in the same folder as your`script.py`, because I will be referencing the name of the file inside the python file.
Here is the code:
```text
```
## Script.py
And here is the python file with my template
```text
# -*- coding: utf-8 -*-
__title__ = "Code Samples: WPF Form Sample"
__doc__ = """Version = 1.0
Date = 15.07.2024
_____________________________________________________________________
Description:
Example of using WPF Form.
Keep in mind that WPF forms need a .xaml file that has the form design.
_____________________________________________________________________
How-To:
- Click the Button
_____________________________________________________________________
Last update:
- [15.07.2024] - V1.0 RELEASE
_____________________________________________________________________
Author: Erik Frits from LearnRevitAPI.com"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#====================================================================================================
from Autodesk.Revit.DB import *
from pyrevit import forms # By importing forms you also get references to WPF package! Very IMPORTANT
import wpf, os, clr # wpf can be imported only after pyrevit.forms!
# .NET Imports
clr.AddReference("System")
from System.Collections.Generic import List
from System.Windows import Window
from System.Windows.Forms import FolderBrowserDialog
import System
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#====================================================================================================
PATH_SCRIPT = os.path.dirname(__file__)
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document #type: Document
# ╔╦╗╔═╗╦╔╗╔ ╔═╗╔═╗╦═╗╔╦╗
# ║║║╠═╣║║║║ ╠╣ ║ ║╠╦╝║║║
# ╩ ╩╩ ╩╩╝╚╝ ╚ ╚═╝╩╚═╩ ╩ MAIN FORM
#====================================================================================================
class SimpleForm(Window):
def __init__(self):
# Connect to .xaml File (in same folder)
path_xaml_file = os.path.join(PATH_SCRIPT, 'FormFolderPaths.xaml')
wpf.LoadComponent(self, path_xaml_file)
# Show Form
self.ShowDialog()
# ╔╦╗╔═╗╔╦╗╦ ╦╔═╗╔╦╗╔═╗
# ║║║║╣ ║ ╠═╣║ ║ ║║╚═╗
# ╩ ╩╚═╝ ╩ ╩ ╩╚═╝═╩╝╚═╝
def browse_for_folder(self):
dialog = FolderBrowserDialog()
if dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK:
return dialog.SelectedPath
return None
# ╔═╗╦═╗╔═╗╔═╗╔═╗╦═╗╔╦╗╦╔═╗╔═╗
# ╠═╝╠╦╝║ ║╠═╝║╣ ╠╦╝ ║ ║║╣ ╚═╗
# ╩ ╩╚═╚═╝╩ ╚═╝╩╚═ ╩ ╩╚═╝╚═╝
#====================================================================================================
# ╔═╗╦ ╦╔═╗╔╗╔╔╦╗╔═╗
# ║╣ ╚╗╔╝║╣ ║║║ ║ ╚═╗
# ╚═╝ ╚╝ ╚═╝╝╚╝ ╩ ╚═╝
#====================================================================================================
def BrowseFolder1_Click(self, sender, e):
folder_path = self.browse_for_folder()
if folder_path:
self.FolderPath1.Text = folder_path
def BrowseFolder2_Click(self, sender, e):
folder_path = self.browse_for_folder()
if folder_path:
self.FolderPath2.Text = folder_path
def BrowseFolder3_Click(self, sender, e):
folder_path = self.browse_for_folder()
if folder_path:
self.FolderPath3.Text = folder_path
# ╔╗ ╦ ╦╔╦╗╔╦╗╔═╗╔╗╔╔═╗
# ╠╩╗║ ║ ║ ║ ║ ║║║║╚═╗
# ╚═╝╚═╝ ╩ ╩ ╚═╝╝╚╝╚═╝ BUTTONS
#==================================================
def UIe_button_run(self, sender, e):
"""Button action: Rename view with given """
self.Close()
# You can do something here when button is clicked too.
# ╦ ╦╔═╗╔═╗ ╔═╗╔═╗╦═╗╔╦╗
# ║ ║╚═╗║╣ ╠╣ ║ ║╠╦╝║║║
# ╚═╝╚═╝╚═╝ ╚ ╚═╝╩╚═╩ ╩
# Show form to the user
UI = SimpleForm()
# Get User Input
print('Path 1: {}'.format(UI.FolderPath1.Text))
print('Path 2: {}'.format(UI.FolderPath2.Text))
print('Path 3: {}'.format(UI.FolderPath3.Text))
```
## Results

### How to create Revit API Stubs for Autocomplete with pyRevit
https://learnrevitapi.com/blog/generate-revit-api-stubs-with-pyrevit-for-autocomplete/
## Download Revit API Stubs
- [**Download Revit API 2024 Stubs**](https://drive.google.com/uc?export=download&id=1V0Ceguve33_HzDxghA8N5GUOt0bKy52U)
- [**Download Revit API 2023 Stubs**](https://drive.google.com/uc?export=download&id=1A7Fbi2MqwbYXR1WGYDhek8XuUKOi9hFk)
- [**Download Revit API 2022 Stubs**](https://drive.google.com/uc?export=download&id=1lNUgVoC_nSPInsiYHJ_0XxX47ub9hpNs)
- [**Download Revit API 2021 Stubs**](https://drive.google.com/uc?export=download&id=1kIBE4w845qr0N021CZJ8dkLVn9tJ4c-k)
- [**Download Revit API 2020 Stubs**](https://drive.google.com/uc?export=download&id=1Q5mDfjO_-gTGZJnGh3pDphA16UR-NPIF)
## What is Revit API Stubs?
Revit API stubs are simplified representation of the Revit API. Stubs can be used to reference in the IDE(code-editor), so we can get autocomplete suggestions when we code and reference doc strings. This is an essential step for any Revit API developer both beginners and advanced.
## How to create Revit API Stubs for other Revit API versions?
It's very common to keep older Revit versions on older projects to avoid any issues. And because of that sometimes people ask me for older Revit API stubs. But instead of that I want to show you how to create these stubs yourself.
As they say, teach a man to fish and he will never go hungry.
For that I would recommend you to watch the video on the top, but I will also write it out in case you prefer written format.
## pyRevit Dev Tools
First of all we need to activate pyRevit Dev tools to access a tool that can generate stubs.
**Go to pyRevit -> Extensions -> Enable pyRevit DevTools**


Once you've enabled this extension you will see **pyRevitDevTools **tab in Revit.
## Generate Revit API Stubs
Go to **pyRevitDevTools **tab, and look for Generate API Stubs button. This will be able to generate stubs for your current Revit version. Here is how the button looks like:

Once you click on it you will have to select an empty folder where there Revit API stubs will be generated.
And after that you've created Revit API stubs, however we are not done yet. It will not work until you make a little fix.
## Fix Revit API Stubs
When pyRevit has generated the stubs it has missed a few `__init__.pyi` files.
These files are used to mark a folder structure as python package or stubs so it can read all the nested folders. We don't need to write anything in the `__init__.pyi` file
**💡Make sure you have ****`__init__.pyi`**** file in every nested folder so it works. **
## Setup Revit API Autocomplete in pyCharm / VS Code
Once you have the right Revit API stubs, you can use them in pyCharm or VS Code or any other IDE of your choice.
In case you need help, I've already created tutorials for pyCharm and VS Code and you can watch them here:
- [How to set up Revit API Autocomplete in VS Code](https://www.youtube.com/watch?v=N6colO7rPWo)
- [How to set up Revit API Autocomplete in pyCharm](https://www.youtube.com/watch?v=3RSq09SVMMY)


### How to add Python 3 packages to pyRevit? (pandas, numpy, openpyxl...)
https://learnrevitapi.com/blog/add-python3-pyrevit-packages-like-numpy-pandas/
## Intro
In this lesson you will learn how to install **pandas**, **numpy**, **openpyxl **and any other python 3 package to be used in pyRevit. The process is not complicated, but there are a few steps to follow.
Let's begin
## CPython
To use python 3 packages like **pandas **or **numpy**, we need to use **CPython **engine in pyRevit.
It's very simple to do, but there are a few things you should know about, so please check out these 2 posts about **CPython **in pyRevit Dev Docs.
[Create Your First CPython Command](https://pyrevitlabs.notion.site/Create-Your-First-CPython-Command-b8a7718c554645d1a18454c0b363e3c9)
[Anatomy of CPython Scripts](https://pyrevitlabs.notion.site/Anatomy-of-CPython-Scripts-0e4cffeb545c4aa699fbe722c837c8d0)
💡There are a few important points mentioned:
- How to run scripts in python 3 -> `#! python3`
- **CPython **scripts always read using **UTF-8** encoding. No need for `# -*- coding: utf-8 -*- `
- List of[ pyRevit packages](https://github.com/pyrevitlabs/pyRevit/tree/master/site-packages)
- How to solve **Interface **Error Message " Duplicate type name within an assembly."
- **CPython **engine is under active development and might be unstable.
- You will encounter issues with Interfaces (`TypeError : Duplicate type name within an assembly.`) You can find a solution in [**Anatomy of CPython Scripts**](https://pyrevitlabs.notion.site/Anatomy-of-CPython-Scripts-0e4cffeb545c4aa699fbe722c837c8d0)
## pyRevit python version
To install python 3 packages correctly, we should use the same version of python as used by pyRevit.
To do that use the following code:
```python
#!python3
import sys
print("Python version:", sys.version)
print("Version info:", sys.version_info)
```

👉 In my case I see [python 3.8.5](https://www.python.org/downloads/release/python-385/). So that's what I will install.
## Install packages
Now we have the right python installed, and we can get more packages with **pip **in the **cmd **console.
Open the console by writing '**cmd' **in the search.

💡Now, before you install anything, make sure that you use the correct **python **version with **pip**.
You can type '**pip -V**' and it will display what version of python is used. It's necessary in case you have more than 1 python version installed, and you need to make sure you use the right one.
You can also find all the python version on your computer by writing '**where python**'

Once you know that you have the right **pip **version, you can install any packages that you want.
Also, while you install packages, make a note of the path to where they are installed. You might need that.
🎦 [**Watch the video**](https://www.youtube.com/watch?v=-r-HSIC6wf8) if you need help with the step.
## Add Paths in pyRevit
Now the tricky part - we need to let pyRevit use these installed packages.
💡But keep in mind, that a single path might not be enough.
There are various dependencies between packages, so it's best to check available paths for your python interpreter
Write **'python -m site**' and you will see a list of available paths.

Once you have these paths you can write the following in your python script to ensure pyRevit can access these new packages

💡You can also use **PYTHONPATH **environment variable to provide these paths. This is the variable pyRevit looks at by default. (Ignore this step if you don't know about environment variables)
## Check out the tutorial for more
🎦 [**Watch this video**](https://www.youtube.com/watch?v=-r-HSIC6wf8) if you want to see me install and configure everything and explain you how to do the same.
## Remarks
⚠️Don't forget that **CPython **engine is under active development and might be unstable.
I've noticed that **pyrevit.forms **might give you an error because of that. So be prepared for the unexpected.
### How to Cut a Pipe/Duct in half with Revit API/
https://learnrevitapi.com/blog/split-pipe-or-duct-in-half-with-revitapi-breakcurve/
## How to Cut Pipe/Duct in half?
If you want to split your pipes or ducts then you need the following methods:
- [PlumbingUtils.BreakCurve](https://rvtdocs.com/2023/3c302b80-d1f8-0e17-154a-b809cad2e545)
- [MechanicalUtils.BreakCurve](https://rvtdocs.com/2023/baeec9be-b43d-d378-31b9-453432d44bfb)
These methods need 3 arguments:
- doc
- ElementId of Pipe/Duct
- Point where to spit
Also keep in mind that these methods will return an **ElementId **of a new pipe/duct segment, or None if it failed.
## Prepare a button
Let's begin by creating a pyRevit button and adding a code to select a Pipe/Duct.
```python
# -*- coding: utf-8 -*-
__title__ = "Split Pipe/Duct"
#⬇️ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
from Autodesk.Revit.DB.Mechanical import Duct, MechanicalUtils
from Autodesk.Revit.DB.Plumbing import Pipe, PlumbingUtils
#📦 VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type:Document
#🎯 MAIN
#==================================================
#✨ Limit Selection to Pipe/Ducts
class ISF_Pipe_Duct(ISelectionFilter):
def AllowElement(self, element):
if type(element) in [Pipe, Duct]:
return True
#👉 Select Pipe/Ducts
ref_pipe_ducts = uidoc.Selection.PickObjects(ObjectType.Element, ISF_Pipe_Duct())
pipe_ducts = [doc.GetElement(ref) for ref in ref_pipe_ducts]
```
This Code Snippet should return us a list of Pipes/Ducts together.
## Get Middle Point
Now we need to think of where we want to cut our Pipes/Ducts. In my case, I will grab the middle point.
To calculate the middle point we would need to get the `elem.Location.Curve` and then by getting `pt_start` and `pt_end` we can calculate the middle point.
```python
# Iterate through Pipes/Ducts
for elem in pipe_ducts:
#📏 Get Middle Point
crv = elem.Location.Curve
pt_start = crv.GetEndPoint(0)
pt_end = crv.GetEndPoint(1)
pt_middle = (pt_start + pt_end)/2
```
## Split Pipe/Duct in Half with BreakCurve
Now we can cut it in half. But keep in mind that there are separate methods for Pipes and Cuts. So we have to make a check and then use [PlumbingUtils ](https://rvtdocs.com/2023/958a3fa2-eb4b-2814-f674-42cac98f4910)or [MechanicalUtils ](https://rvtdocs.com/2023/bf566f7b-e3fc-f76b-4605-a47b900b012a)accordingly.
Here is a snippet and don't forget the [Transaction](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd).
```python
# Start Transaction for changes.
t = Transaction(doc,'Split Pipe/Duct')
t.Start() #🔓
#️✂️️ Cut Pipe/Duct
if type(elem) == Pipe:
new_elem_id = PlumbingUtils.BreakCurve(doc, elem.Id, pt_middle)
elif type(elem) == Duct:
new_elem_id = MechanicalUtils.BreakCurve(doc, elem.Id, pt_middle)
if new_elem_id:
new_elem = doc.GetElement(new_elem_id)
print(new_elem)
t.Commit() #🔒
```
## ✨Final Code Snippet
Here is the complete code to avoid any confusion..
```python
# -*- coding: utf-8 -*-
__title__ = "Split Pipe/Duct"
#⬇️ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
from Autodesk.Revit.DB.Mechanical import Duct, MechanicalUtils
from Autodesk.Revit.DB.Plumbing import Pipe, PlumbingUtils
#📦 VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type:Document
#🎯 MAIN
#==================================================
#✨ Limit Selection to Pipe/Ducts
class ISF_Pipe_Duct(ISelectionFilter):
def AllowElement(self, element):
if type(element) in [Pipe, Duct]:
return True
#👉 Select Pipe/Ducts
ref_pipe_ducts = uidoc.Selection.PickObjects(ObjectType.Element, ISF_Pipe_Duct())
pipe_ducts = [doc.GetElement(ref) for ref in ref_pipe_ducts]
# Iterate through Pipes/Ducts
for elem in pipe_ducts:
try:
#📏 Get Middle Point
crv = elem.Location.Curve
pt_start = crv.GetEndPoint(0)
pt_end = crv.GetEndPoint(1)
pt_middle = (pt_start + pt_end)/2
# Start Transaction for changes.
t = Transaction(doc,'Split Pipe/Duct')
t.Start() #🔓
#️✂️️ Cut Pipe/Duct
if type(elem) == Pipe:
new_elem_id = PlumbingUtils.BreakCurve(doc, elem.Id, pt_middle)
elif type(elem) == Duct:
new_elem_id = MechanicalUtils.BreakCurve(doc, elem.Id, pt_middle)
if new_elem_id:
new_elem = doc.GetElement(new_elem_id)
print(new_elem)
t.Commit() #🔒
except Exception as e:
print('⚠️Error with ElementId({}): {}'.format(elem.Id,e))
```
### How To Purge View Templates with pyRevit
https://learnrevitapi.com/blog/purge-view-templates-with-pyrevit/
## Purge View Templates with EF-Tools
Before we dive into the code, I want you to know that you can use this tool in **EF-Tools**. You can even inspect the code by holding **ALT** and clicking on the button to open the location of the source code.

**👀But Now let's look at the code.**
## Brainstorming
This is a very simple tool.
We need to find all unused view templates and then ask user which ones to delete. I don't think that there is a method to get all unused in Revit API, so we will find all used view templates first, by iterating over all views, and then find the difference with all view templates.
Here are the steps we will go through:
1. Get All Views and ViewTemplates
2. Find Used ViewTemplates (iterate through views)
3. Find all Unused ViewTemplates (set_A - set_B)
4. Ask User Which ones to Delete (pyrevit.forms)
5. Purge View Templates
## 1️⃣ Get View and ViewTemplates
First of all, you will need to get your Views and View Templates.
It's also a good idea to sort them accordingly.
```python
#👉 Get Views and ViewTemplates
all_view_and_vt = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
all_views = [v for v in all_view_and_vt if not v.IsTemplate]
all_vt_ids = [v.Id for v in all_view_and_vt if v.IsTemplate]
```
## 2️⃣ Get Used ViewTemplates
Now, we can iterate through all views and get **ViewTemplateId**.
Then, it's important to check that it's not `ElementId(-1)`, because it refers to **None **in Revit API.
```python
#🔬 Get Used ViewTemplates
used_vt_ids = []
for view in all_views:
vt_id = view.ViewTemplateId
if vt_id != ElementId(-1):
if vt_id not in used_vt_ids:
used_vt_ids.append(vt_id)
```
## 3️⃣ Get Unused ViewTemplates
We have **all view templates**, and a list of **used view templates.**
Now we can turn them into **sets **and subtract one from another to get the difference, which will be our **unused View Templates**.
💡 It's also a good idea to ensure we have unused templates.
```python
# Get All Unused ViewTemplates
unused_vt_ids = set(all_vt_ids) - set(used_vt_ids)
unused_vts = [doc.GetElement(vt_id) for vt_id in unused_vt_ids]
# ✅ Ensure Unused ViewTemplates
if not unused_vt_ids:
forms.alert('There are no unused ViewTemplates in the project. Please try again.',title=__title__, exitscript=True)
```
## 4️⃣ Select ViewTemplates to Purge
Now it's time to give some control to our users.
We shouldn't delete all unused view templates; instead, we should ask them to select which ones to delete.
We can use **pyrevit.forms.SelectFromList** to quickly create a list of our unused View Templates.
💡Make sure the user has selected something here.
```text
#🔎 Select ViewTemplates to Purge
vt_to_del = forms.SelectFromList.show(unused_vts,
multiselect=True,
name_attr='Name',
button_name='Select Unused ViewTemplates to Purge')
# ✅ Ensure ViewTemplates were selected
if not vt_to_del:
forms.alert('There were no ViewTemplates Selected. Please try again.',title=__title__, exitscript=True)
```
## 5️⃣ Purge ViewTemplates
Finally, we can get rid of these unused view templates.
Overall, we just need to use **doc.Delete** method, but it's also good to add **try/except** in case these templates are used by other users or something else.
```text
#🔥 Purge ViewTemplates
t = Transaction(doc, 'Purge ViewTemplates')
t.Start() #🔓
deleted = 0
for vt in vt_to_del:
try:
vt_name = vt.Name
doc.Delete(vt.Id)
output.print_md('🔥Purged ViewTemplate: **{}**'.format(vt_name))
deleted += 1
except Exception as e:
print("✖️ Couldn't delete ViewTempalte: {} due to {}".format(vt_name, e))
t.Commit() #🔒
```
## ✨Full Code
👇Here is the final code with all the steps together and also a few additional print statements.
```text
y
# -*- coding: utf-8 -*-
__title__ = "Purge Unused View Templates"
__doc__ = """Version = 1.0
Date = 24.06.2024
_____________________________________________________________________
Description:
Purge Unused View Templates from your Revit Project.
_____________________________________________________________________
How-To:
- Click the Button
- Select unused View Templates to purge
_____________________________________________________________________
Last update:
- [28.06.2024] - V1.0 RELEASE
_____________________________________________________________________
Author: Erik Frits from LearnRevitAPI.com"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
# ==================================================
from Autodesk.Revit.DB import *
# pyRevit
from pyrevit import forms, script
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
# ==================================================
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
output = script.get_output()
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
# ==================================================
#👉 Get Views and ViewTemplates
all_view_and_vt = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
all_views = [v for v in all_view_and_vt if not v.IsTemplate]
all_vt_ids = [v.Id for v in all_view_and_vt if v.IsTemplate]
#🔬 Get Used ViewTemplates
used_vt_ids = []
for view in all_views:
vt_id = view.ViewTemplateId
if vt_id != ElementId(-1):
if vt_id not in used_vt_ids:
used_vt_ids.append(vt_id)
# Get All Unused ViewTemplates
unused_vt_ids = set(all_vt_ids) - set(used_vt_ids)
unused_vts = [doc.GetElement(vt_id) for vt_id in unused_vt_ids]
# ✅ Ensure Unused ViewTemplates
if not unused_vt_ids:
forms.alert('There are no unused ViewTemplates in the project. Please try again.',title=__title__, exitscript=True)
#🔎 Select ViewTemplates to Purge
vt_to_del = forms.SelectFromList.show(unused_vts,
multiselect=True,
name_attr='Name',
button_name='Select Unused ViewTemplates to Purge')
# ✅ Ensure ViewTemplates were selected
if not vt_to_del:
forms.alert('There were no ViewTemplates Selected. Please try again.',title=__title__, exitscript=True)
#👀 Print ViewTemplates Report
output.print_md('### There were {}/{} Unused ViewTemplates in the project.'.format(len(unused_vt_ids), len(all_vt_ids)))
output.print_md('---')
#🔥 Purge ViewTemplates
t = Transaction(doc, 'Purge ViewTemplates')
t.Start() #🔓
deleted = 0
for vt in vt_to_del:
try:
vt_name = vt.Name
doc.Delete(vt.Id)
output.print_md('🔥Purged ViewTemplate: **{}**'.format(vt_name))
deleted += 1
except Exception as e:
print("✖️ Couldn't delete ViewTempalte: {} due to {}".format(vt_name, e))
t.Commit() #🔒
#👀 Create Final print statement
output.print_md('---')
output.print_md('*Script Execution has finished. {} ViewTemplates were purged.*'.format(deleted))
#⌨️ Happy Coding!
```
### How To Purge View Filters with pyRevit
https://learnrevitapi.com/blog/purge-view-filters-with-pyrevit/
## Purge View Filterswith EF-Tools
Before we dive into the code, I want you to know that you can use this tool in **EF-Tools**. You can even inspect the code by holding **ALT** and clicking on the button to open the location of the source code.

**👀But Now let's look at the code.**
## Brainstorming
For this tool we need to get all unused View Filters and ask the user which ones to purge.
Here are the steps we will go through:
1. Get All Views and Filters
2. Find Used View Filters (iterate through views)
3. Find all Unused View Filters(set_A - set_B)
4. Ask User Which ones to Delete (pyrevit.forms)
5. Purge View Filters
## Get Views and Filters
Firstly, get all you View Filters and Views+ViewTemplates.
Also keep in mind that Parameter filters and Selection filters have different classes. You can use [**FilterElement **](https://rvtdocs.com/2023/909615cd-8abd-044a-cff2-f21fd95b8ee7)class to get them both together. But for my example, I will only get [**ParameterFilterElements**](https://rvtdocs.com/2023/b231dc85-516a-5e75-c634-c6cd81b43fc5)**.**
```python
# 1️⃣ Get Views and Filters
# all_filter_ids = FilteredElementCollector(doc).OfClass(FilterElement).ToElementIds() #Parameter + Selection
# all_sel_filter_ids = FilteredElementCollector(doc).OfClass(SelectionFilterElement).ToElementIds()
all_param_filter_ids = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElementIds()
all_views_and_vt = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
```
## Find Used View FIlters
Now, let's iterate through all views and view templates and see what kind of filters they have with [**GetFilters**](https://rvtdocs.com/2023/bfd1a738-9b18-d4dd-f487-eac4566e8484)**. **Create a set or a list of unique ViewFilter Ids.
Here is the code:
```python
#2️⃣ Find Used ViewFilters
used_filter_ids = []
for view in all_views_and_vt:
view_filter_ids = view.GetFilters()
for view_filter_id in view_filter_ids:
if view_filter_id not in used_filter_ids:
used_filter_ids.append(view_filter_id)
```
## Find Unused View Filters
Now we can get unused view filters by substracting a set of **used_filters **from a set of **all_filters.**
💡Also, it's a good idea to ensure you have unused filters in the project.
```python
#3️⃣ Get Unused ViewFilters
unused_filter_ids = set(all_param_filter_ids) - set(used_filter_ids)
unused_filters = [doc.GetElement(f_id) for f_id in unused_filter_ids]
#✅ Check if Unused Filters in Project
if not unused_filters:
forms.alert('There are no Unused View Filters in the project. Please try again',title=__title__, exitscript=True)
```
## Select View Filters To Purge
Now we need to create a UI form for user to select View Filters. Using [pyrevit.forms.SelectFromList](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056?pvs=25#a0077880c0054f80817decc20c5cc816) is the simplest and quickest way to do that. Also ensure that user has selected something to avoid errors later in the code.
Here is the code:
```python
#👉 Select View Filters to Delete
filters_to_del = forms.SelectFromList.show(unused_filters,
multiselect=True,
name_attr='Name',
button_name='Select Unused View Filters To Delete.')
#✅ Check Selection
if not filters_to_del:
forms.alert('No Unused View Filters were selected. Please try again',title=__title__, exitscript=True)
```
## Purge View Filters
Lastly, let's delete all desired View Filters by using doc.[Delete](https://rvtdocs.com/2023/a0461dd1-71d9-4581-1604-2ef8c211dd60).
💡Also it's a good idea to use **try/except **statements here, in case someone has the rights on view filters.
```python
with Transaction(doc, 'Purge Unused ViewFilters') as t:
t.Start() #🔓
for fil in filters_to_del:
try:
f_name = fil.Name
doc.Delete(fil.Id)
print('✔️ Deleted ViewFilter: {}'.format(f_name))
except Exception as e:
print("✖️ Couldn't Delete View Filter: {}".format(f_name))
print('----- Error Message: {}'.format(e))
t.Commit() #🔒
```
## ✨Full Code
Here is the final code together to avoid any confusion.
```python
# -*- coding: utf-8 -*-
__title__ = "5 - Purge Unused View Filters"
__doc__ = """Version = 1.0
Date = 24.06.2024
_____________________________________________________________________
Description:
Purge Unused View Filters from your Revit Project.
_____________________________________________________________________
How-To:
- Click the Button
- Select unused View Filters to purge
_____________________________________________________________________
Last update:
- [24.06.2024] - V1.0 RELEASE
_____________________________________________________________________
Author: Erik Frits from LearnRevitAPI.com"""
# ⬇️IMPORTS
# ==================================================
from Autodesk.Revit.DB import *
# pyRevit
from pyrevit import forms
# 📦VARIABLES
# ==================================================
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
#🎯 MAIN
# ==================================================
# 1️⃣ Get Views and Filters
# all_filter_ids = FilteredElementCollector(doc).OfClass(FilterElement).ToElementIds() #Parameter + Selection
# all_sel_filter_ids = FilteredElementCollector(doc).OfClass(SelectionFilterElement).ToElementIds()
all_param_filter_ids = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElementIds()
all_views_and_vt = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
#2️⃣ Find Used ViewFilters
used_filter_ids = []
for view in all_views_and_vt:
view_filter_ids = view.GetFilters()
for view_filter_id in view_filter_ids:
if view_filter_id not in used_filter_ids:
used_filter_ids.append(view_filter_id)
#3️⃣ Get Unused ViewFilters
unused_filter_ids = set(all_param_filter_ids) - set(used_filter_ids)
unused_filters = [doc.GetElement(f_id) for f_id in unused_filter_ids]
#✅ Check if Unused Filters in Project
if not unused_filters:
forms.alert('There are no Unused View Filters in the project. Please try again',title=__title__, exitscript=True)
#👉 Select View Filters to Delete
filters_to_del = forms.SelectFromList.show(unused_filters,
multiselect=True,
name_attr='Name',
button_name='Select Unused View Filters To Delete.')
#✅ Check Selection
if not filters_to_del:
forms.alert('No Unused View Filters were selected. Please try again',title=__title__, exitscript=True)
with Transaction(doc, 'Purge Unused ViewFilters') as t:
t.Start() #🔓
for fil in filters_to_del:
try:
f_name = fil.Name
doc.Delete(fil.Id)
print('✔️ Deleted ViewFilter: {}'.format(f_name))
except Exception as e:
print("✖️ Couldn't Delete View Filter: {}".format(f_name))
print('----- Error Message: {}'.format(e))
t.Commit() #🔒
```
### Create Interactive Revit Reports with pyRevit Linkify
https://learnrevitapi.com/blog/create-interactive-revit-reports-with-pyrevit-linkify/
## pyRevit Linkify
pyRevit Linkify is a great feature that can create a linkable buttons to your elements and it can do 3 things:
- Select Elements
- Open Views
- Find Elements in the ActiveView (Zoom on it)
And it's super easy to use! Let's have a look at the documentation first to understand how to use it.
## pyRevit Docs
There are 2 places you can check:
[1. pyRevit Dev Docs - Effective Outputs](https://pyrevitlabs.notion.site/Effective-Output-43baf34d2ca247ada8e040bcb86613a2?pvs=25#483fafe483044956addee6a129a7032d)

[2. pyRevit ReadTheDocs - Linkify](https://pyrevit1.readthedocs.io/en/latest/output/init.html#pyrevit.output.PyRevitOutputWindow.linkify)
## Import Linkify

Before we dive into the examples, I want you to understand that you need to import **script **from pyRevit and then get the **output** so we can use **linkify **function. Here is the example:
```python
#⬇️ Import and Variable
from pyrevit import script
output = script.get_output()
#👉 Get An Element
el = ... # Get Your Element
#🔗 Create Linkify
el_linkify = output.linkify(el.Id)
#👀 Print Linkify Button
print(el_linkify)
```
Now let's have a look at a few examples.
## Example 1 - Linkify Single Elements
Let's begin by looking at the examples.
Here is an example to create Linkify for a single element. We will grab all walls in a view and then create linkify button for each wall. Also notice that I've provided `wall.Name` as the second argument, and that will be the title of our linkify button.
Here is the code:
```python
# 1️⃣ Linkify Single - Walls
all_walls = FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(Wall).ToElements()
for wall in all_walls:
linkify_wall = output.linkify(wall.Id, wall.Name)
print(linkify_wall)
```

## Example 2 - Linkify Multiple Elements
We can also provide a list of Element Ids if we want to create a linkable button for many elements at once.
```python
#2️⃣ Linkify Multiple - Walls
all_walls = FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(Wall).ToElements()
wall_ids = [wall.Id for wall in all_walls]
linkify_walls = output.linkify(wall_ids, 'Walls {}'.format(len(wall_ids)))
print(linkify_walls)
```

## Example 3 - Linkify Limitation
But keep in mind that Linkify has a limit on how many elements can be included in a single button. Usually you will notice it somewhere around 100-150 elements.
Let's put hundreds of walls into a single linkify button to see what kind of an issue we might encounter.
```python
#3️⃣ Limit ~100-150 elements
all_walls = FilteredElementCollector(doc).OfClass(Wall).ToElements()
wall_ids = [wall.Id for wall in all_walls]
linkify_walls = output.linkify(wall_ids, 'Walls {}'.format(len(wall_ids)))
print('Here are all the walls in the project: {}'.format(linkify_walls))
```
This will still create the button without any issues, however, when you try to use it you will see the following error:

## Example 4 - Linkify Views
You will also notice that you can linkify views. And by clicking on suck a linkify button it will open that specific view.
It's great if you want to quickly create a list of views and easily jump between them. This is especially useful if you work on a large project and you have hundreds of views, and sometimes it gets tedious to open the right ones for the day.
So here is a simple sample:
```python
4️⃣ Linkify - Views
all_views_and_vt = FilteredElementCollector(doc).OfClass(ViewPlan).ToElements()
all_views = [view for view in all_views_and_vt if not view.IsTemplate]
for view in all_views:
linkify_view = output.linkify(view.Id, 'View: {}'.format(view.Name))
print(linkify_view)
```
## Example 5 - Analyze Warnings
Alright, now let's put this to use.
You've seen various example of using Linkify, but probably it wasn't that impressive. Now I want to show you a simple tool that can be extremely useful when you work with Revit Warnings.
This example will:
1. Get all warnings in the project,
2. Find elements related to these warnings
3. Find out who was the last person to modify them.
4. Print out the table that will have
- Warning Description
- Username of LastChangedBy
- Linkable Button to select and find these elements
```python
#5️⃣ Bonus Example: Analyze Warnings
def get_sorted_warnings():
"""Function to get All Warnings in the project and sort them by their description
:return: dict of warnings {warn_description : list_of_warnings}"""
from collections import defaultdict
dict_all_warnings = defaultdict(list)
for w in doc.GetWarnings():
description = w.GetDescriptionText()
dict_all_warnings[description].append(w)
return dict_all_warnings
# Get + Sort Warnings
dict_all_warnings = get_sorted_warnings()
for descr, list_warnings in dict_all_warnings.items():
table_data = []
for warn in list_warnings:
# print(warn)
element_ids = list(warn.GetFailingElements()) + list(warn.GetAdditionalElements())
last_modified_by = {WorksharingUtils.GetWorksharingTooltipInfo(doc, el_id).LastChangedBy for el_id in element_ids}
last_modified_by = ', '.join(last_modified_by)
# Linkify
title = 'Select'
warn_linkify = output.linkify(element_ids, title)
# Create a Row of Data
row = [descr, last_modified_by, str(len(element_ids)), warn_linkify]
table_data.append(row)
output.print_table(table_data=table_data,
title =descr,
columns=['Warning Description', 'Last Modified By:', 'Elements', 'Linkify'],
formats=['**{}**', '*{}*', '', ''])
```
Overall it's not that complicated, and it gives you great results like this:

### Revit API Resources You Didn't Know About!
https://learnrevitapi.com/blog/revit-api-resources-for-beginners/
## Revit API is so niche
When we start learning Revit API we realize how little information is out there, or at least that was the issue some years ago. Nowadays, there are actually a lot of resources online that we can leverage to code with Revit API faster and better.
I found it quite surprising, but there are actually so many resources available, that I got lost in them. So I decided to list here all the best resources you didn't know about, so you can start using them and make your life easier.
Before we dive into resources, keep in mind that I couldn't rate them as there are too many of them, so I've just categorized them so it's easier to navigate around and I will also focus on how to find similar resources instead of listing too many of them here...
Let's begin with the basics.
## Documentation
I know it sounds boring to explore documentation… But also keep in mind that docs are the most used resources in programming, especially in Revit API. We constantly need to reference different classes, or see a code snippet that we need. Therefore it's important to start here.
- [Revit API Docs](https://rvtdocs.com/) - This is the most used resource in my opinion. You can find all the classes in Revit API, and most importantly, how to use it.
- [pyRevit Dev Docs](https://pyrevitlabs.notion.site/Developer-Docs-2c88f3ecccde422d9504e20b6b9e04f8) - If you are a python coder, then there is a high chance that you use pyRevit. It's super beginner friendly and very easier to get started with. And it has an amazing documentation where you will be able to find a lot of useful resources and code snippets. I highly recommend you to look around it.
- [Revit Developer's Guide](https://help.autodesk.com/view/RVT/2023/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html) - This one is lesser known resource. At least I missed it for the first couple of years of using Revit API. This is the official guide from Autodesk, and it has certain topics very well explained and documented. Personally, I didn't like the basics in there, but once you start reading about more advanced stuff in Revit API like filtering, IUpdater, Events… This is an amazing resource. I started to often reference it before my tutorials, to see if I missed anything or not.
- [Dynamo Python Primer](https://dynamopythonprimer.gitbook.io/dynamo-python-primer/4-revit-specific-topics/introduction-to-revits-api) - Lastly, Dynamo Primer is a very well known resource. It has a section dedicated to Revit API with python, and there are a few short lessons that can help you get started with Revit API.
## E-Books
[RevitAPI E-Book: The Beginner’s Guide](https://learnrevitapi.com/) - If you are a Revit API beginner, I highly recommend you to grab my Beginner's Guide to Revit API. It's a 50 page E-Book where I tried to fit in as much information as possible. It has plenty of explanations, code snippets, links to other video resources and so on. And most importantly it's FREE!

[Revit API E-Book: FilteredElementCollector Guide](https://learnrevitapi.com/) - Another Guide that I've written some time ago, where I did my best to explain everything about [FilteredElementCollector ](https://rvtdocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3)and provided a lot of code snippets. It's great when you feel lazy and want to find a snippet for your collector to get the right elements.
As you know, sometimes getting the right elements is half the solution.

## pyRevit Extensions
Let's talk a bit more about pyRevit. pyRevit is Open-Source, which is mind blowing!
It means that we can access every single line of code written for this amazing plugin. And not just the plugin, but for every single tool that is run by pyRevit, including additional extensions like EF-Tools, pyRevitMEP, pyRevitPlus and many others… So you should take full advantage of that.
There are 2 ways to get the source code:
1️⃣ ALT + CLICK on a button in Revit, then it will open the source folder where you can find the .py file.
You can install all additional extensions from pyrevit's Extension Menu to test and explore them.

2️⃣ Get source code on the GitHub. All these extensions are hosted on GitHub, so it's very easy to see the code online.
Here are the most popular pyRevit Extensions:
- [pyRevitTools](https://github.com/pyrevitlabs/pyRevit/tree/master/extensions/pyRevitTools.extension)
- [EF-Tools](https://github.com/ErikFrits/EF-Tools)
- [EF-Tutor](https://github.com/ErikFrits/EF-Tutor)
- [pyApex](https://github.com/apex-project/pyApex)
- [pyRevitMEP](https://github.com/CyrilWaechter/pyRevitMEP)
- [pyRevitPlus](https://github.com/gtalarico/pyrevitplus)
- [CustomTools](https://bitbucket.org/davidvadkerti/customtools/src)
- [pyStructure](https://github.com/sampy23/pyStruct.extension)
- [MEPDesign](https://github.com/andrerdsilva/MEPDesign)
- [pyTiBa](https://github.com/tillbaum/pytiba)
- [pyChilizer](https://github.com/dnenov/pyChilizer)
- [pySSG](https://github.com/kbruxvoort/SSG.extension)
- [pyArchitect](https://github.com/romangolev/pyArchitect)
- [guRoo](https://github.com/aussieBIMguru/guRoo)
And these are not all of them!
I highly encourage you to open GitHub and search for pyRevit in there:
[GitHub/Search/pyRevit](https://github.com/search?q=pyrevit&type=repositories)
This will give you more than 200 search results. So you will be able to find so many more extensions where you might find the code that you might reuse in your own work!
## 💡GitHub Pro Tip:
Did you know that you can change **github.com**…. to **github.dev**…. and then it will open GitHub repository in the online VS Code IDE, which is a far better way to explore code.
Here is an [example](https://github.dev/erikfrits/ef-tools) how GitHub can look:

## GitHub Repositories
Also, since we are already on GitHub, let's also [**GitHub/Search/Revit API**](https://github.com/search?q=Revit+API&type=repositories)[ ](https://github.com/search?q=Revit+API&type=repositories)and see what we get. There will be even more repositories with different code samples.
I will list here a few:
- [Amoursol/dynamoPython Samples](https://github.com/Amoursol/dynamoPython/tree/master/revitAPI)
- [GerhardPaw/RevitPythonDocs](https://github.com/GerhardPaw/RevitPythonDocs/tree/main/Dynamo/IronPython2023)
- [DarenThomas/rps-sample-scripts](https://github.com/daren-thomas/rps-sample-scripts)
## Revit API SDK Samples (C#)
Also if you want to look for Revit API samples, you should definitely check Revit API SDK samples. You can [download and install SDK from Autodesk Platform Services](https://aps.autodesk.com/developer/overview/revit).
Once you install it you will see these files:

Including a folder with Revit API Samples. Also you can find it on the [GitHub for Revit 2021 SDK.](https://github.com/jeremytammik/RevitSdkSamples/tree/master/SDK/Samples) These are C# Examples, but still you can find something useful there.
And nowadays, translating C# to Python is not a big deal with all these AI LLM models like ChatGPT, which can easily translate C# to Python with minor errors.
## Learn Revit API - Python Snippets
But if you want to have a look at the collection of python scripts for Revit API, check our my [python snippets collection here](https://learnrevitapi.com/resources/code-samples/). This is a place where I usually paste my code snippets, when I don't forget about it. There are plenty of very useful snippets, check them out.

## Search Code Samples
We can also search for more specific code samples. If we are lucky enough you might be able to find a blog post, youtube video or even ask AI ChatBot and get good results.
But sometimes it's much harder to find what you look for.
For these moments I want to suggest you 2 interesting websites:
- [https://python.hotexamples.com/](https://python.hotexamples.com/)
- [https://csharp.hotexamples.com/](https://csharp.hotexamples.com/)
These are search engines for the code. So you can write a Revit API class name and it will return you matches found across GitHub. Most importantly you can see it in the context. This way you can find how others already used the class that you are looking for.
Also while you at it, check the repositories where the examples come from. Sometimes you might discover a new repository full of useful code snippets that you could use. Keep an eye on it😉
## AI Tools
I've already mentioned AI Tools, but I think they are worth mentioning once more. Our lives have certainly changed since LLM(Large-Language-Models) became a mainstream thing, so we should definitely adapt using them more.
I often experiment with Chat GPT and see how far can it go. But same as you've already experienced it's limited and often gets stuck on bigger problems.
It might be successful to delete all doors in the project (for whatever reason), but once you start adding more steps to your logic, it start to break or hallucinate. Usually it happens on the topics which are not so well documented online, and it can't find the answer anywhere so it just makes up hoping it will work… Just like I did in the University.
Obviously you can use:
- [**ChatGPT**](https://chatgpt.com/?oai-dm=1)
- [**Google Gemini**](https://gemini.google.com/app)
- [**Meta LLama**](https://llama.meta.com/)
- [**X AI - GROK**](https://x.ai/)
It's a bit hard to choose, because often times each of these models can give you better answer than another. And also they improve at different intervals. But there is a place where you can test all common LLMs.
## ChatBot Arena
There is an amazing website - [ChatBot Arena(https://chat.lmsys.org/)](https://chat.lmsys.org/)

It's a place where you can test multiple models for free and compare their results. You can either choose random models and see their names after you rate which one is better. Or you can also go to side-by-side arena, where you can specifically select 2 models you want to compare. You can even grab the latest Open AI GPT4-o model and but it against latest Gemini or Lama model.
And the best part? You don't even need to register, you can use all these models in 1 place just by going to the website.
## Coding Pair / AI Code Assistants
Also to improve our coding we can use AI Coding Pair (AI Assistant). These are AI models integrated into an IDE. It means that we can ask for its help inside of our code, or even make it write it for us.

There are many options, but from what I've researched, here are the most popular ones:
- [**GitHub CoPilot**](https://github.com/features/copilot)
- [**Codeium**](https://codeium.com/pricing)
- [**Cursor IDE**](https://cursor.sh/pricing)
- [**TabNine**](https://www.tabnine.com/pricing/)
- [**Cody**](https://sourcegraph.com/cody)
- [**JetBrains AI Assistant**](https://www.jetbrains.com/ai/)
I can't recommend one over the other for Revit API yet, as I haven't tested them all yet. But it's something that I have on my mind and I will share my findings when it happens!
## Forums
If nothing above has helped you, then probably you need some human help. Forums might sound obsolete, but there are still very active forums on such niche topics. Here are the best ones for Revit API:
- [**pyRevit forum**](https://discourse.pyrevitlabs.io/)** **
The most active Revit API community in my opinion. You can always ask you question and somebody will try to help you out or share the solution if they have it. Highly recommend you to join it.
- [**Autodesk Revit API Forum**](https://forums.autodesk.com/t5/revit-api-forum/bd-p/160)** **
Official Revit API forum from Autodesk. Also a great place to go when you are stuck,.
- [**DynamoBIM Forum**](https://forum.dynamobim.com/)** **
Alternatively, if you use Revit API inside of Dynamo, or need help with the nodes - there are many people who are willing to help you in this forum.
## Blogs
Also, I should mention some blogs. When we have an issue in Revit API - we start googling and then we end up on some random blogs. I still keep doing that and find new blogs, but there are a few that keep popping up in my search:
- [**thebuildingcoder Blog**](https://thebuildingcoder.typepad.com/)** **
The OG blog by Jeremy Tammik. You've definitely been there.
- [**Danimosite Blog**](https://danimosite.wordpress.com/2021/09/07/transforms-transformed/)
This is not a very big blog, but I found so much value in it, when I was exploring Coordinate systems in Revit API. So I want to give it a shout-out for that!
- [**Learn Revit API Blog**](https://learnrevitapi.com/blog/)** **
Also you can check my own Revit API Blog. I had some users reach out and thank me that I saved them days of work thanks to certain articles. Hopefully you will find it useful too.
- [**BoostYourBIM Blog**](https://boostyourbim.wordpress.com)** - **Lots of articles about Revit API in C#. Written by Harry Mattison.
## Other Learning Resources
Lastly, I want to mention video resources for Revit API. These are more useful and educational, however there are less of them than written posts. But you should still check out and see what you can find.
- [**YouTube: Revit API**](https://www.youtube.com/results?search_query=Revit+API)Search for Revit API in YouTube and find a lot of different videos from multiple channels. Sometimes you can try searching for your specific problem and if you are lucky enough, it can save you days!
- [**Autodesk University: Revit API**](https://www.autodesk.com/autodesk-university/search?query=Revit+API&fields.recordtype=class)Also, make sure you check previous recordings on Autodesk university. I remember when I started I've found a bunch of presentations there that helped me get started. Since then I haven't looked at new ones, but I am sure it has even more cool recordings now!
## Take a Shortcut
Lastly, you can take a shortcut in Learning Revit API.
[**Join Learn Revit API Course.**](https://learnrevitapi.com/)

This course will take you through basics and beyond. Not only you will learn all the theory that you need, but also you will see how to apply it to create a lot of tools together.
This will save you weeks if not months of Learning Revit API and you will have a huge collection of code snippets that you will keep reusing after the course.
This course already has 50+ lessons (~12 hours), and I keep uploading more content, so it will get even bigger.

If you doubt if you should join the Learn Revit API Course -[ ](https://learnrevitapi.com/)[**Check Testimonials section**](https://learnrevitapi.com/)**.**
**Don't just take my word for it 😉**
### How to Create IUpdater in Revit with pyRevit (Create Custom Features)
https://learnrevitapi.com/blog/how-to-create-iupdater-in-revit-pyrevit-doc-updater/
## IUpdater (Dynamic Model Update)
Dynamic model update offers the ability for a Revit API application to modify the Revit model as a reaction to changes happening in the model when those changes are about to be committed at the end of a transaction. Revit API applications can create updaters by implementing the IUpdater interface and registering it with the UpdaterRegistry class. Registering includes specifying what changes in the model should trigger the updater.
## Resources
[**Revit API Dev Guide - IUpdater**](https://help.autodesk.com/view/RVT/2023/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Dynamic_Model_Update_html)
## pyRevit doc-updater
…
## Create pyRevit Hook
##
## Hook Base
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from datetime import datetime
from Autodesk.Revit.DB import (BuiltInCategory,
BuiltInParameter,
UnitUtils,
UnitTypeId,
ElementId,
WorksharingUtils,
FamilyInstance)
#📦 Variables
sender = __eventsender__
args = __eventargs__
doc = args.GetDocument()
#👉 Get ElementIds for Modified/Deleted/New
modified_el_ids = args.GetModifiedElementIds()
deleted_el_ids = args.GetDeletedElementIds()
new_el_ids = args.GetAddedElementIds()
modified_el = [doc.GetElement(e_id) for e_id in modified_el_ids]
```
## Feature #1: Track Coordinates
## Feature #2: Track LastEdited Timestamp + Name
## Feature #3: Track Mirrored Windows and Doors
## Error: Third-Party IUpdater not Registered
…
## Solution: How to get rid of the the Error
### Find Intersecting Rooms and Areas
https://learnrevitapi.com/blog/find-intersecting-rooms-and-areas-in-autodesk-revit/
## Intro
I was asked how to find related [**Rooms **](https://rvtdocs.com/2023/75c9d2c7-a402-ea8b-9e7c-f8bc3510bbd5)and [**Areas **](https://rvtdocs.com/2023/44ffe200-fb00-b64d-a2fb-6db2299eaef8)in Revit project to exchange some parameters?
Check this example to better understand it.

In this example I find intersecting rooms and areas and I write `Area.Name` to `Room.Name`. Obviously, you would want to write it to another parameter, but it's great as an example.
It's not possible to do in Revit by default, but if you happen to know some python and Revit API, then you can do that.
## Brainstorming
Unfortunately, [**Areas **](https://rvtdocs.com/2023/44ffe200-fb00-b64d-a2fb-6db2299eaef8)don't have any methods to check if point is inside of them like [room.IsPointInRoom](https://rvtdocs.com/2023/96e29ddf-d6dc-0c40-b036-035c5001b996)… But we can find a workaround!
👇 Here are the steps that I will do, to make it happen :
- Get All Rooms
- Get All Areas
- Sort Areas by Type
- Iterate through Areas
- Get Area Boundary
- Build a Solid Geometry from Boundary (Extrusion)
- Iterate through Rooms
- Create a fake little Line
- Check Intersection between Geometry and Line
- Write Parameters to Room if **True**
Overall it's quite a simple script. But if you are new to working with **Geometry **and **Intersection**, then there is a tricky part!
But I got you 😉
## Get Rooms and Sorted Areas
Firstly, let's get our rooms and areas. However, keep in mind that we can have a lot of different Areas with different AreaSchemes placed in the same place! And that can be an issue if we don't choose a specific one. So therefore, we need to filter only 1 type of areas to check room intersection.
Here is how to do it:
```python
from collections import defaultdict
#👉 Get Rooms & Areas
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
all_areas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToElements()
#🔎 Sort Areas by AreaScheme
dict_areas = defaultdict(list) # List will be default value for new keys!
for area in all_areas:
dict_areas[area.AreaScheme.Name].append(area)
```
💡 Lastly, you need to select areas with which **AreaScheme **to use.
Since I use pyRevit I will use [SelectFromList ](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056?pvs=25#a0077880c0054f80817decc20c5cc816)form to ask user to select one of **AreaSchemes**.
```python
from pyrevit import forms
#👉 Select AreaScheme
sel_area_scheme = forms.SelectFromList.show(dict_areas.keys(), button_name='Select AreaScheme')
if not sel_area_scheme:
forms.alert('No AreaScheme was selected. Please Try Again')
areas = dict_areas[sel_area_scheme]
```
## Get Area Solid Geometry
Unfortunately, we can't directly get Area 3D Geometry, because it's a 2D object… However, we can get its boundaries. And once we have boundaries we can easily create an extruded solid by using [GeometryCreationUtilities .CreateExtrusionGeometry](https://rvtdocs.com/2023/2dd1de2f-b8fc-60d6-30d8-46810f79c3fc). Also keep in mind that I will use a random height (10ft = ~3m) for creating a 3D representation of my Area 3D Boxes.
I will make it as a function, so you can easily adjust and reuse it.
```python
#📦 Function to create a solid from an Area
def create_area_solid(area):
area_boundary = area.GetBoundarySegments(SpatialElementBoundaryOptions())
if area_boundary:
if len(area_boundary) == 0:
return None
profile = CurveLoop()
for curve in area_boundary[0]: # First loop is the outer boundary
profile.Append(curve.GetCurve())
extrusion_height = 10.0 #⚠️ Random Height in Feet! ~3m
return GeometryCreationUtilities.CreateExtrusionGeometry([profile], XYZ.BasisZ, extrusion_height)
```
Here is how to use this function to get **Area Solids**.
```python
for area in areas:
try:
area_solid = create_area_solid(area)
except:
# ⚠️ Print Error Message if Fails
import traceback
print(traceback.format_exc())
```
💡I've added **Try/Except** so we can handle errors better.
## Find Intersecting Rooms
By now we have Area 3D Boxes geometry, and we can easily get Room.Location.Point.
Now we need to check if we room's point is actually intersecting with the geometry. I haven't seen a method to check if point intersects the geometry. However, there is a method[ Solid.IntersectWithCurve](https://rvtdocs.com/2023/8e04f956-b262-7f3e-59cb-d2c02c2769d7) (tricky to use this one!).
To use this method, we will need to convert our point into a tiny line with fraction of a length and use it for intersecting. Then we will get intersection segments, and we can check if them if [**IsAlmostEqualTo**](https://rvtdocs.com/2023/81a72471-bfa6-18ec-db83-911a49c3f4e8)**.**
```python
#✂️ Function to check if point is inside a solid
def is_point_inside_solid(point, solid):
# Create a tiny line from Point
line = Line.CreateBound(point, XYZ(point.X, point.Y, point.Z + 0.01)) # Create Tiny Line
tolerance = 0.00001
# Create Intersection Options
opts = SolidCurveIntersectionOptions()
opts.ResultType = SolidCurveIntersectionMode.CurveSegmentsInside
# Intersect Line with Geometry
sci = solid.IntersectWithCurve(line, opts)
for i,x in enumerate(sci):
curve = sci.GetCurveSegment(i)
pt_start = curve.GetEndPoint(0)
pt_end = curve.GetEndPoint(1)
if point.IsAlmostEqualTo(pt_start, tolerance) or point.IsAlmostEqualTo(pt_end, tolerance):
return True
```
Now we have everything we need to check if **Rooms **and **Areas** intersect and then do something. In my case I will just write `Area.Name` to `Room.Name`, so it's obvious that we got the correct match. But feel free to modify what should happen.
Here is how to check that:
```python
#🔓 Start transaction to modify the document
t = Transaction(doc, "Update Rooms")
t.Start()
for area in areas:
try:
area_solid = create_area_solid(area)
if area_solid:
for room in rooms:
room_point = room.Location.Point
if is_point_inside_solid(room_point, area_solid):
room.Name = Element.Name.GetValue(area) #Abstract Example
#👇 Write something to a Parameter...
# value = area.Name
# room.LookupParameter("SharedParamName").Set(value)
except:
# ⚠️ Print Error Message if Fails
import traceback
print(traceback.format_exc())
t.Commit() #🔒
```
💡 Don't forget to add [**Transaction **](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd)for Changes 😉
## Final Code + Results
😉 Here is the final result put together.
```python
# -*- coding: utf-8 -*-
__title__ = "Find Intersecting Rooms&Areas"
__doc__ = """Date = 18.04.2024
__________________________
Description:
Find Intersecting Rooms&Areas and write Area.Name to Room.Name
(Adjust to your own needs)
_____________________________________________________________________
How-To:
- Run the Tool
- Select AreaScheme of desired Areas
_____________________________________________________________________
Author: Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Architecture import Room
from pyrevit import forms
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
#_____________________________________________________________________
# 📦 Function to create a solid from an Area
def create_area_solid(area):
area_boundary = area.GetBoundarySegments(SpatialElementBoundaryOptions())
if area_boundary:
if len(area_boundary) == 0:
return None
profile = CurveLoop()
for curve in area_boundary[0]: # First loop is the outer boundary
profile.Append(curve.GetCurve())
extrusion_height = 10.0 # ⚠️ Random Height in Feet! ~3m
return GeometryCreationUtilities.CreateExtrusionGeometry([profile], XYZ.BasisZ, extrusion_height)
#✂️ Function to check if point is inside a solid
def is_point_inside_solid(point, solid):
# Create a tiny line from Point
line = Line.CreateBound(point, XYZ(point.X, point.Y, point.Z + 0.01)) # Create Tiny Line
tolerance = 0.00001
# Create Intersection Options
opts = SolidCurveIntersectionOptions()
opts.ResultType = SolidCurveIntersectionMode.CurveSegmentsInside
# Intersect Line with Geometry
sci = solid.IntersectWithCurve(line, opts)
for i,x in enumerate(sci):
curve = sci.GetCurveSegment(i)
pt_start = curve.GetEndPoint(0)
pt_end = curve.GetEndPoint(1)
if point.IsAlmostEqualTo(pt_start, tolerance) or point.IsAlmostEqualTo(pt_end, tolerance):
return True
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝
#_____________________________________________________________________
from collections import defaultdict
#👉 Get Rooms & Areas
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
all_areas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToElements()
#🔎 Sort Areas by AreaScheme
dict_areas = defaultdict(list) # List will be default value for new keys!
for area in all_areas:
dict_areas[area.AreaScheme.Name].append(area)
#_____________________________________________________________________
from pyrevit import forms
# 👉 Select AreaScheme
sel_area_scheme = forms.SelectFromList.show(dict_areas.keys(), button_name='Select AreaScheme')
if not sel_area_scheme:
forms.alert('No AreaScheme was selected. Please Try Again')
areas = dict_areas[sel_area_scheme]
#_____________________________________________________________________
#🔓 Start transaction to modify the document
t = Transaction(doc, "Update Rooms")
t.Start()
for area in areas:
try:
area_solid = create_area_solid(area)
if area_solid:
for room in rooms:
room_point = room.Location.Point
if is_point_inside_solid(room_point, area_solid):
room.Name = Element.Name.GetValue(area) #Abstract Example
#👇 Write something to a Parameter...
# value = area.Name
# room.LookupParameter("SharedParamName").Set(value)
except:
# ⚠️ Print Error Message if Fails
import traceback
print(traceback.format_exc())
t.Commit() #🔒
```
## Result:

### Disable Dragging Elements on Selection with pyRevit startup script
https://learnrevitapi.com/blog/stop-dragging-elements-on-selection-with-pyrevit-startup-script/
## How to stop dragging elements?
In Revit, there is a selection option menu that includes several toggles. One of these toggles is called "**Drag Elements on Selection" among others.**

We can turn it off, and problem sort of goes away.
However, many BIM Managers face an issue that, not every user deactivates this toggle. And it can lead to accidents by dragging elements, especially among less experienced Revit users. While most of the times it's not harmful, sometimes users might not even realize it and later you find an element floating in space because of that.
## Solution
What if there was a way to automatically disable this setting by default, whenever users open the Revit Application? And this can actually be achieved by using **startup **script in **pyRevit**.
It's a script that will be executed every time Revit application is started and loads pyRevit. You can do a lot of things with it, but let's focus on this particular settings.
## pyRevit start up script
To better understand startup script, I would recommend you to reference the **pyRevit Dev Docs:**
- [Extension Startup Script](https://pyrevitlabs.notion.site/Extension-Startup-Script-605ce7b1831d41d88741bc9a9eee42a7)
- [UI Extension Bundle](https://pyrevitlabs.notion.site/Extension-Bundles-10df16fe826040bc9dbd9e83bb4248e6)

After reading the documentation you will learn that you just need to create `startup.py` file in the root folder of your extension (next to `lib`, and `hooks` folders if you have them already).
## Script to Disable Drag Elements
Once you've created the file, we need to write a script that will change these settings, and it's super simple. We need to use [SelectionUIOptions ](https://rvtdocs.com/2024/a87989f8-c37e-e5c6-7836-ff5014a66513)Class to disable these options.

And it's not complicated to use, here is a snippet you can paste in your `startup.py` script to get these options and change them.
```python
# Imports
from pyrevit import HOST_APP, framework
from pyrevit import DB
from pyrevit import forms
# Variables
uidoc = HOST_APP.uidoc
# Get And Modify Options
from Autodesk.Revit.UI import SelectionUIOptions
opts = SelectionUIOptions.GetSelectionUIOptions()
opts.DragOnSelection = False
#Other Options: (Select True/False)
#opts.SelectFaces = False # / True
#opts.SelectLinks = False # / True
#opts.SelectPinned = False # / True
#opts.SelectUnderlay = False # / True
#opts.ActivateControlsAndDimensionsOnMultiSelect = False #/ True
```
💡 There is no need for **Transaction**!
### Create 3D BoundingBox by using DirectShape
https://learnrevitapi.com/blog/create-3d-boundingbox-with-directshape-in-revit-api/
## How To Visualize a BoundingBox with Revit API?
If you start using BoundingBox, and something doesn't add up, then it's a good point to visualize your bounding box to better understand the issue. If you use Dynamo then you can simply get a preview in the Dynamo Viewer.
However, if you use pyRevit, then it gets a bit tricky. However, there is a way out by converting bounding box into a solid geometry. And for that we need to use [DirectShape ](https://rvtdocs.com/2023/bfbd137b-c2c2-71bb-6f4a-992d0dcf6ea8)class from Revit API, so we can create this solid in the project.
To do that we need to do the following steps:
- Get BoundingBox
- Create Base Outline
- Create solid with [CreateExtrusionGeometry](https://rvtdocs.com/2023/c21472c0-2825-819c-226f-bc8e00ddfec8)
- Create [DirectShape ](https://rvtdocs.com/2023/bfbd137b-c2c2-71bb-6f4a-992d0dcf6ea8)from the solid
Let's look how to make it happen
## Get BoundingBox
For this example, I will just get my current selection from Revit's UI. But please adjust it to your own needs.
Here is how to get selected elements and retrieve their BoundingBox.
```text
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#Import .NET List
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 VARIABLES
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
# Get Selected Elements
selected_elems = [doc.GetElement(elId) for elId in uidoc.Selection.GetElementIds()]
# Get BoundingBoxes
for elem in selected_elems:
bbox = elem.get_BoundingBox(None)
```
## Create Solid from BoundingBox
Now we need to convert BoundingBox to a Solid object, so we can construct a [DirectShape ](https://rvtdocs.com/2023/bfbd137b-c2c2-71bb-6f4a-992d0dcf6ea8)**.**
Since BoundingBoxes are simple boxes, we can use [CreateExtrusionGeometry ](https://rvtdocs.com/2023/c21472c0-2825-819c-226f-bc8e00ddfec8)method to create it. We just need to create an outline by using its **Min **and **Max **points.
Here is function that can do that for you:
```python
def solidBoundingBox(elem):
bbox = elem.get_BoundingBox(None)
# Lower Corner Points from BoundingBox
pt0 = XYZ(bbox.Min.X, bbox.Min.Y, bbox.Min.Z)
pt1 = XYZ(bbox.Max.X, bbox.Min.Y, bbox.Min.Z)
pt2 = XYZ(bbox.Max.X, bbox.Max.Y, bbox.Min.Z)
pt3 = XYZ(bbox.Min.X, bbox.Max.Y, bbox.Min.Z)
# Create Edges of the BoundingBox
edge0 = Line.CreateBound(pt0, pt1)
edge1 = Line.CreateBound(pt1, pt2)
edge2 = Line.CreateBound(pt2, pt3)
edge3 = Line.CreateBound(pt3, pt0)
# Create CurveLoop from Edges
edges = [edge0, edge1, edge2, edge3]
baseLoop = CurveLoop.Create(edges)
loopList = [baseLoop]
# Create Solid
height = bbox.Max.Z - bbox.Min.Z
preTransformBox = GeometryCreationUtilities.CreateExtrusionGeometry(loopList, XYZ.BasisZ, height)
# Make sure BoundingBox has the same Transform
transformBox = SolidUtils.CreateTransformed(preTransformBox, bbox.Transform)
return transformBox
```
## Create Direct Shape
Now, once you have your Solid geometry it's very easy to create a direct shape.
Here is the code snippet:
```python
#🔓 Start a transaction
t = Transaction(doc, 'Create DirectShape from BoundingBox')
t.Start()
for el in selection:
# Convert Element's BoundingBox to Solid
solid = solidBoundingBox(el)
# Create a DirectShape
ds = DirectShape.CreateElement(doc, ElementId(BuiltInCategory.OST_GenericModel))
ds.SetShape([solid])
t.Commit()
```
## Final Snippet
Here is the whole code put together so there are no misunderstandings. You can even use Revit Python Shell to test it.

```python
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#Import .NET List
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 VARIABLES
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
#👉 Get Selected Elements
selected_elems = [doc.GetElement(elId) for elId in uidoc.Selection.GetElementIds()]
#🔓 Start a transaction
t = Transaction(doc, 'Create DirectShape from BoundingBox')
t.Start()
def solidBoundingBox(elem):
bbox = elem.get_BoundingBox(None)
# Lower Corner Points from BoundingBox
pt0 = XYZ(bbox.Min.X, bbox.Min.Y, bbox.Min.Z)
pt1 = XYZ(bbox.Max.X, bbox.Min.Y, bbox.Min.Z)
pt2 = XYZ(bbox.Max.X, bbox.Max.Y, bbox.Min.Z)
pt3 = XYZ(bbox.Min.X, bbox.Max.Y, bbox.Min.Z)
# Create Edges of the BoundingBox
edge0 = Line.CreateBound(pt0, pt1)
edge1 = Line.CreateBound(pt1, pt2)
edge2 = Line.CreateBound(pt2, pt3)
edge3 = Line.CreateBound(pt3, pt0)
# Create CurveLoop from Edges
edges = [edge0, edge1, edge2, edge3]
baseLoop = CurveLoop.Create(edges)
loopList = [baseLoop]
# Create Solid
height = bbox.Max.Z - bbox.Min.Z
preTransformBox = GeometryCreationUtilities.CreateExtrusionGeometry(loopList, XYZ.BasisZ, height)
# Make sure BoundingBox has the same Transform
transformBox = SolidUtils.CreateTransformed(preTransformBox, bbox.Transform)
return transformBox
for el in selection:
solid = solidBoundingBox(el)
# Create a DirectShape
ds = DirectShape.CreateElement(doc, ElementId(BuiltInCategory.OST_GenericModel))
ds.SetShape([solid])
t.Commit()
```
### Suppress Warnings in Revit API
https://learnrevitapi.com/blog/suppress-warnings-in-revit-api/
## Revit Warnings
While warnings are very important to notify users that something is wrong, Revit Warnings can be just annoying...
Remember those times, when you set the same 'Mark' value and you get a warning where you have to click on **OK **button?

## Why Suppressing Warnings?
When we work in Revit, we often get annoying Warning messages.
And while making an extra click might not seem like an issue, imagine if you create a script to change 100 elements in individual transactions, and each one will causes a warning...
Then you would have to click on all 100 warnings or Kill Revit process...
`💡That's usually when people start asking:`
**`"How To Suppress Warnings?"`**` `
## Create a Warning with Revit API
Before I can show you how to suppress a warning, we need to find a way to create a warning with Revit API.
So every time we click on a button we get a warning, then we can experiment and learn how to suppress it.

I think the easiest way to trigger a warning in Revit is to set the same values in Mark Parameter. Then you will get this warning:

Here is a simple snippet that will give us this warning
```text
#⬇️ Imports
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import ObjectType
#📦 Variables
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
#👉 Pick Walls
ref_picked_walls = uidoc.Selection.PickObjects(ObjectType.Element, WallFilter())
picked_walls = [doc.GetElement(ref) for ref in ref_picked_walls]
#⚠️ Create a Warning
for wall in picked_walls:
# 🔓 Start Transaction
t = Transaction(doc, 'Update Mark')
t.Start()
#⚠️ Warning 1
p_mark = wall.get_Parameter(BuiltInParameter.ALL_MODEL_MARK)
p_mark.Set('Warning 2')
t.Commit()
```
This script does the following:
👉 Prompts user to select Walls
🔓 Starts Transaction for making changes
⚠️Changes Mark Parameter to get a Warnin
*💡****P.S.***
*I always recommend to put Transaction outside of loops so your scripts execute much faster. However, in this example I want each wall to give me a warning while I'm in development stage! *
*And don't select hundreds of walls!*
## Suppress All Warnings
Now we have a script that will give us multiple warnings when we execute and select walls.
Now we can think of how can we can suppress these warnings. We will start by suppressing all Revit warnings, and later I will show you how to suppress specific ones only.
**To suppress a warning:**
You need to do 2 things:
1️⃣ Create a Warning Handler with [**IFailuresPreprocessor**](https://rvtdocs.com/2025/Autodesk.Revit.DB.IFailuresPreprocessor)
2️⃣ Set Warning Handler to your transaction
Let's explore how to do these steps
## 1️⃣ Create a Warning Handler
Firstly, we need to create a class that will interact with warnings. WE have to use [**IFailuresPreprocessor**](https://rvtdocs.com/2025/Autodesk.Revit.DB.IFailuresPreprocessor) Interface for building our Warning Suppressor Class. (**Interface** - is a blueprint for building a class that has special functionality and methods to be overriden.)
👇 Here is a Sample Code for this class.
```text
#⚠️ Transaction Error Handler
class SupressWarnings(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
try:
failures = failuresAccessor.GetFailureMessages()
for fail in failures: #type: FailureMessageAccessor
severity = fail.GetSeverity()
description = fail.GetDescriptionText()
fail_id = fail.GetFailureDefinitionId()
if severity == FailureSeverity.Warning:
if fail_id == BuiltInFailures.GeneralFailures.DuplicateValue:
print('✅Suppressed Warning: {}'.format(description))
failuresAccessor.DeleteWarning(fail)
except:
import traceback
print(traceback.format_exc())
return FailureProcessingResult.Continue
```
💡I know it looks complicated, but you can literally copy this code and change nothing to suppress all warning.
But if you want a brief explanation of all the steps, here we go:
1️⃣ Create a Class and Inherit **IFailuresPreprocessor **functionality
2️⃣ Override **PreprocessFailures **method that has* (self, failureAccessor) *arguments.
3️⃣ Create **try/except **blocks for development to print error messages if they happen. Because otherwise they won't be shown. (Optional step)
4️⃣ Get Warnings with .[GetFailureMEssages](https://rvtdocs.com/2025/Autodesk.Revit.DB.FailuresAccessor.GetFailureMessages)
5️⃣ Iterate through warnings and get:
- Severity
- Description
- FailureId
6️⃣ IF severity says Warning, then DeleteWarning
7️⃣ We need to return **FailureProcessingResult.Continue**, or otherwise Revit might not let you accept the warning.
So this class is our warning handler that will just delete all Warnings and user won't even see them. But we need to configure **Transaction** to use our warning handler.
## 2️⃣ Set Warning Handler to a Transaction
Now let's go to our Transaction and set our custom warning handler. We have to write it between t.Start and t.Commit and it only takes 3 lines and they are self-explanatory:
1️⃣ fail_hand_opts = t.[GetFailureHandlingOptions](https://rvtdocs.com/2025/Autodesk.Revit.DB.Transaction.GetFailureHandlingOptions)()
2️⃣ fail_hand_opts .[SetFailuresPreprocessor](https://rvtdocs.com/2025/Autodesk.Revit.DB.FailureHandlingOptions.SetFailuresPreprocessor)(SupressWarnings())
3️⃣ t.[SetFailureHandlingOptions](https://rvtdocs.com/2025/Autodesk.Revit.DB.Transaction.SetFailureHandlingOptions)(fail_hand_opts)
Here is updated code snippet:
```text
#⚠️ Create a Warning
for wall in picked_walls:
# 🔓 Start Transaction
t = Transaction(doc, 'Update Mark')
t.Start()
#⚠️ Warning 1
p_mark = wall.get_Parameter(BuiltInParameter.ALL_MODEL_MARK)
p_mark.Set('Warning 2')
#💡 Assign Error Handler
fail_hand_opts = t.GetFailureHandlingOptions()
fail_hand_opts.SetFailuresPreprocessor(SupressWarnings())
t.SetFailureHandlingOptions(fail_hand_opts)
t.Commit()
```
**💡SuppressWarnings**() - Is our warning handler class we made.
By using these 2 snippets, you will be able to suppress any warnings that happen during this specific Transaction!
Give it a Try!
## Suppress Specific Warnings
It's not a good practice to suppress all warnings all the time, because we might suppress something we would want to see right away... So instead, let's look how to suppress specific warnings only.
We will need to use **fail_id **variable that we defined in our class and compare it to Revit API classes.
In my case, I want to suppress warnings for duplicate values and I need to use this property from GeneralFailures Class:
[BuiltInFalures.GeneralFailures.DuplicateValue](https://rvtdocs.com/2025/Autodesk.Revit.DB.BuiltInFailures.GeneralFailures)
Here is how to do it:
```text
#⚠️ Transaction Warning Handler
class SupressWarnings(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
try:
failures = failuresAccessor.GetFailureMessages()
for fail in failures: #type: FailureMessageAccessor
severity = fail.GetSeverity()
description = fail.GetDescriptionText()
fail_id = fail.GetFailureDefinitionId()
if severity == FailureSeverity.Warning:
print('✅Suppressed Warning: {}'.format(description))
failuresAccessor.DeleteWarning(fail)
except:
import traceback
print(traceback.format_exc())
return FailureProcessingResult.Continue
```
## 💪 And that's how you suppress warnings with Revit API
### Create Sections on the ScopeBox edges
https://learnrevitapi.com/blog/create-sections-from-scope-boxes-with-revit-api/
## Intro
I was asked on how to Create Sections on the edges of a ScopeBox?
Let's think what we need to do to achieve that:
1️⃣ Pick ScopeBoxes
2️⃣ Get ScopeBox Bounding Box
3️⃣ Calculate Lines and Heigth based on .Min and .Max
4️⃣ Calculate ScopeBox Heigth based on Min/Max Z Value
5️⃣ Calculate Points and Vectors
6️⃣ Create Transform
🎯 Create Sections
💡 Let's code step by step and combine The final script in the end which will work like this:

## 1️⃣ Pick ScopeBoxes
First of all we need to select desired ScopeBoxes. There are many ways to do it, I will create [**ISelectionFilter **](https://rvtdocs.com/2023/d552f44b-221c-0ecd-d001-41a5099b2f9f)so I can only select **ScopeBoxes.**
Also keep in mind that [Selection.PickObjects()](https://rvtdocs.com/2023/8038c1e1-262e-5d25-c065-b75b9ba98603) return References. So we need to convert the to actual elements.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import *
from pyrevit import forms
#📦 Variables
doc = __revit__.ActiveUIDocument.Document #type: Document
uidoc = __revit__.ActiveUIDocument
#💊 Classes
# Define a selection filter class for Scope Boxes
class ScopeBoxSelectionFilter(ISelectionFilter):
def AllowElement(self, element):
if element.Category.Id == ElementId(BuiltInCategory.OST_VolumeOfInterest):
return True
#1️⃣ Pick ScopeBoxes
ref_scope_boxes = uidoc.Selection.PickObjects(ObjectType.Element, ScopeBoxSelectionFilter())
scope_boxes = [doc.GetElement(ref) for ref in ref_scope_boxes]
#Ensure ScopeBox selected
if not scope_boxes:
forms.alert('No Box selected. Please Try Again',exitscript=True)
```
💡 Also it's good to check if we even selected any **ScopeBoxes **before going further. **forms.alert** is the perfect solution.
## 2️⃣ Get ScopeBox Bounding Box
Once we got ScopeBoxes, we can start iterating through them. The first thing we need to get its [BoundingBox](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2).
We can use get_BoundingBox which is based on [**BoundingBox Property.**](https://rvtdocs.com/2023/def2f9f2-b23a-bcea-43a3-e6de41b014c8)
```python
#2️⃣ Iterate through scope boxes
for sbox in scope_boxes:
BB = sbox.get_BoundingBox(None)
```
## 3️⃣ Calculate Lines and Height based on .Min and .Max
Next, we need to calculate Lines and Height based on BB [Min ](https://rvtdocs.com/2023/608e6914-2465-b572-2c5d-2a6cd696c740)and [Max ](https://rvtdocs.com/2023/b79bd9ee-ccff-cc81-8a32-9eb9bdb1e58c)points.

ScopeBox Height would be the difference between Min/Max Z Coordinate.
And to create lines, we would just use X,Y coordinates of both points to create lines between corners.
```python
#3️⃣ Iterate through scope boxes
for sbox in scope_boxes:
BB = sbox.get_BoundingBox(None)
# Calculate Heigth
BB_height = BB.Max.Z - BB.Min.Z
# Calculate Bottom Points
pt_1 = XYZ(BB.Min.X, BB.Min.Y, BB.Min.Z)
pt_2 = XYZ(BB.Max.X, BB.Min.Y, BB.Min.Z)
pt_3 = XYZ(BB.Max.X, BB.Max.Y, BB.Min.Z)
pt_4 = XYZ(BB.Min.X, BB.Max.Y, BB.Min.Z)
# Create Lines
line_1 = Line.CreateBound(pt_1, pt_2)
line_2 = Line.CreateBound(pt_2, pt_3)
line_3 = Line.CreateBound(pt_3, pt_4)
line_4 = Line.CreateBound(pt_4, pt_1)
lines = [line_1, line_2, line_3, line_4]
```
## 4️⃣ Calculate Points and Vectors
Now we have everything we need, let's start iterating through lines and prepare everything we need for creating sections.
First of all we need to get line points Start, End and Middle.
Start and End points will be used for creating a vector, so our sections is rotated correctly. and Point Mid will be used for the origin point.
```python
lines = [line_1, line_2, line_3, line_4]
#4️⃣ Create Sections from Lines
for line in lines:
# Calculate Origin + Vector
pt_start = line.GetEndPoint(0) #type: XYZ
pt_end = line.GetEndPoint(1) #type: XYZ
pt_mid = (pt_start + pt_end)/2 #type: XYZ
vector = pt_end - pt_start #type: XYZ
```
## 5️⃣ Create Transform
Now let's create Transform for our section. It looks confusing, but after you use it a few times it gets easy. (Check the video for detailed explanation). To create an instance of Transform we need to use its property [**Identity**](https://rvtdocs.com/2023/2eb2a180-c7ef-a0c0-0fa4-baef2901c351). It's a bit strange, but that's a common way across all 3D Softwares.
Next we will set [Origin ](https://rvtdocs.com/2023/9c67a7e5-c869-bfb9-c6fa-e5ac356868f0)property by assigning our our Mid Point.
And we need to calculate X, Y, Z vectors so our section is placed correctly.
The X is going to be the vector we calculated earlier. We will need to [Normalize ](https://rvtdocs.com/2023/6228ceb8-100b-daf8-78cf-0b7f514a1338)it(Normalized indicates that the length of this vector equals one unit vector). And also we need to rotate it so it looks in the right direction by multiplying by -1.
Y Vector is going to be vertical Axis (XYZ.BasisZ)
Last vector can always be calculated with [CrossProduct](https://rvtdocs.com/2023/c5c099ad-e9f5-976b-94ee-d96af1c677f3). The cross product is defined as the vector which is perpendicular to both vectors.
```python
#5️⃣ Create Transform
trans = Transform.Identity
trans.Origin = pt_mid
vector = vector.Normalize() * -1 # Reverse Vector by *-1
trans.BasisX = vector
trans.BasisY = XYZ.BasisZ
trans.BasisZ = vector.CrossProduct(XYZ.BasisZ)
#The cross product is defined as the vector which is perpendicular to both vectors
```
## 🎯 Create Section
Lastly, We need create a SectionBox which will represent the Section itself.
We start by defining a default [BoundingBox](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2).
Then we can calculate it's Min and Max points by using **line_length **and **BB_height **values. And we will also apply ther Transform that we've just created in the previous step. This will ensure our section is located in a correct place in 3D space.
```python
#6️⃣ Create SectionBox
section_box = BoundingBoxXYZ() # origin 0,0,0
offset = 1 #in Feet!
half = line.Length/2
section_box.Min = XYZ(-half - offset , 0 - offset , 0)
section_box.Max = XYZ(half + offset , BB_height + offset , line.Length)
#💡 XYZ(X - Left/Right , Y - Up/Down , Z - Forward/Backwards)
section_box.Transform = trans # Apply Transform (Origin + XYZ Vectors)
#6️⃣ Create Section View
section_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeSection)
new_section = ViewSection.CreateSection(doc, section_type_id, section_box)
```
## Final Code:
Finally here is how it works:

Let's combine all the code together, so there are no confusing of what goes where.
```python
# -*- coding: utf-8 -*-
__title__ = 'ScopeBox to Sections'
#⬇️ Imports
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import *
from pyrevit import forms
#📦 Variables
doc = __revit__.ActiveUIDocument.Document #type: Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
#💊 Classes
# Define a selection filter class for Scope Boxes
class ScopeBoxSelectionFilter(ISelectionFilter):
def AllowElement(self, element):
if element.Category.Id == ElementId(BuiltInCategory.OST_VolumeOfInterest):
return True
#🎯 MAIN
#1️⃣ Pick ScopeBoxes
ref_scope_boxes = uidoc.Selection.PickObjects(ObjectType.Element, ScopeBoxSelectionFilter())
scope_boxes = [doc.GetElement(ref) for ref in ref_scope_boxes]
#Ensure ScopeBox selected
if not scope_boxes:
forms.alert('No Box selected. Please Try Again',exitscript=True)
# Transaction 🔓
t = Transaction(doc, 'BB to Sections')
t.Start()
#2️⃣ Iterate through scope boxes
for sbox in scope_boxes:
BB = sbox.get_BoundingBox(None)
BB_height = BB.Max.Z - BB.Min.Z
#3️⃣ Calculate Bottom Points
pt_1 = XYZ(BB.Min.X, BB.Min.Y, BB.Min.Z)
pt_2 = XYZ(BB.Max.X, BB.Min.Y, BB.Min.Z)
pt_3 = XYZ(BB.Max.X, BB.Max.Y, BB.Min.Z)
pt_4 = XYZ(BB.Min.X, BB.Max.Y, BB.Min.Z)
#3️⃣ Create Lines
line_1 = Line.CreateBound(pt_1, pt_2)
line_2 = Line.CreateBound(pt_2, pt_3)
line_3 = Line.CreateBound(pt_3, pt_4)
line_4 = Line.CreateBound(pt_4, pt_1)
lines = [line_1, line_2, line_3, line_4]
# Create Sections from Lines
for line in lines:
#4️⃣ Calculate Origin + Vector
pt_start = line.GetEndPoint(0) #type: XYZ
pt_end = line.GetEndPoint(1) #type: XYZ
pt_mid = (pt_start + pt_end)/2 #type: XYZ
vector = pt_end - pt_start #type: XYZ
#5️⃣ Create Transform
trans = Transform.Identity
trans.Origin = pt_mid
vector = vector.Normalize() * -1 # Reverse Vector by *-1
trans.BasisX = vector
trans.BasisY = XYZ.BasisZ
trans.BasisZ = vector.CrossProduct(XYZ.BasisZ)
#The cross product is defined as the vector which is perpendicular to both vectors
#6️⃣ Create SectionBox
section_box = BoundingBoxXYZ() # origin 0,0,0
offset = 1 #in Feet!
half = line.Length/2
section_box.Min = XYZ(-half - offset , 0 - offset , 0)
section_box.Max = XYZ(half + offset , BB_height + offset , line.Length)
#💡 XYZ(X - Left/Right , Y - Up/Down , Z - Forward/Backwards)
section_box.Transform = trans # Apply Transform (Origin + XYZ Vectors)
#6️⃣ Create Section View
section_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeSection)
new_section = ViewSection.CreateSection(doc, section_type_id, section_box)
t.Commit() #🔒
```
##
## ⌨️ Happy Coding!
### pyRevit Hooks: How to create EventTriggers to Block CAD Imports in Revit API?
https://learnrevitapi.com/blog/pyrevit-hooks-event-triggers/
## What is Revit API Events or pyRevit hooks?
**Event **- Is an action that can be monitored by the software. This means that we can subscribe to an event, and whenever it happens we will execute a piece of our code.
**pyRevit hook** is a simplified way of subscribing to Events. It allows you to simply create hooks folder, and name your python file and pyRevit knows what to do next.
## Why do we need Events?
When we work with Revit API we have an ability to subscribe to **Events, and** execute code when they are triggered. This allows you to wait for certain actions and then execute your code when it happens. It can open a whole new world of automation in Revit.
For example, we know that Import CAD is a cursed button, and many BIM managers try very hard to make everyone Link CAD files instead of importing because they bring a lot of useless patterns, and don't have an original path associated with them… So we can subscribe to a command event of Import CAD button, and whenever it's clicked we can execute our assigned code (show a warning message in this case).
This examples is exactly what I will show you how to create by the end of this lesson. But first let's explore Revit API events a bit more.
## Revit API Event Types
There are a lot of events available in Revit API, and I will try to categorize and list them here starting with Database events.
### 1️⃣ DataBase Events ([**Application **](https://rvtdocs.com/2023/94db8ea8-d2c3-5e71-8030-466bcb8e4426))
Database events are looking for changes related to the project and application state. It will monitor when projects are being saved, opened printed, exported and similar interactions. These events can be found under [**Application **](https://rvtdocs.com/2023/94db8ea8-d2c3-5e71-8030-466bcb8e4426)Class and here is a list of them:
- [DocumentChanged ](https://rvtdocs.com/2023/988dd6cf-fcaa-85d2-622d-c50f13917a13)- notify when a transaction is committed, undone or redone
- [DocumentClosing ](https://rvtdocs.com/2023/f6573d8b-20ca-1ec7-fb20-755e3c02ec06)- notify when Revit is about to close a document
- [DocumentClosed ](https://rvtdocs.com/2023/d6c0ea53-175c-75b5-4e0e-9b3d5ba92f06)- notify just after Revit has closed a document
- [DocumentCreating ](https://rvtdocs.com/2023/6fbb52ca-889f-3340-30ba-a87c549fcd13)- notify when Revit is about to create a new document
- [DocumentCreated ](https://rvtdocs.com/2023/a8958534-bcbf-a627-eacf-aeeb46934197)- notify when Revit has finished creating a new document
- [DocumentOpening ](https://rvtdocs.com/2023/ca44b05b-3875-ed67-cbff-281d5aef48c6)- notify when Revit is about to open a document
- [DocumentOpened](https://rvtdocs.com/2023/b9415c2d-442e-f61d-aafa-de31cce7959b) - notify after Revit has opened a document
- [DocumentPrinting ](https://rvtdocs.com/2023/86546cf5-eb2f-ffd7-3931-fc361f1264e2)- notify when Revit is about to print a view or ViewSet of the document
- [DocumentPrinted](https://rvtdocs.com/2023/0846d2d2-5eff-0df2-cfdc-50378114a1e3) - notify just after Revit has printed a view or ViewSet of the document
- [DocumentReloadedLatest ](https://rvtdocs.com/2023/83f69554-54d6-1632-fb6c-81edf0280d33)- notify after Revit has finished reloading a document with central model
- [DocumentReloadingLatest](https://rvtdocs.com/2023/f266e021-0f55-3671-f010-4b23128d6ca3) - notify when revit is about to reload latest changes from central model
- [DocumentSaving ](https://rvtdocs.com/2023/af9cc434-2934-d407-8ecf-960fc95ac569)- notify when Revit is about to save the document
- [DocumentSaved](https://rvtdocs.com/2023/3eef29c9-7384-77e7-e4c1-d2149ea79e95) - notify just after Revit has saved the document
- [DocumentSavingAs ](https://rvtdocs.com/2023/331fadc0-ca6a-13c4-2242-7a8da3e35ed3)- notify when Revit is about to save the document with a new name
- [DocumentSavedAs ](https://rvtdocs.com/2023/6d3e2981-dfe0-fd33-9bd0-57e04815c4fd)- notify when Revit has just saved the document with a new name
- [DocumentSynchronizingWithCentral ](https://rvtdocs.com/2023/3587a871-b667-7a2a-89e9-8601460c2cec)- notify when Revit is about to synchronize a document with the central file
- [DocumentSynchronizedWithCentral ](https://rvtdocs.com/2023/ae850cbb-699f-0077-5ee7-9401e8eb8451)- notify just after Revit has synchronized a document with the central file
- [DocumentWorksharingEnabled](https://rvtdocs.com/2023/51879d12-03fd-0360-d6e1-ce1dcbccbe2d) - notify when a document has become workshared
- [ElementTypeDuplicated](https://rvtdocs.com/2023/07386cf7-236a-d8cc-2423-298467b1f441) - notify when Revit has finished duplicating an element type.
- [ElementTypeDuplicating](https://rvtdocs.com/2023/d8bf6d7a-9d18-9f9d-85ef-f2507710759e) - notify when Revit is just about to duplicate an element type.
- [FailuresProcessing ](https://rvtdocs.com/2023/446796ca-d8f5-0f8a-7b82-a4ec6e5aa7a0)- notify when Revit is processing failures at the end of a transaction
- [FamilyLoadedIntoDocument](https://rvtdocs.com/2023/ca1d4dde-b446-d9d4-72a2-c649475eafe5) - notify after Revit loaded a family into a document.
- [FamilyLoadingIntoDocument](https://rvtdocs.com/2023/cb807c26-a08a-ec81-e97e-1bdc3ed9699e) - notify when Revit is just about to load a family into a document.
- [FileExporting ](https://rvtdocs.com/2023/fd255a5c-f079-e2bb-060b-4ca778f499fc)- notify when Revit is about to export to a file format supported by the API
- [FileExported ](https://rvtdocs.com/2023/54ac62e1-a215-ba22-c19e-6ad3c37ccc7c)- notify after Revit has exported to a file format supported by the API
- [FileImporting ](https://rvtdocs.com/2023/175ff66b-fd69-bf09-9153-7695c140720c)- notify when Revit is about to import a file format supported by the API
- [FileImported ](https://rvtdocs.com/2023/f72dee18-1a0d-dc0c-eb72-b75b0939c7c9)- notify after Revit has imported a file format supported by the API
- [LinkedResourceOpened](https://rvtdocs.com/2023/58045f61-5a60-aa9e-5360-afb39e51268e) notify immediately after Revit has finished opening a linked resource.
- [LinkedResourceOpening](https://rvtdocs.com/2023/54d34744-25e2-4e7b-87ef-695aa00fe899) notify when Revit is just about to open a linked resource.
- [ProgressChanged ](https://rvtdocs.com/2023/cabf8932-111c-6036-3d74-3d33c18260ed)- notify when an operation in Revit has progress bar data
- [ViewExported](https://rvtdocs.com/2023/0a3d3bee-957a-45e0-3779-b1b924a0ce0f) notify immediately after Revit has finished exporting a view of the document.
- [ViewExporting](https://rvtdocs.com/2023/0968f8d8-2f4a-619e-f085-3c8aedcb1775) notify when Revit is just about to export a view of the document.
- [ViewPrinted](https://rvtdocs.com/2023/5f995f6a-15d8-b1c3-9bc4-3bd203dc16f6) - notify just after Revit has printed a view of the document
- [ViewPrinting](https://rvtdocs.com/2023/9dab43ee-41f1-99d3-6480-d32af1675ad4) - notify when Revit is about to print a view of the document
- [ViewsExportedByContext](https://rvtdocs.com/2023/8488474a-5499-567b-4505-89ba6c401c63) notify immediately after Revit has finished exporting one or more views of the document via an export context by CustomExporter.
- [ViewsExportingByContext](https://rvtdocs.com/2023/1d8c5c16-9458-9846-627a-01d8283c70b5) notify when Revit is just about to export one or more views of the document via an export context by CustomExporter.
- [WorksharedOperationProgressChanged](https://rvtdocs.com/2023/8f1a7577-eb50-2135-ffa1-8b18fcf22691) notify when progress has changed during Collaboration for Revit's workshared operations: open model and synchronize with central.
### 2️⃣ UI Events ([**UIApplication**](https://rvtdocs.com/2023/51ca80e2-3e5f-7dd2-9d95-f210950c72ae))
Then we have related to Revit UI. These are about interaction with the application or certain actions being taken. All these events are located in [**UIApplication**](https://rvtdocs.com/2023/51ca80e2-3e5f-7dd2-9d95-f210950c72ae)** **Class, and here is the list:
- [ApplicationClosing ](https://rvtdocs.com/2023/61068521-c216-3ab5-9d6e-28006fcfe0ae)-be notified when the Revit application is just about to be closed.
- [DialogBoxShowing](https://rvtdocs.com/2023/cb46ea4c-2b80-0ec2-063f-dda6f662948a) - be notified when Revit is just about to show a dialog box or a message box.
- [DisplayingOptionsDialog](https://rvtdocs.com/2023/7d12db51-950c-b506-f23d-19c1e58bd615) - be notified when Revit options dialog is displaying.
- [DockableFrameFocusChanged](https://rvtdocs.com/2023/f007d1f4-e911-60cf-3973-af1007b67ce2) - be notified when a Revit GenericDockableFrame has gained focus or lost focus in the Revit user interface.
- [DockableFrameVisibilityChanged](https://rvtdocs.com/2023/6ae2552a-6a6c-bc44-515d-8ca7ad7f6ae4) - be notified when a Revit GenericDockableFrame has been shown or hidden in the Revit user interface.
- [FabricationPartBrowserChanged](https://rvtdocs.com/2023/4b9bd1fa-925a-a5a3-af6c-d7b7b54e3ee7) - be notified when MEP Fabrication part browser is updated.
- [FormulaEditing](https://rvtdocs.com/2023/ff842cc8-67a9-2c51-843d-d17767e757a8) - be notified when the edit formula button has been clicked.
- [Idling](https://rvtdocs.com/2023/56145d84-e948-730a-dc72-2a7b88a50a99) - be notified when Revit is not in an active tool or transaction.
- [SelectionChanged](https://rvtdocs.com/2023/9ac32ac2-974b-235c-ceea-5d436e5b8e59) - be notified after the selection was changed.
- [TransferredProjectStandards](https://rvtdocs.com/2023/8c9b377b-1416-01b2-91ec-5ceb04ae55b3) - be notified after the scope of a Transfer Project Standards operation has been finalized.
- [TransferringProjectStandards](https://rvtdocs.com/2023/a7326050-7532-df52-a54a-8acd66a2a8a3) - be notified before the scope of an impending Transfer Project Standards operation has been finalized in the Transfer Project Standards dialog.
- [ViewActivated](https://rvtdocs.com/2023/b208aae7-5cbf-21b4-b70e-af2e63ece383) - be notified immediately after Revit has finished activating a view of a document.
- [ViewActivating](https://rvtdocs.com/2023/ee4212fa-e41d-5cb5-ddc3-e31bc42db881) - be notified when Revit is just about to activate a view of a document.
There are also Events under [Autodesk.Revit.UI](https://rvtdocs.com/2023/e86fd90a-8957-02a6-da7f-ced248966e3e) - [PreviewControl](https://rvtdocs.com/2023/50112279-5c9d-0351-bbd1-698e76be9e36) for monitoring user's interaction like DragEnter, DragLeave…
### 3️⃣ CommandBinding Event
We can create Command Binding Events. This will allow us to monitor commands within Revit and subscribe to them. You can see a list of all commands in [PostableCommand ](https://rvtdocs.com/2023/f6ccdc1b-6ac3-9c49-d0bb-8a7d1877eab0)Enumeration, it has hundreds if not thosands of commands, so I won't list them here…
On top of that all these commands can be subscribed as:
- [**BeforeExecuted**](https://rvtdocs.com/2023/1a0b276f-37f0-e800-e1a7-ecf4446c414f)- This read-only event occurs before the associated command executes. An application can react to this event but cannot make changes to documents, or affect the invocation of the command.
- [**CanExecute**](https://rvtdocs.com/2023/3601b61f-c546-13f3-4928-c0eec4c47b88)[ ](https://rvtdocs.com/2023/3601b61f-c546-13f3-4928-c0eec4c47b88)- Occurs when the associated command initiates a check to determine whether the command can be executed on the command target.
- [**Executed **](https://rvtdocs.com/2023/71c684fd-fc43-fadd-92f2-a7048c86d0fc)- This event occurs when the associated command executes and is where any overriding implementation should be performed.
💡pyRevit simplifies this step for us, but I will also show you how to manually subscribe with code, and these stages of an Event will matter.
### 4️⃣ IUpdater (Dynamic Model Update)
Lastly, I want to mention that there is also an [IUpdater Interface](https://rvtdocs.com/2023/4cdaf502-fc25-8f18-7618-8448cce33d11). It's The interface used to create an updater capable of reacting to changes in the Revit model. It also has its hook equivalent in pyRevit `doc-updater.py`
Technically it's not an event, but it acts like one. It allows us to monitor changes in the project, and piggy back on the same Transaction to add our additional changes to it.
Just to give you an example how it can be used:
We can monitor changes for Windows, and whenever they change, we might want to update X,Y,Z coordinates in one of the parameters, so we can actually tag their location and it will always update as you move them.
There are endless possibilities for new functionality by using [IUpdater](https://rvtdocs.com/2023/4cdaf502-fc25-8f18-7618-8448cce33d11). It's incredible useful, but I won't cover it in this lesson. It deserves a lesson of its own. Comment on the YouTube video if you want to see how to use it 😉
### So how do we work with Events?
We have 2 options to subscribe to Events in Revit API.
🅰️ pyRevit Hooks - Very powerful and beginner friendly approach
🅱️ Manually Subscribe to Events - You can also write the whole code yourself to subscribe, but then it needs to be executed every time you start Revit or whenever you need it.
I will mainly focus on pyRevit hooks, but I will also show an example of doing it manually in the end.
🎯 Let's create an Event to monitor when users click on **Import CAD **button. And then we will give them a warning, saying that they should Link instead of importing and ask for a password, so only a select few users can import CAD files. You can apply the same concept to other buttons or other events, it's just an example I chose.
## pyRevit Hooks
pyRevit provides a very simple approach to events. I will also link additional resources here that will help you understand them and see a few examples:
- [pyRevit Dev Docs - Extension Hooks](https://pyrevitlabs.notion.site/Extension-Hooks-b771ecf65f6a45fe87ae12beab2a73a6?pvs=24)
- [pyRevit Dev Docs - Anatomy of Hook Scripts](https://pyrevitlabs.notion.site/Anatomy-of-Hook-Scripts-47c2d5b796774afca51ff53a4c1e9f1c)
- [pyRevit Dev Docs - Create Your First Hook](https://pyrevitlabs.notion.site/Create-Your-First-Hook-0214eee855fc43cead1e6f30f586a04e)
- [Revit Dev Guide - Commands](https://help.autodesk.com/view/RVT/2024/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Commands_html)
In a nutshell - you need to create a **hooks **folder in **.extension **folder and place your scripts for certain events. And keep in mind that naming of your scripts in that folder is very important. The name of the files will tell pyRevit what kind of event should it be subscribed to. You can see a table of all hooks in [Extension Hooks](https://pyrevitlabs.notion.site/Extension-Hooks-b771ecf65f6a45fe87ae12beab2a73a6).

Creating pyRevit hooks is not that complicated. It's all about creating a python file with the correct name, and writing the script that you want to execute when event gets triggered.
💡 I know it still sounds confusing, but it's not! Let me show you how to actually use it.
## How to create pyRevit Hooks? (Example)
There are plenty of different hooks to choose from, but I will start with `command-before-exec[]`. This kind of hook can subscribe to certain commands inside of Revit and trigger **BEFORE **it's executed.
You can see a full list of commands and how to get them in the end of this post, but I need to name it `command-before-exec[ID_FILE_IMPORT].py,`so it gets triggered when user click on **Import CAD** button.
Let's make sure our users won't import CAD to Revit Projects and only allow in Family Documents.

First of all we need to create a hook python file in a hooks folder. Make sure you name your file correctly. In my case I want to create an Event for **ID_FILE_IMPORT **command, so I will have to name my file `command-before-exec[ID_FILE_IMPORT].py`
Here is folder structure example: (**.tab** and **lib **folders are just for reference so you know where to place hooks))

💡This file in hooks folder will tell pyRevit that the script inside should subscribe to **ID_FILE_IMPORT **command.
And here is a simple code we are going to put inside this python hook.
Whenever a user clicks on Import CAD, it will check if Document is project or family document, and if it's a project doc, then show a warning asking to use Link CAD. Additionally, it will also prompt a TextDialog asking for a password. If they enter the right one, they will be able to import CAD inside the project. Otherwise it won't allow importing CAD, and our BIM Managers can sleep tight at night.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from pyrevit import revit, EXEC_PARAMS
from Autodesk.Revit.UI import TaskDialog
#📦 Variables
sender = __eventsender__ # UIApplication
args = __eventargs__ # Autodesk.Revit.UI.Events.BeforeExecutedEventArgs
# args = EXEC_PARAMS.event_args
doc = revit.doc
# doc = args.GetDocument()
# doc = args.Document
#🎯 MAIN
if not doc.IsFamilyDocument:
#⚠️ Show Warning
TaskDialog.Show('Big Brother is Watching!',
'Import CAD is not Allowed! Use Link CAD Instead.')
#🔒 Ask user for Password
from pyrevit.forms import ask_for_string
password = 'LearnRevitAPI.com'
user_input = ask_for_string(prompt='Only users with a password can Import CAD.',
title='Import CAD Blocked')
# ❌ Stop Execution
if user_input != password:
args.Cancel = True
else:
TaskDialog.Show('Family CAD Import',
'Import CAD is Allowed in families!')
```
👀 Here is the Result of how it works in a **Project. **You will notice that once I write the correct password it allows me to Import CAD. But if I would write it wrong, it would not stop the command.** **

## How to get PostableCommand Id?
Let's go a step back and figure out how did I know that I need to use **ID_FILE_IMPORT **Command name for Command Binding?

I've noticed that people get very creative when looking for the right name of the command ID. You can find it in your journals or even in the .xml file of your shortcuts.
But we can also use [LookupPostableCommandId Method](https://rvtdocs.com/2023/e5cb5335-70f7-3f74-2263-188847474335) which comes from [Autodesk.Revit.UI.RevitCommandId](https://rvtdocs.com/2023/0fb2f851-f469-f739-d6ee-89b40b25c4a2).

This method takes a [PostableCommand Enumeration](https://rvtdocs.com/2023/f6ccdc1b-6ac3-9c49-d0bb-8a7d1877eab0), which has a list of all possible commands. There are hundreds if not thosands of them.

Here is an example of how to use it:
```text
from Autodesk.Revit.UI import RevitCommandId, PostableCommand
all_post_commands = PostableCommand.GetValues(PostableCommand)
for pc in all_post_commands: #type: PostableCommand
try:
rvt_com_id = RevitCommandId.LookupPostableCommandId(pc) #type: RevitCommandId
print('{} {}'.format(str(pc).ljust(45), rvt_com_id.Name))
except:
print(pc)
```
This will give you a list of all Postable Commands.
```text
RoofByFace ID_ROOF_PICK_FACES
Soffit ID_CREATE_SOFFIT_TB
LoadAsGroupIntoOpenProjects ID_LOAD_INTO_PROJECTS
LoadIntoProject ID_LOAD_INTO_PROJECTS_REBAR_SHAPE
RepeatComponent ID_REPEAT_COMPONENT
ConnectionSettings ID_STRUCTURAL_CONNECTION_SETTINGS
StructuralConnection ID_STRUCTURAL_CONNECTION_DIRECT_CREATION
ShowWarningsInViews ID_TOGGLE_STRUCTCONNECTIONS_SHOW_WARNINGS
ViewList ID_NEW_VIEWLIST
LinearDimensionTypes ID_SETTINGS_DIMENSIONS_LINEAR
AngularDimensionTypes ID_SETTINGS_DIMENSIONS_ANGULAR
SplitElement ID_SPLIT
SpotElevation ID_SPOT_ELEVATION
SpotCoordinate ID_SPOT_COORDINATE
AlignmentStation ID_ALIGNMENT_STATION_LABEL
AlignmentStationSet ID_ALIGNMENT_STATION_LABEL_SET
RoofByFootprint ID_ROOF_FOOTPRINT
RoofByExtrusion ID_ROOF_EXTRUSION
RadialDimensionTypes ID_SETTINGS_DIMENSIONS_RADIAL
ReloadLatest ID_WORKSETS_RELOAD_LATEST
Render ID_PHOTO_RENDERING_VIEW
ShowHistory ID_PARTITIONS_SHOW_HISTORY
SplitSurface ID_SPLIT_SURFACE
DrawOnFace 2706
DrawOnWorkPlane 2707
GrayInactiveWorksets ID_GRAY_INACTIVE_WORKSET_GRAPHICS
ImportGBXML ID_ABS_IMPORT_GBXML
ExportReportsRoomOrAreaReport ID_ROOM_AREA_REPORT
SheetIssuesOrRevisions ID_SETTINGS_REVISIONS
RevisionSchedule ID_VIEW_NEW_REVISION_SCHEDULE
CalloutTags ID_VIEWTAGSTYLES_CALLOUTTAGS
ElevationTags ID_VIEWTAGSTYLES_ELEVATIONTAGS
SectionTags ID_VIEWTAGSTYLES_SECTIONTAGS
FloorByFaceFloor ID_FLOOR_PICK_FACES
HideCategory ID_VIEW_HIDE_CATEGORY
RunInterferenceCheck ID_INTERFERENCE_CHECK
SpecifyCoordinatesAtPoint ID_SPECIFY_SHARED_COORDINATES
ExportIFC ID_EXPORT_IFC
SystemBrowser ID_RBS_SYSTEM_NAVIGATOR
ResetAnalyticalModel ID_RESET_ANALYTICAL_MODEL
ExportOptionsIFCOptions ID_IFC_OPTIONS
ExportDWFOrDWFx ID_EXPORT_DWF
ExportCADFormatsDWG ID_EXPORT_DWG
ExportCADFormatsDXF ID_EXPORT_DXF
ExportCADFormatsDGN ID_EXPORT_DGN
ExportCADFormatsACIS_SAT ID_EXPORT_SAT
ExportPDF ID_EXPORT_PDF
ExportCADFormatsSTL ID_EXPORT_STL
ExportCADFormatsOBJ ID_EXPORT_OBJ
OpenIFC ID_IMPORT_IFC
RelinquishAllMine ID_RELINQUISH_ALL_MINE
MaterialTakeoff ID_VIEW_NEW_MATERIAL_TAKEOFF
DWFMarkup ID_MARKUPS_LOAD
ImportTypes IDC_COMBOBOX_CONTROL
ExportExportTypes ID_EXPORT_FAM_TYPES
OpenIFCOptions ID_IFC_IMPORT_OPTIONS
CheckMemberSupports ID_COMMAND_CHECK_MEMBER_SUPPORTS
AnalyticalConsistencyChecks ID_COMMAND_ANALYTICAL_CONSISTENCY_CHECKS
KeynoteLegend ID_VIEW_NEW_KEYNOTE_LEGEND
KeynotingSettings ID_SETTINGS_KEYNOTING
OpenBuildingComponent ID_OPEN_ADSK
Web ID_TRUSS_WEB_CURVE
TopChord ID_TRUSS_TOP_CHORD_CURVE
BottomChord ID_TRUSS_BOTTOM_CHORD_CURVE
ShapeStatus ID_SHAPE_STATUS
TogglePropertiesPalette ID_TOGGLE_PROPERTIES_PALETTE
CoordinationModel ID_COORDINATION_MODEL
StatusBarWorksets ID_STATUSBAR_WORKSETS
StatusBarDesignOptions ID_STATUSBAR_DESIGNOPTIONS
ReinforcementNumbers ID_NUMBERING_REINF_PARTITIONS
FamilyCategoryAndParameters ID_OBJECTS_FAMILYHOST
ExportImagesandAnimationsWalkthrough ID_RM_ANIMATION
ExportImagesandAnimationsSolarStudy ID_FILE_EXPORT_SOLAR_STUDY
SunSettings ID_SETTINGS_SUNANDSHADOWSSETTINGS
Grid ID_OBJECTS_GRID
ArchitecturalWall ID_OBJECTS_WALL
Door ID_OBJECTS_DOOR
Window ID_OBJECTS_WINDOW
Delete ID_BUTTON_DELETE
Space ID_OBJECTS_MEP_SPACE
SpaceTag ID_OBJECTS_MEP_SPACE_TAG
SpaceSeparator ID_OBJECTS_MEP_SPACE_SEPARATION
TypeProperties ID_EDIT_TYPE
Level ID_OBJECTS_LEVEL
FramingElevation ID_BUTTON_BRACING_ELEVATION
ArchitecturalFloor ID_OBJECTS_FLOOR
Stair ID_OBJECTS_STAIRS
ArchitecturalColumn ID_OBJECTS_COLUMN
MirrorProject ID_MIRROR_PROJECT
RotateProjectNorth ID_ROTATE_PROJECT
Rotate ID_EDIT_ROTATE
MirrorPickAxis ID_EDIT_MIRROR
LineWeights ID_SETTINGS_PENS
ObjectStyles ID_SETTINGS_OBJECTSTYLES
AnalysisDisplayStyles ID_SETTINGS_ANALYSIS_DISPLAY_STYLES
Snaps ID_SETTINGS_SNAPPING
ProjectUnits ID_SETTINGS_UNITS
StructuralPlan ID_VIEW_NEW_STRUCTURAL_PLAN
FloorPlan ID_VIEW_NEW_PLAN
Section ID_VIEW_NEW_SECTION
Camera ID_VIEW_NEW_3DVIEW
ProjectBrowser ID_VIEW_PROJECTEXPLORER
NewSheet ID_VIEW_NEW_SHEET
ImportCAD ID_FILE_IMPORT
LinkCAD ID_FILE_CADFORMAT_LINK
PointCloud ID_POINT_CLOUD
NewFamily ID_FAMILY_NEW
LoadShapes ID_FAMILY_LOAD
NewConceptualMass ID_NEW_REVIT_DESIGN_MODEL
LoadAutodeskFamily ID_FAMILY_LOAD_CLOUD
Pin ID_LOCK_ELEMENTS
Walkthrough ID_VIEW_NEW_WALKTHROUGH
Unpin ID_UNLOCK_ELEMENTS
SolidExtrusion ID_OBJECTS_EXTRUSION
PlaceAComponent ID_OBJECTS_FAMSYM
ModelLine ID_OBJECTS_PROJECT_CURVE
StairPath ID_OBJECTS_STAIRS_PATH
ReferencePlane ID_OBJECTS_CLINE
Redo ID_BUTTON_REDO
Undo ID_BUTTON_UNDO
Control ID_OBJECTS_CONTROL
PickAPlane ID_PICK_WORKPLANE
Filters ID_SETTINGS_FILTERS
TemporaryDimensions ID_SETTINGS_DIMENSIONS
LinePatterns ID_SETTINGS_PEN_FONTS
Array ID_EDIT_CREATE_PATTERN
Move ID_EDIT_MOVE
Copy ID_EDIT_MOVE_COPY
PlaceView ID_VIEW_PLACE_VIEW
Text ID_OBJECTS_TEXT_NOTE
NewTitleBlock ID_TITLEBLOCK_NEW
AutomaticCeiling ID_OBJECTS_CEILING
FillPatterns ID_SETTINGS_FILLPATTERNS
Default3DView ID_VIEW_DEFAULT_3DVIEW
Label ID_OBJECTS_TAG_NOTE
VisibilityOrGraphics ID_VIEW_CATEGORY_VISIBILITY
Opening ID_OBJECTS_OPENING
NewProject ID_FILE_NEW_CHOOSE_TEMPLATE
ActivateView ID_VIEWPORT_ACTIVATE
Materials ID_SETTINGS_MATERIALS
DeactivateView ID_VIEWPORT_ACTIVATE_BASE
MaterialAssets ID_SETTINGS_RENDERING_APPEARANCE
DecalTypes ID_SETTINGS_DECAL_TYPES
Options ID_OPTIONS
Room ID_OBJECTS_ROOM
CurtainGrid ID_OBJECTS_CW_GRID
CurtainWallMullion ID_OBJECTS_MULLION
FamilyTypes ID_FAMILY_TYPE
FilledRegion ID_OBJECTS_FILLED_REGION
RoomTag ID_OBJECTS_ROOM_TAG
Align ID_ALIGN
Symbol ID_OBJECTS_FAM_ANN_INST
DuplicateView ID_PRJBROWSER_COPY
ExportOptionsExportSetupsDGN ID_SETTINGS_EXPORT_SETUPS_DGN
ExportOptionsExportSetupsDWGOrDXF ID_SETTINGS_EXPORT_SETUPS_DWGDXF
ColorFillLegend ID_OBJECTS_ROOM_FILL
BuildingElevation ID_BUTTON_INTERIOR_ROOM_ELEVATION
JoinOrUnjoinRoof ID_JOIN_ROOF
SolidBlend ID_OBJECTS_BLEND
ManageLinks ID_LINKED_DWG
SolidRevolve ID_OBJECTS_REVOLUTION
ScheduleOrQuantities ID_VIEW_NEW_SCHEDULE
Callout ID_VIEW_NEW_CALLOUT
SolidSweep ID_OBJECTS_SWEEP
CreateGroup ID_EDIT_GROUP
Ramp ID_OBJECTS_RAMP
RoomSeparator ID_OBJECTS_AREA_SEPARATION
AlignedToCurrentView ID_EDIT_PASTE_ALIGNED
AlignedToPickedLevel ID_EDIT_PASTE_ALIGNED_PICK_LEVEL
WallJoins ID_EDIT_WALL_JOINS
StartingView ID_STARTING_VIEW
AlignedToSelectedLevels ID_EDIT_PASTE_ALIGNED_LEVEL_BY_NAME
TagByCategory ID_BUTTON_TAG
AlignedToSelectedViews ID_EDIT_PASTE_ALIGNED_VIEWS_BY_NAME
LoadedTagsAndSymbols ID_SETTINGS_TAGS
NewAnnotationSymbol ID_ANNOTATION_SYMBOL_NEW
AlignedToSamePlace ID_EDIT_PASTE_ALIGNED_SAME_PLACE
SpotSlopeTypes ID_SETTINGS_SPOT_SLOPE
Arrowheads ID_SETTINGS_ANNOTATIONS_LEADERS
SpotElevationTypes ID_SETTINGS_SPOT_ELEVATION
SpotCoordinateTypes ID_SETTINGS_SPOT_COORDINATE
ReviewWarnings ID_REVIEW_WARNINGS
AlignmentStationLabelTypes ID_SETTINGS_ALIGNMENT_STATION_LABEL
LineStyles ID_SETTINGS_LINE_STYLES
ReflectedCeilingPlan ID_VIEW_NEW_RCP
DetailLevel ID_DETAIL_LEVEL
VoidExtrusion ID_OBJECTS_EXTRUSION_CUT
VoidBlend ID_OBJECTS_BLEND_CUT
VoidRevolve ID_OBJECTS_REVOLUTION_CUT
VoidSweep ID_OBJECTS_SWEEP_CUT
CutGeometry ID_CUT_HOST
UncutGeometry ID_UNCUT_HOST
PlaceDetailGroup ID_OBJECTS_PLACE_DETAIL_GROUP
OverrideByCategory ID_VIEW_OVERRIDE_CATEGORY
DetailComponent ID_OBJECTS_FAMDETAIL
DetailLine ID_OBJECTS_DETAIL_CURVES
Insulation ID_OBJECTS_INSULATION
CreateSimilar ID_EDIT_CREATE_SIMILAR
Worksets ID_SETTINGS_PARTITIONS
Phases ID_SETTINGS_PHASES
PropertyLine ID_SITE_PROPERTYLINE
BuildingPad ID_SITE_BUILDINGPAD
ImportImage ID_OBJECTS_RASTER
ImportPDF ID_OBJECTS_RASTER_PDF
MatchTypeProperties ID_EDIT_MATCH_TYPE
ScopeBox ID_VOLUME_OF_INTEREST
Linework ID_EDIT_LINEWORK
SetWorkPlane ID_SKETCH_PLANE_TOOL
DraftingView ID_VIEW_NEW_DRAFTING
Legend ID_VIEW_NEW_LEGEND
Demolish ID_EDIT_DEMOLISH
RevisionCloud ID_OBJECTS_CLOUD
SynchronizeAndModifySettings ID_FILE_SAVE_TO_CENTRAL
ProjectInformation ID_SETTINGS_PROJECT_INFORMATION
ModelInPlace ID_INPLACE_COMPONENT
SheetList ID_VIEW_NEW_DRAWING_LIST
AreaPlan ID_VIEW_NEW_AREASCHEME
GradedRegion ID_SITE_GRADE
Toposurface ID_SITE_TOPO_SURFACE
ManageImages ID_EDIT_RASTER_SYMBOLS
ApplyTemplatePropertiesToCurrentView ID_APPLY_VIEW_TEMPLATE
RevealWall ID_OBJECTS_REVEAL
SweepWall ID_OBJECTS_CORNICE
Paint ID_EDIT_PAINT
RemovePaint ID_EDIT_UNPAINT
NoteBlock ID_VIEW_NEW_NOTE_BLOCK
ModelText ID_OBJECTS_MODELTEXT
ShowHiddenLinesByElement ID_HIDE_ELEMENTS_EDITOR
RemoveHiddenLinesByElement ID_UNHIDE_ELEMENTS_EDITOR
ManageViewTemplates ID_SETTINGS_VIEWTEMPLATES
CreateTemplateFromCurrentView ID_CREATE_VIEW_TEMPLATE
SplitFace ID_SPLIT_FACE
RestoreBackup ID_FILE_BACKUPS
ExportODBCDatabase ID_FILE_EXPORT_ODBC
LoadAsGroup ID_LOAD_GROUP
SaveAsLibraryGroup ID_SAVE_GROUP
ParkingComponent ID_SITE_PARKING_COMPONENT
TransferProjectStandards ID_TRANSFER_PROJECT_STANDARDS
SymbolicLine ID_OBJECTS_VIEW_DIR_SPEC_CURVE
CutProfile ID_EDIT_CUT_BOUNDARY
ExportReportsSchedule ID_FILE_EXPORT_SCHEDULE
CloseInactiveViews ID_VIEW_CLOSE_INACTIVE
AreaTag ID_OBJECTS_AREA_TAG
AreaBoundary ID_OBJECTS_AREASCHEME_BOUNDARY
Area ID_OBJECTS_AREA
JoinGeometry ID_JOIN_ELEMENTS_EDITOR
UnjoinGeometry ID_UNJOIN_ELEMENTS_EDITOR
SwitchJoinOrder ID_SWITCH_JOIN_ORDER_EDITOR
TagAllNotTagged ID_BUTTON_TAG_ALL
MergeSurfaces ID_MERGE_SURFACE
SharedParameters ID_FILE_EXTERNAL_PARAMETERS
LegendComponent ID_OBJECTS_LEGEND_COMPONENT
Offset ID_OFFSET
PurgeUnused ID_PURGE_UNUSED
PlaceDecal ID_RM_CREATE_DECAL
TitleBlock ID_OBJECTS_PLACE_TITLEBLOCK
RebarLine ID_OBJECTS_REBAR_CURVE
LabelContours ID_SITE_LABEL_CONTOURS
SplitWithGap ID_SPLIT_WITH_GAP
ThinLines ID_THIN_LINES
LinkRevit ID_RVTDOC_LINK
ExportImagesandAnimationsImage ID_FILE_PRINT_TO_IMAGE
ProjectParameters ID_SETTINGS_PROJECT_PARAMETERS
RelocateProject ID_RELOCATE_SHARED_COORDINATES
RotateTrueNorth ID_ROTATE_SHARED_COORDINATES
DuplicateWithDetailing ID_DUPLICATE_WITH_DETAILING
Location ID_GEO_MANAGE_LOCATIONS
AcquireCoordinates ID_GEO_ACQUIRE_COORDINATES
ReportSharedCoordinates ID_REPORT_SHARED_COORDINATES
IdsOfSelection ID_IDS_OF_SELECTION
SelectById ID_SELECT_BY_ID
PublishCoordinates ID_GEO_PUBLISH_COORDINATES
ParametersService ID_SETTINGS_FORGE_PARAMETERS
PlanRegion ID_NEW_PLAN_REGION
BrowserOrganization ID_BROWSER_ORGANIZATION
Matchline ID_NEW_MATCHLINE
ViewReference ID_NEW_REFERENCE_VIEWER
DesignOptions ID_EDIT_DESIGNOPTIONS
AddToSet ID_EDIT_ADDTODESIGNOPTIONSET
PickToEdit ID_EDIT_PICKS_OPTION
EditingRequests ID_WORKSET_EDITING_REQUESTS
SaveAsLibraryFamily ID_SAVE_FAMILY_ANY
Subregion ID_SITE_AREA
Railing ID_OBJECTS_RAILING
Beam ID_OBJECTS_BEAM
Brace ID_OBJECTS_BRACE
StructuralColumn ID_OBJECTS_STRUCTURAL_COLUMN
StructuralWall ID_OBJECTS_STRUCTURAL_WALL
SpanDirectionSymbol ID_OBJECTS_SPAN_DIR_SYM
StructuralFloor ID_OBJECTS_SLAB
Scale ID_EDIT_SCALE
Loads ID_OBJECT_LOADS
StructuralSettings ID_STRUCTURAL_SETTINGS
ReferenceLine ID_OBJECTS_REFERENCE_CURVE
RebarCoverSettings ID_REBAR_COVER_SETTINGS
ShowMassFormAndFloors ID_SHOW_MASS_STANDARD
CurtainSystemByFace ID_CURTA_SYSTEM_PICK_FACES
WallByFaceWall ID_WALL_PICK_FACES
ShowMassByViewSettings ID_SHOW_MASS_NO_OVERRIDE
ShowMassSurfaceTypes ID_SHOW_MASS_SURFACES
ShowMassZonesAndShades ID_SHOW_MASS_ZONES
StructuralRebar ID_REBAR_PLACE
CopyMonitorUseCurrentProject ID_COPY_WATCH_CURRENT
CopyMonitorSelectLink ID_COPY_WATCH_LINK
CoordinationReviewUseCurrentProject ID_RECONCILE_CURRENT
CoordinationSelectLink ID_RECONCILE_LINK
Wall ID_OBJECTS_CONTINUOUS_FOOTING
Isolated ID_OBJECTS_ISOLATED_FOOTING
MaterialTag ID_TAG_MATERIAL
CoordinationSettings ID_COPY_SETTINGS
Slab ID_OBJECTS_FOOTING_SLAB
ElementKeynote ID_KEYNOTE_ELEMENT
MaterialKeynote ID_KEYNOTE_MATERIAL
UserKeynote ID_KEYNOTE_USER
LoadSelection ID_RETRIEVE_FILTERS
SaveSelection ID_FILTERS_SELECTION_SAVE
EditSelection ID_EDIT_SELECTIONS
ActivateControlsAndDimensions ID_TOGGLE_ACTIVATE_CONTROLS
ShowWorksharingMakeEditableControls ID_TOGGLE_SHOW_MAKE_ELEMENT_EDITABLE_CONTROLS
MultiCategoryTag ID_TAG_MULTI
BoundaryConditions ID_OBJECT_BC
StructuralPathReinforcement ID_PATH_REIN_SKETCH
PathReinforcementSymbol ID_OBJECTS_PATH_REIN_SPAN_SYM
OpeningByFace ID_CREATE_OPENING_BY_FACE_TB
VerticalOpening ID_CREATE_VERTICAL_OPENING_TB
DormerOpening ID_CREATE_DORMER_OPENING_TB
WallOpening ID_CREATE_WALL_OPENING_TB
ShaftOpening ID_CREATE_SHAFT_OPENING_TB
SpotSlope ID_SPOT_SLOPE
HideElements ID_VIEW_HIDE_ELEMENTS
ToggleRevealHiddenElementsMode ID_VIEW_FRAME_REVEALHIDDEN
OverrideByElement ID_VIEW_OVERRIDE_ELEMENTS
OverrideByFilter ID_VIEW_GO_FILTER
DuplicateAsDependent ID_CREATE_DEPENDENT_VIEW
MaskingRegion ID_MASKING_REGION
MajorSegment ID_MAJOR_SEGMENT
ReinforcementSettings ID_REBAR_ABBREVIATION
ExportFBX ID_EXPORT_FBX
OpenFamily ID_FAMILY_OPEN
CreateParts ID_CREATE_PARTS
ViewCube ID_SHOW_VIEWCUBE
BeamAnnotations ID_BEAM_ANNOTATION_PLACEMENT
AllowableBarTypes ID_REBAR_SHAPE_ALLOWABLE_BAR_TYPES
MacroManager ID_TOOLS_MACROS
MacroSecurity ID_TOOLS_MACROSECURITY
NavigationBar ID_NAVIGATION_BAR
FormWorkPlaneView ID_WORKPLANE_VIEW
ReconcileHosting ID_TOGGLE_HOST_BY_LINK_BROWSER
AdjustAnalyticalModel ID_AM_EDIT_MODE_START
DiameterDimension ID_ANNOTATIONS_DIMENSION_DIAMETER
DiameterDimensionTypes ID_SETTINGS_DIMENSIONS_DIAMETER
StructuralFabricArea ID_FABRIC_DISTR_SYSTEM_SKETCH
FabricReinforcementSymbol ID_FABRIC_SYSTEM_PLACE_SPANSYMBOL
PlaceOnStairOrRamp ID_OBJECTS_RAILING_ON_HOST
DuctPressureLossReport ID_MEP_DUCT_PRESSURE_LOSS_REPORT
PipePressureLossReport ID_MEP_PIPE_PRESSURE_LOSS_REPORT
OpenSampleFiles ID_SAMPLES_OPEN
SingleFabricSheetPlacement ID_FABRIC_SINGLE_PLACEMENT
AlignedMultiRebarAnnotation ID_MULTI_REFERENCE_ANNOTATION_ALIGNED
LinearMultiRebarAnnotation ID_MULTI_REFERENCE_ANNOTATION_LINEAR
FabricationSettings ID_MEP_FABRICATION_SETTINGS
LinkIFC ID_IFC_LINK
SelectionBox ID_VIEW_APPLY_SELECTION_BOX
StructuralRebarCoupler ID_REBAR_COUPLER
PAndIDModeler ID_MEP_PNID_MODELER
PAndIDSettings ID_MEP_PNID_SETTINGS
TogglePAndIDModelerBrowser ID_MEP_TOGGLE_PNID_BROWSER
DuctAccessory ID_RBS_MECHANICAL_ACCESSORY
AirTerminal ID_RBS_MECHANICAL_DIFFUSER
Duct ID_RBS_MECHANICAL_DUCT
MechanicalEquipment ID_RBS_MECHANICAL_EQUIPMENT
DuctFitting ID_RBS_MECHANICAL_FITTING
FlexDuct ID_RBS_MECHANICAL_FLEX
ConvertToFlexDuct ID_RBS_MECHANICAL_CONVERTTOFLEX
DuctLegend ID_RBS_MECHANICAL_COLOR_FILL
PanelSchedules ID_RBS_VIEW_PANEL_SCHEDULE
ElectricalSettings ID_RBS_ELECTRICAL_SETTINGS
LoadClassifications ID_RBS_ELECTRICAL_LOAD_CLASSIFICATION
LightingFixture ID_RBS_LIGHTING_FIXTURE
ElectricalEquipment ID_RBS_ELECTRICAL_EQUIPMENT
ElectricalFixture ID_RBS_ELECTRICAL_DEVICE
CheckCircuits ID_RBS_CHECK_CIRCUITS
DemandFactors ID_RBS_ELECTRICAL_DEMAND_FACTOR
Pipe ID_RBS_PIPE_PIPE
FlexPipe ID_RBS_PIPE_FLEX
PipeFitting ID_RBS_PIPE_FITTING
PipeAccessory ID_RBS_PIPE_ACCESSORY
ArcWire ID_RBS_ELECTRICAL_WIRE
PipeLegend ID_RBS_PIPING_COLOR_FILL
CheckPipeSystems ID_RBS_CHECK_PIPE_SYSTEMS
CheckDuctSystems ID_RBS_CHECK_DUCT_SYSTEMS
MechanicalSettings ID_RBS_MECHANICAL_SETTINGS
PlumbingFixture ID_RBS_PLUMBING_FIXTURE
Sprinkler ID_RBS_SPRINKLER
ElectricalConnector ID_RBS_ADD_ELECTRICAL_CONNECTOR
DuctConnector ID_RBS_ADD_DUCT_CONNECTOR
PipeConnector ID_RBS_ADD_PIPE_CONNECTOR
Zone ID_RBS_HVAC_ZONE
BuildingOrSpaceTypeSettings ID_RBS_BUILDINGSPACE_TYPE_SETTINGS
ChamferedWire ID_RBS_ELECTRICAL_WIRE_CHAMFER
SplineWire ID_RBS_ELECTRICAL_WIRE_SPLINE
Communication ID_RBS_ELECTRICAL_COMMUNICATION_DEVICE
Data ID_RBS_ELECTRICAL_DATA_DEVICE
FireAlarm ID_RBS_ELECTRICAL_FIREALARM_DEVICE
Lighting ID_RBS_ELECTRICAL_LIGHTING_DEVICE
NurseCall ID_RBS_ELECTRICAL_NURSECALL_DEVICE
Security ID_RBS_ELECTRICAL_SECURITY_DEVICE
Telephone ID_RBS_ELECTRICAL_TELEPHONE_DEVICE
CableTrayConnector ID_RBS_ADD_CABLETRAY_CONNECTOR
ConduitConnector ID_RBS_ADD_CONDUIT_CONNECTOR
CableTrayFitting ID_RBS_CABLETRAY_FITTING
ConduitFitting ID_RBS_CONDUIT_FITTING
CableTray ID_RBS_CABLE_TRAY
Conduit ID_RBS_CONDUIT
ManageTemplates ID_RBS_PANEL_SCHEDULE_MANAGE_TEMPLATES
EditATemplate ID_RBS_PANEL_SCHEDULE_EDIT_A_TEMPLATE
ParallelConduits ID_PARALLEL_CONDUIT
DuctPlaceholder ID_DUCT_1LINE_PATH
PipePlaceholder ID_PIPE_1LINE_PATH
ParallelPipes ID_PARALLEL_PIPES
ShowDisconnects ID_SHOWDISCONNECTS_BUTTON
MultiPointRouting ID_FABRICATION_PART_START_MPR
SystemZone ID_MEP_CREATE_SYSTEM_ZONE
SiteComponent ID_SITE_COMPONENT
AreaAndVolumeComputations ID_SETTING_AREACALCULATIONS
ShowWorkPlane ID_SKETCH_GRID_VIS
Fascia ID_CREATE_FASCIA_TB
Gutter ID_CREATE_GUTTER_TB
SlabEdgeFloor ID_CREATE_SLAB_EDGE_TB
CheckSpelling ID_CHECK_SPELLING
RepeatingDetailComponent ID_OBJECTS_REPEATING_DETAIL
InsertViewsFromFile ID_INSERT_VIEWS_FROM_FILE
Insert2DElementsFromFile ID_INSERT_2D_ELEMENTS_FROM_FILE
SaveAsLibraryView ID_SAVE_VIEWS_TO_FILE
AutomaticBeamSystem ID_OBJECTS_JOIST_SYSTEM
PlaceMass ID_OBJECTS_MASS
InPlaceMass ID_INPLACE_MASS
SynchronizeNow ID_FILE_SAVE_TO_CENTRAL_SHORTCUT
StructuralTrusses ID_OBJECTS_TRUSS
CreateAnAreaBasedLoad IDS_RBS_ANALYTICAL_LOADZONE
AreaBasedLoadBoundary ID_RBS_ANALYTICAL_AREA_BASED_LOAD_BOUNDARY
EquipmentLoad ID_RBS_ELECTRICAL_ANALYSIS_ADD_EQUIPMENT_LOAD
ShowBoundaryOpenEnds ID_RBS_SHOW_ABL_SEPARATION_LINE_OPEN_END
MechanicalControlDevice ID_RBS_MECHANICAL_CONTROL_DEVICE
PlumbingEquipment ID_RBS_PLUMBING_EQUIPMENT
HideBoundaryOpenEnds ID_RBS_HIDE_ABL_SEPARATION_LINE_OPEN_END
ShowLastReport ID_INTERFERENCE_REPORT
GraphicalColumnSchedule ID_VIEW_NEW_GRAPH_SCHED_COLUMN
ApplyCoping ID_COPING
RemoveCoping ID_UNCOPING
BeamSystemSymbol ID_OBJECTS_BEAM_SYSTEM_TAG
StructuralAreaReinforcement ID_REBAR_SYSTEM_SKETCH
AreaReinforcementSymbol ID_OBJECTS_REBAR_SYSTEM_SPAN_SYM
SolidSweptBlend ID_OBJECTS_SWEPTBLEND
VoidSweptBlend ID_OBJECTS_SWEPTBLEND_CUT
EditRebarCover ID_CONCRETE_COVER
ColorSchemes ID_SETTINGS_COLORFILLSCHEMES
CreateAnalyticalLink ID_CREATE_ANALYTICAL_LINK
TrimOrExtendToCorner ID_TRIM_EXTEND_CORNER
TrimOrExtendSingleElement ID_TRIM_EXTEND_SINGLE
TrimOrExtendMultipleElements ID_TRIM_EXTEND_MULTIPLE
AlignedDimension ID_ANNOTATIONS_DIMENSION_ALIGNED
LinearDimension ID_ANNOTATIONS_DIMENSION_LINEAR
AngularDimension ID_ANNOTATIONS_DIMENSION_ANGULAR
RadialDimension ID_ANNOTATIONS_DIMENSION_RADIAL
ArcLengthDimension ID_ANNOTATIONS_DIMENSION_ARCLENGTH
MeasureBetweenTwoReferences ID_MEASURE_LINE
MeasureAlongAnElement ID_MEASURE_PICK_LINES
MirrorDrawAxis ID_EDIT_MIRROR_LINE
KeyboardShortcuts ID_KEYBOARD_SHORTCUT_DIALOG
BeamOrColumnJoins ID_EDIT_BEAM_JOINS
SaveAsTemplate ID_REVIT_SAVE_AS_TEMPLATE
SaveAsFamily ID_REVIT_SAVE_AS_FAMILY
HalftoneOrUnderlay ID_SETTINGS_HALFTONE
Multiplanar ID_TURN_ON_MULTI_PLANAR_SHAPE
OpenProject ID_APPMENU_PROJECT_OPEN
LoadCases ID_STRUCTURAL_SETTINGS_LOAD_CASES
LoadCombinations ID_STRUCTURAL_SETTINGS_LOAD_COMB
BoundaryConditionsSettings ID_STRUCTURAL_SETTINGS_BOUND_COND
FindOrReplace ID_FIND_REPLACE
EnergySettings ID_CEA_VIEW_ENERGY_DATA
Generate ID_CEA_LAUNCH_ANALYSIS
ExportGBXML ID_EXPORT_GBXML
GuideGrid ID_CREATE_GUIDE_GRID
CreateAssembly ID_CREATE_ASSEMBLY
StairTreadOrRiserNumber ID_STAIRS_TRISER_NUMBER
ManageConnectionToARevitServerAccelerator ID_MANAGE_CONNECTION_TO_A_REVIT_SERVER_ACCELERATOR
RenderInCloud ID_PHOTO_RENDER_IN_CLOUD
RenderGallery ID_PHOTO_RENDER_GALLERY
CreateEnergyModel ID_ENABLE_ENERGY_ANALYSIS
DisplaceElements ID_DISPLACEMENT_CREATE
GlobalParameters ID_SETTINGS_GLOBAL_PARAMETERS
Collaborate ID_COLLABORATE
CollaborateInCloud ID_COLLABORATE_360
PublishSettings ID_VIEWS_FOR_A360
AssemblyCode ID_SETTINGS_ASSEMBLY_CODE
RevealObstacles ID_PATH_OF_TRAVEL_SHOW_OBSTACLES
PathOfTravel ID_PATH_OF_TRAVEL
MultipleValuesIndication ID_MULTIPLE_VALUES_INDICATOR_SETTINGS
MultiplePaths ID_MULTIPLE_PATHS
OneWayIndicator ID_ONE_WAY_INDICATOR
PeopleContent ID_PEOPLE_CONTENT
SpatialGrid ID_SPATIAL_GRID
LoadFamilyIntoProjectAndClose ID_LOAD_INTO_PROJECTS_CLOSE
FabricationPart ID_TOGGLE_FABPART_BROWSER
LoadRebarShapeIntoProjectAndClose ID_LOAD_INTO_PROJECTS_CLOSE_REBAR_SHAPE
Dynamo ID_VISUAL_PROGRAMMING_DYNAMO
DeleteEnergyModel ID_DISABLE_ENERGY_ANALYSIS
Shorten ID_CREATE_EXT_ENTITY_SHORTENING
CopeSkewed ID_CREATE_EXT_ENTITY_BEAM_COPE
CornerCut ID_CREATE_EXT_ENTITY_CORNER_CUT
Welds ID_CREATE_EXT_ENTITY_WELD
Plate ID_CREATE_EXT_ENTITY_PLATE
Bolts ID_CREATE_EXT_ENTITY_BOLT
Holes ID_CREATE_EXT_ENTITY_HOLE
Anchors ID_CREATE_EXT_ENTITY_ANCHOR
ShearStuds ID_CREATE_EXT_ENTITY_SHEAR_STUD
ContourCut ID_CREATE_EXT_ENTITY_CONTOUR
Cope ID_STEEL_PARAM_CUT_COPE
Miter ID_STEEL_PARAM_CUT_MITER
SawCutFlange ID_STEEL_PARAM_CUT_SAW_CUT_FLANGE
SawCutWeb ID_STEEL_PARAM_CUT_SAW_CUT_WEB
CutThrough ID_STEEL_PARAM_CUT_THROUGH
CutBy ID_STEEL_PARAM_CUT_BY
ToggleHome ID_REVIT_MODEL_BROWSER
SaveAsCloudModel ID_REVIT_FILE_SAVE_AS_CLOUD_MODEL
SystemsAnalysis ID_RUN_SYSTEMS_ANALYSIS
LinkPDF ID_LINK_PDF
LinkImage ID_LINK_IMAGE
AnalyticalMember ID_ANALYTICAL_MODEL_MEMBERS
BatchPrint ID_BATCH_PRINT
WorksharingMonitor ID_WORKSHARING_MONITOR
SharedViews ID_SHARED_VIEWS
ResetSharedCoordinates ID_RESET_SHARED_COORDINATES
ElectricalAnalyticalLoadTypeSettings ID_MEP_ELECTRICAL_ANALYSIS_SETTINGS
GenerateAnalysis ID_SYSTEMS_ANALYSIS_INSIGHT
ViewAnalysis ID_SYSTEMS_ANALYSIS_RESULTS_INSIGHT
OpenCloudModel ID_FILE_OPEN_CLOUD_MODEL
DynamoPlayerForSteel ID_STEEL_PLAYLIST_DYNAMO
PanelByBoundary ID_CREATE_ANALYTICAL_MODEL_PANEL
AnalyticalAutomation ID_ANALYTICAL_AUTOMATION_PLAYLIST_DYNAMO
PanelByExtrusion ID_CREATE_ANALYTICAL_MODEL_PANEL_BY_EXTRUSION
SpaceNaming ID_MEP_SPACE_NAMING_UTILITY
DynamoPlayer ID_PLAYLIST_DYNAMO
RepairCentralModel ID_REPAIR_CENTRAL_MODEL
LinkTopography ID_TOPOGRAPHY_LINK
Optimize ID_CEA_OPTIMIZE
OpenRevitFile ID_REVIT_FILE_OPEN
Close ID_REVIT_FILE_CLOSE
Save ID_REVIT_FILE_SAVE
SaveAsProject ID_REVIT_FILE_SAVE_AS
PrintSetup ID_REVIT_FILE_PRINT_SETUP
Print ID_REVIT_FILE_PRINT
PrintPreview ID_REVIT_FILE_PRINT_PREVIEW
CopyToClipboard ID_EDIT_COPY
CutToClipboard ID_EDIT_CUT
PasteFromClipboard ID_EDIT_PASTE
TabViews ID_VIEW_TAB
TileViews ID_WINDOW_TILE_VERT
ExitRevit ID_APP_EXIT
StatusBar ID_VIEW_STATUS_BAR
```
You can also get this list of all these commands by using
**pyRevit -> Spy -> List Elements -> System Postable Commands**


## How to Subscribe to Events Manually?
Lastly, here is an example on how to subscribe to events manually. pyRevit takes this step from us, and makes it even nicer to manage it in a folder. But you might want to know how it's used too.
You need to do the following steps:
1️⃣ Create a functions that will be subscribed to an event. I called it **import_replacement **in my example
2️⃣ Get Command Id with [**LookupCommandId**](https://rvtdocs.com/2023/da7c96b5-6347-d712-80ed-a5ae31291aa2)[ ](https://rvtdocs.com/2023/da7c96b5-6347-d712-80ed-a5ae31291aa2)or [**LookupPostableCommandId**](https://rvtdocs.com/2023/e5cb5335-70f7-3f74-2263-188847474335)
3️⃣ [**CreateAddInCommandBinding**](https://rvtdocs.com/2023/a9a2ddeb-f35c-de4f-55b2-83f6fdea7dae)
**4️⃣ **Now you can subscribe your function to this command. Make sure you select from [BeforeExecuted](https://rvtdocs.com/2023/1a0b276f-37f0-e800-e1a7-ecf4446c414f), [CanExecute](https://rvtdocs.com/2023/3601b61f-c546-13f3-4928-c0eec4c47b88), [Executed ](https://rvtdocs.com/2023/71c684fd-fc43-fadd-92f2-a7048c86d0fc)Events.
Here is an Example:
```python
# Imports
from Autodesk.Revit import UI
from Autodesk.Revit.DB import *
# .NET
import clr
clr.AddReference('System')
from System import EventHandler
# Define the function for EventTrigger
def import_replacement(sender, args):
TaskDialog.Show('Stop!', 'Do not import!')
# Main
uiapp = __revit__
commandId = UI.RevitCommandId.LookupCommandId("ID_FILE_IMPORT")
#commandId = UI.RevitCommandId.LookupPostableCommandId(POstableCommand.ImportCAD)
# Try to create a binding for the import command
try:
import_binding = uiapp.CreateAddInCommandBinding(commandId)
import_binding.BeforeExecuted += EventHandler[UI.Events.ExecutedEventArgs](import_replacement)
except:
import traceback
print(traceback.format_exc())
```
You can use **RevitPythonShell **to test it. But keep in mind that this event handler will work until you restart Revit or unsubscribe from an event. To unsubscribe from the event, you can use the same code and only change `+=` to **`-=`** like this:
`import_binding.Executed -= EventHandler[UI.Events.ExecutedEventArgs](eventhandler_file_import)`
### Happy Coding!
Congratulations!
You've just unlocked a new achievement and you can use pyRevit Hooks and Revit API Events!
### How to Place Views on Sheets with Revit API?
https://learnrevitapi.com/blog/how-to-place-views-on-sheets-with-python-and-revit-api/
## Intro
So, you might be wondering how to automate placing views on sheets in Autodesk Revit?
Sometimes that might be a very time-consuming task. But also, if you are into automation, there is a good chance that you created hundreds of views and now you need to place them on sheet.
That's exactly what we did in the previous lesson -[ ](https://learnrevitapi.com/blog/how-to-automate-window-sections-in-revit-api-and-python/)[**Stop Wasting your Time on Revit Sections. Automate with Revit API!**](https://learnrevitapi.com/blog/how-to-automate-window-sections-in-revit-api-and-python/)**. **
I showed you how to create hundreds of Elevations, Cross-Sections and Plans for all unique Window Types in the project.
And now we will continue and place all of them on individual sheets.
## 🧠Brainstorming
So how are we going to do that?
Let's brainstorm and write out all the steps we will go through in this lesson:
1️⃣ Get All Views + Filter
2️⃣ Sort Views for Placing on Sheets
3️⃣ Iterate and Create New Sheet
4️⃣ Place Views on Sheets
5️⃣ Handle Errors during placement (with **SubTransaction**)
6️⃣ Rename Sheets
Sounds like a lot of steps, but most of them will be short snippets.
So let's begin writing this code.
## 1️⃣ Get All Views
First of all, we are going to get all views in the project by using [**FilteredElementCollector**](https://rvtdocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3), and then we need to filter only the ones that we want to place on sheets.
In my case, it's quite simple. I gave them all a '**py_**' prefix when they were created with another script. So now I can easily grab them by checking if they have this prefix.
💡You might need to adjust this step to get views with your own logic! It depends on your view management.
```python
from Autodesk.Revit.DB import *
#📦 Variables
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type: Document
#📦 Get Views to Place
all_views = FilteredElementCollector(doc).OfClass(View).WhereElementIsNotElementType().ToElements()
views_to_place = [view for view in all_views if 'py_' in view.Name]
#👀 view_name_pattern = "py_X (Elevation) | py_X (Cross) | py_X (Plan)" # X - Unique Window Family_Type Name
```
📚 You Can Get [**FilteredElementCollector **](https://learnrevitapi.com/)[PDF Guide ](https://learnrevitapi.com/)with explanation and examples if you are new to this.
## 2️⃣ Sort Views based on Window Type
As I've mentioned earlier I am working with hundreds of Window sections.
There are 3 types of sections that I created in the [previous lesson](https://learnrevitapi.com/blog/how-to-automate-window-sections-in-revit-api-and-python/):
- Window Elevation
- Window Cross-Section
- Window Plan (Made with Section Too)
And they all have the same view name except for the suffix, which indicates which one of this is it.
It has the following naming pattern:
```python
plan_name = "py_X (Elevation)"
cross_name = "py_X (Cross)"
elevation_name = "py_X (Plan)"
#💡 X - means Unique Window Family_Type Name
```
Here is the Screenshot as well:

So it will be fairly easy to sort my views. But you might need to use different structure and logic, depending on how you organize your views in Revit!
I will use **defaultdict **with a nested dictionary for that! Keep in mind that this sorting method will only work if you have 3 sections for each of your windows! Otherwise, you need to ensure you have error handling as well.
Here is my desired output example
```python
#🎯 Desired Dict with Nested Dict Structure
dict_views = {'VIEW_NAME' : {'Plan': None,
'Elevation': None,
'Cross': None}
}
```
👇 And here is the Code Snippet to do that.
```python
#📦 Create defaultdict with nested dict as default value.
from collections import defaultdict
dict_views = defaultdict(dict)
#♻️ Sort Views by Window Types
for view in views_to_place:
try:
view_name = view.Name.replace('py_', '') # Remove _py from view name.
win_name = view_name.split(' (')[0] # Ensure '(' is only used in suffix.
if '(Plan)' in view.Name: dict_views[win_name]['Plan'] = view
elif '(Cross)' in view.Name: dict_views[win_name]['Cross'] = view
elif '(Elevation)' in view.Name: dict_views[win_name]['Elevation'] = view
except: pass
```
💡 Keep in mind that this step will be different because we probably name and organize our views differently.
👀 Also don't forget to preview if you get views correctly before going to the next step!
Here is my code snippet since I used dictionaries for collecting my views.
```python
#👀 Preview Results
for win_name, dict_win_views in dict_views.items():
print(win_name)
for view in dict_win_views.values():
print('- {}'.format(view.Name))
print('-'*50)
```
👀 And here is the Output.

## 3️⃣ Iterate and Create New Sheet
Next, let's iterate through these views and start creating new [**ViewSheets**](https://rvtdocs.com/2023/af2ee879-173d-df3a-9793-8d5750a17b49).
To create a new [**ViewSheet**](https://rvtdocs.com/2023/af2ee879-173d-df3a-9793-8d5750a17b49)** **we can use its [**Create **](https://rvtdocs.com/2023/bc9e8be3-f3fd-97c2-2709-1d6eea3db775)Method.
It takes 2 arguments:
- **Document**
- **TitleBlock.Id**
We always have **doc **variable and the easiest way to get default **TitleBlock is **by using [**doc.GetDefaultFamilyTypeId**](https://rvtdocs.com/2023/34d20683-dfea-b1f8-14cf-750611b218ed)
💡And since we are making a change to the project, we also need to use [**Transaction**](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd)**.**
We need to [Start ](https://rvtdocs.com/2023/1146fa87-127d-c432-0f51-79a5eb102031)and [Commit](https://rvtdocs.com/2023/32714010-7138-f64f-8fde-a310354448e3), and all changes have to be between these statements.
👉 I will also get my plan, elevation and cross-section from the dictionary so we can use it later on.
```python
# Get Default TitleBlock Id
def_title_block_id = doc.GetDefaultFamilyTypeId(ElementId(BuiltInCategory.OST_TitleBlocks))
#🔐 Start Transaction
t = Transaction(doc, 'New Sheet')
t.Start() # 🔓
#🪟 Iterate Through Window Views
for win_name, dict_win_views in dict_views.items():
#🪟 Get Plan/Cross/Elevation Views
plan = dict_win_views['Plan']
elev = dict_win_views['Elevation']
cros = dict_win_views['Cross']
#👀 Preview View Names
# print(plan.Name)
# print(elev.Name)
# print(cros.Name)
# print('-----')
new_sheet = ViewSheet.Create(doc, def_title_block_id)
t.Commit() # 🔒
```
⚠️ Keep in mind that we might not want to produce hundreds of sheets while we are in development stage.
So I will add a counter to my iteration and break out of the loop after I iterated 10 times like this:
```text
#🪟 Iterate Through Window Views
counter = 0 #⏱️ Counter Start
for win_name, dict_win_views in dict_views.items():
#... Create ViewsToSheets Code Here
#TODO 📛️ Temp Counter
counter +=1
if counter> 10:
break #FIXME: Limit to 1 item during Development
```
✅ Now we can test it and see if we create empty sheets for each iteration.
## 4️⃣ Place Views on Sheets
Now we will place views on sheets.
To place views on sheets we need to create a new instance of a [**Viewport**](https://rvtdocs.com/2023/5991dc40-234a-4835-cc06-07524d2e61a4). You can check its [**Create **](https://rvtdocs.com/2023/0f951f28-eb6b-2a37-668a-b248bfb7de97)method that has the following arguments:
- **Document**
- **Sheet.Id**
- **View.Id**
- **Location Point (XYZ)**
We already have the first 3, so we only need to define **Location Points** for our views.
To keep it simple, I will hardcode these values for views so they are always placed in the same location.
I've placed views manually on 1 sheet, and then looked in **RevitLookup **at [**Viewport.GetBoxCenter**](https://rvtdocs.com/2023/10a5ede6-0c97-79e0-a31a-2ffd90c7fc97) values.
And then here is how we can create our [**Viewports**](https://rvtdocs.com/2023/5991dc40-234a-4835-cc06-07524d2e61a4):
```python
#⏺️ Define Location for each plan
pt_plan = XYZ(-0.4, 0.3,0)
pt_elev = XYZ(-0.4,0.75,0)
pt_cros = XYZ(-0.15,0.75,0)
#🖼️ Create ViewPorts on ViewSheet
vp_plan = Viewport.Create(doc, new_sheet.Id, plan.Id, pt_plan)
vp_elev = Viewport.Create(doc, new_sheet.Id, elev.Id, pt_elev)
vp_cros = Viewport.Create(doc, new_sheet.Id, cros.Id, pt_cros)
print('✅ Placed 3 Views on a sheet[{}] for Window: {}'.format(new_sheet.Id, win_name))
```
👀 Let's test if we get any errors, and in my case I got an error that some sections couldn't be placed on the sheet. And it's because they are already placed! So we need to add some error handling here!
## 5️⃣ Handle Errors
I will use [**Viewport.CanAddViewToSheet**](https://rvtdocs.com/2023/1da33e38-255f-a27a-0626-9891d897b29a)** **method to test if view can be placed.
But it need **doc**, **view_sheet_id **and **view_id **arguments, so we need to create our sheet first.
I will use **SubTransaction **here.
This will allow me to
- Create the sheet
- Check if view can be placed, and **Commit SubTransaction **if it can.
- Or **Rollback **and undo creation of the sheet where we can't place any views.
💡 There are easier ways to handle this error, but I wanted to use **SubTransaction **here!
Here is the Code:
```python
# Start SubTransaction 🔓
# SubTransaction - Will allow creation of new Sections only if we can place Views there.
# Otherwise this step will be skipped for this iteration.
st = SubTransaction(doc)
st.Start()
#📰 Create ViewSheet (If Views aren't placed yet)
new_sheet = ViewSheet.Create(doc, def_title_block_id)
# Check if Views are placed
if Viewport.CanAddViewToSheet(doc, new_sheet.Id, plan.Id) and \
Viewport.CanAddViewToSheet(doc, new_sheet.Id, elev.Id) and \
Viewport.CanAddViewToSheet(doc, new_sheet.Id, cros.Id):
st.Commit()
# Show where views are already placed and skip iteration
else:
st.RollBack()
print('-'*50)
print('The following views are already Placed:')
print('Plan: SheetNumber:{}'.format(plan.get_Parameter(BuiltInParameter.VIEWER_SHEET_NUMBER).AsString()))
print('Elev: SheetNumber:{}'.format(elev.get_Parameter(BuiltInParameter.VIEWER_SHEET_NUMBER).AsString()))
print('Cross: SheetNumber:{}'.format(cros.get_Parameter(BuiltInParameter.VIEWER_SHEET_NUMBER).AsString()))
print('-'*50)
continue # Skip this For-Loop iteration
```
## 6️⃣ Rename Sheets
The last simple step is to rename our sheets.
It's very simple because we can write new values to [**SheetNumber **](https://rvtdocs.com/2023/5f9129ba-b323-c55d-e27e-46d88bec503b)and [**Name **](https://rvtdocs.com/2023/e372092e-ff47-71c2-1272-50ab08e5a41d)properties like this:
```python
#📝 Rename ViewSheet
try:
new_sheet.SheetNumber = 'Window - {}'.format(win_name)
new_sheet.Name = ''
except:
pass
```
## ✨Final Code
Lastly, let's put it all together in a single code, so you can easily copy and adjust it to your own needs!
```python
# -*- coding: utf-8 -*-
__title__ = "Tutorial Automate Views on Sheets"
__doc__ = """Date = 12.02.2024
_____________________________________________________________________
Description:
Tutorials on how to Place Views on New Sheets.
_____________________________________________________________________
Author: Erik Frits"""
#⬇️ IMPORTS
#--------------------------------------------------
from Autodesk.Revit.DB import *
#📦 VARIABLES
#--------------------------------------------------
doc = __revit__.ActiveUIDocument.Document #type: Document
# Global
default_title_block_id = doc.GetDefaultFamilyTypeId(ElementId(BuiltInCategory.OST_TitleBlocks))
#🎯 MAIN
#--------------------------------------------------
#📦 Get All Views + Filter
all_views = FilteredElementCollector(doc).OfClass(View).WhereElementIsNotElementType().ToElements()
views_to_place = [view for view in all_views if 'py_' in view.Name]
#♻️ Sort Views for Placing on Sheets
from collections import defaultdict
dict_views = defaultdict(dict)
#🎯 Desired Dict Structure
# dict_views = {'VIEW_NAME' : {'Plan': None,
# 'Elevation': None,
# 'Cross': None},
# }
# 👇 Sort Views to Place
for view in views_to_place:
try:
view_name = view.Name.replace('py_', '') #Remove py_ prefix
win_name = view_name.split(' (')[0]
if '(Plan)' in view.Name: dict_views[win_name]['Plan'] = view
elif '(Cross)' in view.Name: dict_views[win_name]['Cross'] = view
elif '(Elevation)' in view.Name: dict_views[win_name]['Elevation'] = view
except:
pass
#👀 Preview Results
# for win_name, dict_win_views in dict_views.items():
# print(win_name)
# for view in dict_win_views.values():
# print('- {}'.format(view.Name))
# print('-'*50)
#🔏 Transaction to Make changes
t = Transaction(doc, 'Create Window Sheets')
t.Start() #🔓
# 📰 Iterate and Create New Sheet
counter = 0
for win_name, dict_win_views in dict_views.items():
#🪟 Get Plan/Cross/Elevation Views
plan = dict_win_views['Plan']
elev = dict_win_views['Elevation']
cros = dict_win_views['Cross']
# ⚠️ Handle Errors during view placement (SubTransaction)
# SubTransaction Will allow creation of new Section only if we can place them
# Otherwise this step will be rollbacked for this iteration
st = SubTransaction(doc)
st.Start()
#📰 Create new ViewSheet
new_sheet = ViewSheet.Create(doc, default_title_block_id)
#💡 Check if possible to place views
if Viewport.CanAddViewToSheet(doc, new_sheet.Id, plan.Id) and \
Viewport.CanAddViewToSheet(doc, new_sheet.Id, elev.Id) and \
Viewport.CanAddViewToSheet(doc, new_sheet.Id, cros.Id):
st.Commit()
else:
st.RollBack()
print('❌ The following window sections already placed: {}'.format(win_name))
continue
# ⏺️ Define position for placing views
pt_plan = XYZ(-0.4, 0.3, 0)
pt_cros = XYZ(-0.15, 0.75, 0)
pt_elev = XYZ(-0.4, 0.75, 0)
# 🖼️ Place Views on Sheets
vp_plan = Viewport.Create(doc, new_sheet.Id, plan.Id, pt_plan)
vp_cros = Viewport.Create(doc, new_sheet.Id, cros.Id, pt_cros)
vp_elev = Viewport.Create(doc, new_sheet.Id, elev.Id, pt_elev)
print('✅ Created New Sheet for Window: {}'.format(win_name))
# 📝 Rename Sheets
try:
new_sheet.SheetNumber = 'Window - {}'.format(win_name)
new_sheet.Name = ''
except:
pass
# # 📛️ Temp Counter
# counter +=1
# if counter > 10:
# break
t.Commit() #🔒
#--------------------------------------------------
# 🎯 And this will create Hundreds of New Sheets for our Window Sections!
```
## ⌨️Happy Coding!
### Stop Wasting your Time on Revit Sections. Automate with Revit API!
https://learnrevitapi.com/blog/how-to-automate-window-sections-in-revit-api-and-python/
## Intro
Creating sections in Autodesk Revit is boring, and adjusting them to see only the correct elements is even worse! So let me help you with this problem.
In this video I will show you how to automate section creation with Revit API + python. And by the end of this lesson you will learn how to create a custom add-in to automate sections for windows. This will allow you to create multiple sections for your windows with a click of a button.
It will include:
- Elevation Section
- Cross Section
- Plan View (Made with section. Yes, we can rotate sections to act like plans 😉)
And the best part - You will understand the steps it takes to create and rotate sections correctly to apply for any other category in Revit. So you will be able to automate not only sections for windows but also for other elements you have in mind.
So let's begin this lesson 🥳!
## ✂️ How to Create a Section
First of all we need to check Revit API documentation to see what's necessary to create a [**ViewSection**](https://rvtdocs.com/2023/fcc75682-bd99-a97d-5a4d-0f8eb9e92ab5).
Here is the [**CreateSection **](https://rvtdocs.com/2023/d6228f68-3643-8aaf-72bb-f9a0b4125886)method and we need 3 arguments:
- **document **- Represents Revit Project
- **viewFamilyTypeId **- Element Id of a SectionType
- **sectionBox **- 3D BoundingBox that represents the section

So in the end we will need to use it like this with python:
```text
new_section = ViewSection.CreateSection(doc, section_type_id, section_box)
```
👀 The first 2 arguments are easy to get, but the 3rd one will involve multiple steps. So let's brainstorm together.
## 🧠Brainstorm the Steps
Now, before we begin coding, we need to understand what are the steps to create sections for each window. The main focus will be on creating a **Section Box, **because not only we need to make it in the right location with the right size, we also need to rotate it to match the wall direction.
Let's brainstorm together and write out all the steps:
📃 Check Docs how to create Section
🪟 Get and Sort Windows of Each Type
1️⃣ Get Window Origin Point
2️⃣ Get Vector to match Host Wall Location
3️⃣ Get Window Sizes
4️⃣ Create Transform (Location Point + XYZ Vectors)
5️⃣ Create SectionBox
6️⃣ Create ViewSection
7️⃣ New Section View Naming
8️⃣ Transaction to make changes
9️⃣ Simple Error Handling
And most importantly:
- **⌨️ Happy Coding!**
It's a big lesson, but it's a certainly the one that is worth going through!
## 🐍Template
To use Revit API with python we will need to use **pyRevit**.
If you are new to this, make sure you check my free lessons on setting up your development environment here:
### [👉 How To Setup Developemnt Environment for Revit API + Python?](https://learnrevitapi.com/)
[Lesson 1 - What is Revit API](https://learnrevitapi.com/)
[Lesson 2 - Install Revit Plugins](https://learnrevitapi.com/)
[Lesson 3 - Setup Revit API Autocomplete in VS Code](https://learnrevitapi.com/)
[Lesson 4 - Create YOUR OWN Extension with pyRevit](https://learnrevitapi.com/)
[Lesson 5 - pyRevit Script Anatomy](https://learnrevitapi.com/)
[Lesson 6 - How to Reuse code in pyRevit](https://learnrevitapi.com/)
[Lesson 7 - pyRevit vs Dynamo](https://learnrevitapi.com/)
These lessons should help you get started with Revit API to create your own custom tools.
And now let's continue with automating sections.
## 🪟 Get & Sort Windows
First of all we need to get window instances of each type. This step can be done in a lot of different ways.
I will keep it simple and get all window instances with [FilteredElementCollector ](https://rvtdocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3)Class. And then we will iterate and create a dictionary where we will combine Family and Type names for a key, and place the window instance as a value itself.
Also, keep in mind that windows can be made with different family templates. So I want to filter windows that are hosted in a Wall. This will make it much easier to work with, and ensure I create my sections correctly.
For that I will use [**Host **](https://rvtdocs.com/2023/69f30141-bd3b-8bdd-7a63-6353d4d495f9)property and check the type of a host. And if it's not a [**Wall**](https://rvtdocs.com/2023/b5891733-c602-12df-beab-da414b58d608), I will make a print statement to notify user that certain windows are not wall hosted.
Once you get your elements, make a test print statement to ensure you get elements.
```python
#👉 Get and Sort Window Instances of Each Type
windows = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).WhereElementIsNotElementType().ToElements()
dict_windows = {}
for win in windows:
family_name = win.Symbol.Family.Name
type_name = Element.Name.GetValue(win.Symbol)
key_name = '{}_{}'.format(family_name, type_name)
host = win.Host
if type(host) == Wall:
if key_name not in dict_windows:
dict_windows[key_name] = win
else:
print('Unsupported Host for Window: {} [{}]'.format(key_name, win.Id))
# #👀 Preview Dict Windows
for k,v in dict_windows.items():
print(k,v)
```
## 1️⃣ Get Window Origin
Now, we can start iterating through all these windows and get more information from them for our section boxes.
First of all we need to get window's origin point. And it's very simple to do!
Since all our windows are hosted in walls, we can use [**Location.Point**](https://rvtdocs.com/2023/8d81892a-7863-cbec-9148-a0311f3bf2b6) property to get a point.
```python
for window_name, window in dict_windows.items():
#1️⃣ Get Window Origin Point
win_origin = window.Location.Point #type: XYZ
```
## 2️⃣ Get Vector of Host Wall
Next, let's create a vector to match wall's direction. This will be necessary for rotating our section correctly.
First of all we can get our wall by using [**Host **](https://rvtdocs.com/2023/69f30141-bd3b-8bdd-7a63-6353d4d495f9)property.
Then we will get the curve that is used with [**Location.Curve.**](https://rvtdocs.com/2023/b03df3be-687a-2ac8-e28d-2e038ecac142)
And by using [**GetEndPoint **](https://rvtdocs.com/2023/a02da994-2976-38c0-e16b-20292de9fe57)method we can get **Start/End Points**.
Once you have points, creating a vector is simple. Just subtract these points and it will result in a vector between them.
This vector will be used for setting up XYZ axis of the [Transform ](https://rvtdocs.com/2023/58dd01c8-b3fc-7142-e4f3-c524079a282d)in a moment.

👇 Here is the Snippet on how to do all that:
```python
#2️⃣ Calculate Vector based on the Wall
host_wall = window.Host
curve = host_wall.Location.Curve #type: Curve
pt_start = curve.GetEndPoint(0) #type: XYZ
pt_end = curve.GetEndPoint(1) #type: XYZ
vector = pt_end - pt_start #type: XYZ
```
## 3️⃣ Get Window Sizes
Now let's think about how we are going to create a SectionBox with the correct size.
We can look at the window's Height and Width parameters and add a little offset to see around the window as well.
**NB! - It's important that you adjust parameters to your projects!**
I use windows from Autodesk German library of windows. They are really good and consistent.
I need to look at default **'Width'** and **'Height'** parameters in Window Types.
They have [**BuiltInParameter**](https://rvtdocs.com/2023/fb011c91-be7e-f737-28c7-3f1e1917a0e0)[ ](https://rvtdocs.com/2023/fb011c91-be7e-f737-28c7-3f1e1917a0e0)names: **GENERIC_WIDTH **and **CASEWORK_HEIGHT.**
💡Also some windows don't use that parameter!
Instead, they have a custom parameter called `'Höhe ab FBOK`, which means '**Height above Floor Finish'.**
So I will also make an if statement and use that parameter when regular **Height **returns **0** and **None**.
And I will manually define the depth of the box (which represents how far section looks) and the offset. I work in metric system so I also need to convert units to feet, because **REVIT API USES FEET BY DEFAULT!**
For that I will use [ConvertToInternalUnits ](https://rvtdocs.com/2023/b5e8d065-d274-62f8-7b5d-89722f7c44f3)method from [**UnitUtils **](https://rvtdocs.com/2023/128dd879-fea8-5d7b-1eb2-d64f87753990)Class.
```python
#3️⃣ Get Window Size
win_width = window.Symbol.get_Parameter(BuiltInParameter.GENERIC_WIDTH).AsDouble()
cm_40 = UnitUtils.ConvertToInternalUnits(40, UnitTypeId.Centimeters) #40cm (Revit API takes unit in FEET!)
win_depth = cm_40
offset = cm_40
win_height = window.Symbol.get_Parameter(BuiltInParameter.CASEWORK_HEIGHT).AsDouble() # ADJUST TO YOUR PARAMETERS!
if not win_height:
win_height = window.Symbol.LookupParameter('Höhe ab FBOK').AsDouble() # ADJUST TO YOUR PARAMETERS!
```
💡 [**UnitTypeId **](https://rvtdocs.com/2023/bc1b6454-f10a-66dc-9268-1dccbc403f78)is used for converting in Revit 2022+. Before that we used [DisplayUnitType ](https://rvtdocs.com/2021/7d3d3306-a4c2-c577-0aeb-cca42d6cfd2f)Enumeration.
## 4️⃣ Create Transform (Origin + XYZ Vectors)
Now we going to make the trickiest step of all. We need to create a [**Transform**](https://rvtdocs.com/2021/58dd01c8-b3fc-7142-e4f3-c524079a282d)[.](https://rvtdocs.com/2021/58dd01c8-b3fc-7142-e4f3-c524079a282d)
It's a bit confusing first time you use it. But once you understand it, it's fairly simple.
This step is all about defining Origin point and XYZ vectors for rotation. And keep in mind that we can rotate our vectors in any direction we want. We are not limited to use Z axis as vertical! So let's break all the steps.
First of all we need to create an instance of [**Transform**](https://rvtdocs.com/2021/58dd01c8-b3fc-7142-e4f3-c524079a282d)** **by using [Identity ](https://rvtdocs.com/2021/2eb2a180-c7ef-a0c0-0fa4-baef2901c351)property. (it's a common way across many 3D software to use property instead of constructor or method..)
Then defining a point is simple, we just write a value to [Origin ](https://rvtdocs.com/2021/e861b86d-b8ef-6978-3c78-1ff297e512ff)property.
Now not so fun part - Vectors. We need to define [BasisX](https://rvtdocs.com/2021/00944fa6-49d9-4564-9f55-c0f71fa14706), [BasisY ](https://rvtdocs.com/2021/dfae1c2b-d0fd-0b56-3610-b7055f4169d3)and [BasisZ](https://rvtdocs.com/2021/f0a5bbf5-41f2-ec36-80c4-207e9bae36d9) vectors.
First try to imagine 3 vectors that are perpendicular to each other. Like Transform Gizmo(👇)

```python
# 🪟 TRANSFORMATION - ELEVATION SECTION
# 4️⃣🅰️ Create Transform (Origin point + X,Y,Z Vectors)
# TRANSFORMATION - ELEVATION
trans = Transform.Identity # Create Instance of Transform
trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
vector = vector.Normalize() # * -1/1 Multiply Vector to flip Section if necessary!
trans.BasisX = vector
trans.BasisY = XYZ.BasisZ
trans.BasisZ = vector.CrossProduct(XYZ.BasisZ) #The cross product is defined as the vector which is perpendicular to both vectors
```
👀 Watch this short explanation for XYZ Vectors.
💡 Also it's important that we can invert our vectors by multiplying by -1. `(vector * -1)`
This means that we can Flip the axis of our section like this. Check the full video to see an example 😉
## Transform - Cross Section
Here is an alternative of Transform for CrossSection.
If you think about it we just need to change X and Z axis that we used before.
Because our X used to go along the wall, now it should be perpendicular.
And the Z used to be perpendicular and now should go along the wall.
And since Y stays vertical we can use it for calculating cross product of other vectors!
```python
#🪟 TRANSFORMATION - CROSS SECTION
#4️⃣🅱️ Create Transform (Origin point + X,Y,Z Vectors)
trans = Transform.Identity # Create Instance of Transform
trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
vector = vector.Normalize() # * -1/1 Multiply Vector to flip Section if necessary!
vector_cross = vector.CrossProduct(XYZ.BasisZ)
trans.BasisX = vector_cross
trans.BasisY = XYZ.BasisZ
trans.BasisZ = vector_cross.CrossProduct(XYZ.BasisZ)
```
## Transform - ViewPlan
⚠️ I noticed too late that in my video I made my **ViewPlan **section to look up and not down…
So it means that we need to invert a vector. In my case I inverted **BasisZ **vector, and I also need it inverted during calculation of **BasisY.**
Overall it's the same logic as before. We need to define our **XYZ **vectors to rotate our box correctly, and in the end we will see whatever the box is cutting through 😉
I also included Create **SectionBox**, because we need to modify Z values for **Min **and **Max **so we are actually cutting through the window at the correct location.
```python
#🪟 TRANSFORMATION - SECTION PLAN
#4️⃣©️ Create Transform (Origin point + X,Y,Z Vectors)
trans = Transform.Identity # Create Instance of Transform
trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
# Create Transform for PlanSection (XYZ Vectors) 🤦♂️ Yes, Section can be used to look down like Plans...
vector = vector.Normalize()
trans.BasisX = vector
trans.BasisY = -XYZ.BasisZ.CrossProduct(vector).Normalize()
trans.BasisZ = -XYZ.BasisZ
# ==================================================
#5️⃣ Create SectionBox
section_box = BoundingBoxXYZ() # origin 0,0,0
half = win_width/2
section_box.Min = XYZ(-half - offset , 0 - offset , -win_depth)
section_box.Max = XYZ(half + offset , win_height + offset , win_depth*2)
#💡 XYZ(X - Left/Right , Y - Up/Down , Z - Forward/Backwards)
```
## 5️⃣ Create SectionBox
Now we have everything to create a **SectionBox **by using [**BoundingBoxXYZ **](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2)Class.
I will continue here in the written lesson by creating only Elevation, and you can adjust the rest like in a video yourself 😉.
But keep in mind that when you create you [**BoundingBoxXYZ **](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2), it has its origin at [**XYZ**](https://rvtdocs.com/2023/c2fd995c-95c0-58fb-f5de-f3246cbc5600)(0,0,0). And we can change the size by using [Min](https://rvtdocs.com/2023/608e6914-2465-b572-2c5d-2a6cd696c740)/[Max](https://rvtdocs.com/2023/b79bd9ee-ccff-cc81-8a32-9eb9bdb1e58c) properties. And we can use Positive and Negative values to move in opposite directions from origin point.
**X - Left/Right**
**Y - Up/Down**
**Z - Forward/Backwards**
💡 It will also depend on how you rotate your box with Transform that we created earlier. Since we defined BasisY as Vertical Axis, and X as the vector along the wall, these are the directions that section box will affect. If we would change axis, then we would need to address it here as well!
Don't forget to add offset here.
Once you create a box with the right size, we can apply transformation by using [**Transform **](https://rvtdocs.com/2023/58dd01c8-b3fc-7142-e4f3-c524079a282d)property.
```python
#5️⃣ Create SectionBox
section_box = BoundingBoxXYZ() # origin 0,0,0
half = win_width/2
section_box.Min = XYZ(-half - offset , 0 - offset , -win_depth)
section_box.Max = XYZ(half + offset , win_height + offset , win_depth)
#💡 XYZ(X - Left/Right , Y - Up/Down , Z - Forward/Backwards)
section_box.Transform = trans # Apply Transform (Origin + XYZ Vectors)
```
## 6️⃣ Create Section View
Now we are ready to create our first section - Elevation.
As you remember we needed: **document**, **section_type_id **and **section_box.**
The only missing thing is the Id of a **ViewTypeSection**. And we can easily get it by using [**GetDefaultElementTypeId.**](https://rvtdocs.com/2023/b62f6563-aca4-56dc-4697-7717932187b3)
So here is the final snippet:
```python
#6️⃣ Create Section View
section_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeSection)
window_elevation = ViewSection.CreateSection(doc, section_type_id, section_box)
```
By now we have all the main steps for creating a section, however we are not done yet!
## 7️⃣ Section Naming
Let's also name our newly created sections correctly.
I will use the name we created in a dictionary, where we combined Family + Type name.
Also I will create a loop with try/except statement, so in case a view with the same name already exists, I will add '*' symbol in the end and try again for 10 times.
Many will prefer to use **while **loop here, but I hate them. You always at a risk to end up with an infinite loop, and then you will crash your Revit. So I stick with for loops instead!
```python
# 7️⃣ New Name
new_name = 'py_{} (Plan)'.format(window_name)
for i in range(10):
try:
window_elevation.Name = new_name
print('✅ Created Section: {}'.format(new_name))
break
except:
new_name += '*'
```
## 8️⃣ Transaction + Basic Error Handling
And the very last step is to add [Transaction](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd).
As you know, we can't make any changes to our project with Revit API, unless we are using [Transaction](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd).
It's like a guardian of our projects, to make sure that all changes happen intentionally, so we don't accidentally break something. We just need to Start and Commit the Transaction. And all the changes have to be in between, so make sure you start before and commit after you create your sections.
```python
#🔏 Create Transaction to Modify Project
t = Transaction(doc, 'Generate Window Sections')
t.Start() #🔓
# Changes Here...
t.Commit() # 🔒
```
And additionally, we can introduce **Try/Except** to avoid crashing our script due to exception cases. This is always good to have.
```python
#🎯 Create Section
for window_name, window in dict_windows.items():
try:
#🎯 Main Code Here...
except:
import traceback
print('---\n❌ERROR:')
print(traceback.format_exc())
```
## ✨Results
At last we made sections for all our window types!
So far we only made Elevation section.
However, as I showed in the video, by adjusting Transform a little, we will be able to create Cross and Plan sections as well!
And you can combine all of this to create all 3 sections for your windows with a single click!
Happy Coding!

## 💻Final Code
Lastly, let's put it all together into a single snippet👀
I know it was a huge lesson, but I am sure it was totally worth it!
Here is the final code Snippet to Automate your Sections for Windows:
```text
# -*- coding: utf-8 -*-
__title__ = "Tutorial Automate Sections"
__doc__ = """Date = 30.01.2024
_____________________________________________________________________
Description:
Tutorial on how to Create Sections for all Window Types.
- Elevation Section
- Cross Section
- Plan Section (Yes, we can create PlansViews with sections)
_____________________________________________________________________
Author: Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from pyrevit import forms
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type: Document
app = __revit__.Application
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
#==================================================
#👉 Get and Sort Window Instances of Each Type
windows = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).WhereElementIsNotElementType().ToElements()
dict_windows = {}
for win in windows:
family_name = win.Symbol.Family.Name
type_name = Element.Name.GetValue(win.Symbol)
key_name = '{}_{}'.format(family_name, type_name)
host = win.Host
if type(host) == Wall:
dict_windows[key_name] = win
else:
print('Unsupported Host for Window: {} [{}]'.format(key_name, win.Id))
# #👀 Preview Dict Windows
# for k,v in dict_windows.items():
# print(k,v)
#🔏 Create Transaction to Modify Project
t = Transaction(doc, 'Generate Window Sections')
t.Start() #🔓
#🎯 Create Section
for window_name, window in dict_windows.items():
try:
#1️⃣ Get Window Origin Point
win_origin = window.Location.Point #type: XYZ
#2️⃣ Calculate Vector based on the Wall
host_wall = window.Host
curve = host_wall.Location.Curve #type: Curve
pt_start = curve.GetEndPoint(0) #type: XYZ
pt_end = curve.GetEndPoint(1) #type: XYZ
vector = pt_end - pt_start #type: XYZ
#3️⃣ Get Window Size
win_width = window.Symbol.get_Parameter(BuiltInParameter.GENERIC_WIDTH).AsDouble()
cm_40 = UnitUtils.ConvertToInternalUnits(40, UnitTypeId.Centimeters) #40cm (Revit API takes unit in FEET!)
win_depth = cm_40
offset = cm_40
win_height = window.Symbol.get_Parameter(BuiltInParameter.CASEWORK_HEIGHT).AsDouble() # ADJUST TO YOUR PARAMETERS!
if not win_height:
win_height = window.Symbol.LookupParameter('Höhe ab FBOK').AsDouble() # ADJUST TO YOUR PARAMETERS!
# ╔╦╗╦═╗╔═╗╔╗╔╔═╗╔═╗╔═╗╦═╗╔╦╗
# ║ ╠╦╝╠═╣║║║╚═╗╠╣ ║ ║╠╦╝║║║
# ╩ ╩╚═╩ ╩╝╚╝╚═╝╚ ╚═╝╩╚═╩ ╩
# ==================================================
# 🪟 TRANSFORMATION - ELEVATION SECTION
# 4️⃣🅰️ Create Transform (Origin point + X,Y,Z Vectors)
# TRANSFORMATION - ELEVATION
trans = Transform.Identity # Create Instance of Transform
trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
vector = vector.Normalize() # * -1/1 Multiply Vector to flip Section if necessary!
trans.BasisX = vector
trans.BasisY = XYZ.BasisZ
trans.BasisZ = vector.CrossProduct(XYZ.BasisZ) #The cross product is defined as the vector which is perpendicular to both vectors
# ==================================================
#🪟 TRANSFORMATION - CROSS SECTION
#4️⃣🅱️ Create Transform (Origin point + X,Y,Z Vectors)
# trans = Transform.Identity # Create Instance of Transform
# trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
#
# vector = vector.Normalize() # * -1/1 Multiply Vector to flip Section if necessary!
#
# vector_cross = vector.CrossProduct(XYZ.BasisZ)
#
# trans.BasisX = vector_cross
# trans.BasisY = XYZ.BasisZ
# trans.BasisZ = vector_cross.CrossProduct(XYZ.BasisZ)
# ==================================================
# #🪟 TRANSFORMATION - SECTION PLAN
# #4️⃣©️ Create Transform (Origin point + X,Y,Z Vectors)
# trans = Transform.Identity # Create Instance of Transform
# trans.Origin = win_origin # Set Origin Point (Window Insertion Point)
#
# # Create Transform for PlanSection (XYZ Vectors) 🤦♂️ Yes, Section can be used to look down like Plans...
# vector = vector.Normalize()
# trans.BasisX = vector
# trans.BasisY = -XYZ.BasisZ.CrossProduct(vector).Normalize()
# trans.BasisZ = -XYZ.BasisZ
# ==================================================
#5️⃣ Create SectionBox
section_box = BoundingBoxXYZ() # origin 0,0,0
half = win_width/2
section_box.Min = XYZ(-half - offset , 0 - offset , -win_depth)
section_box.Max = XYZ(half + offset , win_height + offset , win_depth)
#💡 XYZ(X - Left/Right , Y - Up/Down , Z - Forward/Backwards)
section_box.Transform = trans # Apply Transform (Origin + XYZ Vectors)
#6️⃣ Create Section View
section_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeSection)
window_elevation = ViewSection.CreateSection(doc, section_type_id, section_box)
# 7️⃣ New Name
new_name = 'py_{} (Plan)'.format(window_name)
for i in range(10):
try:
window_elevation.Name = new_name
print('✅ Created Section: {}'.format(new_name))
break
except:
new_name += '*'
except:
import traceback
print('---\n❌ERROR:')
print(traceback.format_exc())
t.Commit() # 🔒
```
## 🧙♂️You are a Legend!
🙌Listen, if you are reading this, then you are certainly decided on making it work in your project!
🙏 I hope you won't have major issues and I would highly appreciate if you would share this lesson with others, so they also automate that boring step in their work!
📶 Feel free to post your results in LinkedIn and tag me along([**Erik Frits**](https://www.linkedin.com/in/erik-frits/)), so I can see how much it helped you and what you managed to achieve!
💟 Now I wish you all the best in your coding journey with Revit API.
-Erik Frits
P.S.
Help me spread the word 😉
### How To Get Material Layers from Wall, Floors and Roofs
https://learnrevitapi.com/blog/how-to-get-material-layers-from-wall-types/
## How to Get Material Layers?
Since you are here, probably you are wondering:
"How do you get **Material Layers **of our **WallType**, **FloorType**, **RoofType **and **CeilingType**?".
Well, I'm glad you asked!
I will explain everything on an example of **WallTypes**, and the similar logic will apply to other elements.
First of all, let's think of Revit UI functionality to access this information.
## 💡Brainstorming
You can use Revit Lookup to inspect your elements until you find layers. You can follow this path:
`Wall -> WallType -> `[`GetCompoundStructure`](https://rvtdocs.com/2023/a1ec47e5-c552-944d-2152-74d7bd3f2a31)` -> `[`GetLayers`](https://rvtdocs.com/2023/105b59e9-9cea-1988-a5a7-cc9cde49145c)` -> `[`MaterialId`](https://rvtdocs.com/2023/c5a502aa-217c-b76b-b1ad-33f57cc7b24d)
Overall it's not complicated, but let's explore a few details.
💡Here is the pyRevit Template I will begin with.
```python
# -*- coding: utf-8 -*-
__title__ = "Read Wall Layers"
__doc__ = """Version = 1.0
Date = 25.01.2024
_____________________________________________________________________
Description:
Learn How to Get Material Layers?
_____________________________________________________________________
Author: Erik Frits"""
#⬇️ Imports
from Autodesk.Revit.DB import *
#📦 Variables
doc = __revit__.ActiveUIDocument.Document #type: Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
```
## 1️⃣Select Elements
First of all we need some Wall elements. You probably already have a code snippet where you get them, but I will leave a snippet for others to use:
```python
from Autodesk.Revit.UI.Selection import Selection, ObjectType
selection = uidoc.Selection #type: Selection
#👉 Get Current Selection
selected_el_ids = selection.GetElementIds()
selected_el = [doc.GetElement(e_id) for e_id in selected_el_ids]
#👉 Prompt User Selection if nothing selected
if not selected_el:
selected_el_refs = selection.PickObjects(ObjectType.Element)
selected_el = [doc.GetElement(ref) for ref in selected_el_refs]
#👀 Filter Elements
selected_walls = [el for el in selected_el if type(el) == Wall]
#❗ Ensure Walls Selected
if not selected_walls:
from pyrevit import forms
forms.alert('No walls selected. Please try again', exitscript=True)
```
Here is a simple Snippet to get user selection.
1️⃣ First of all we try to get current user's selection
2️⃣ Then if nothing is selecte, we will prompt PickObjects selection
3️⃣ Since we only want to work with Walls, let's make a simple filter.
4️⃣ Lastly, let's give a warning if user hasn't selected any walls.
## 2️⃣Get Layers
Now once we have Walls, we can start looking inside of them. I would recommend you to use Revit Lookup and look inside until you find Layers. Then it becomes very easy to follow the same logic in your code.
As I've mentioned earlier, we need to look in WallType to get material layers.
There will be .[`GetCompoundStructure`](https://rvtdocs.com/2023/a1ec47e5-c552-944d-2152-74d7bd3f2a31) method that returns [CompoundStructure](https://rvtdocs.com/2023/dc1a081e-8dab-565f-145d-a429098d353c).
Then we can use [GetLayers](https://rvtdocs.com/2023/105b59e9-9cea-1988-a5a7-cc9cde49145c) to get all material layers. Keep in mind it returns `List<`[`CompoundStructureLayer`](https://rvtdocs.com/2023/faece83a-6d49-41b0-2713-fe6cfaa5a3b5)`>`. So you can look in the Revit API Documentation what else we can get from them.
```python
for wall in selected_walls:
wall_type = wall.WallType
wall_type_name = Element.Name.GetValue(wall_type)
structure = wall_type.GetCompoundStructure() #type: CompoundStructure
layers = structure.GetLayers() #type: List[CompoundStructureLayer]
```
## 3️⃣Read Material
Now we have all layers, we can read their properties.
In my case, I want to read Material Names and Thicknesses of each layer and print in the console.
It might be used later for renaming our types 😉.
Here is the code snippet:
```python
print('Wall Materials:')
for lay in layers:
mat_id = lay.MaterialId
width_ft = lay.Width #❗ Revit API USES FEET!
width_cm = width_ft * 30.48
if mat_id == ElementId(-1): #👀 ElementId(-1) Means None
mat_name = 'None
else:
mat = doc.GetElement(mat_id)
mat_name = mat.Name
print('--- {} ({}cm)'.format(mat_name, width_cm))
```
Keep in mind that some layers have no material assigned to them, so they will return `ElementId(-1)`. So don't forget to make an if statement before you try to get Material by using [doc.GetElement(e_id)](https://rvtdocs.com/2023/d9848d7d-5917-2433-8454-f65f5ac03964)
💡Also will notice that I multiplied my width with `30.48` for rounding.
You can use a better approach for rounding using [UnitUtils ](https://rvtdocs.com/2023/128dd879-fea8-5d7b-1eb2-d64f87753990)Class.
```python
width_cm = UnitUtils.ConvertFromInternalUnits(width_ft, UnitTypeId.Centimeters)
```
## ✨Final Code
Here is the Final Code. And you will find the screenshot example on the bottom ;)
```python
# -*- coding: utf-8 -*-
__title__ = "Read Properties"
__doc__ = """Version = 1.0
Date = 15.01.2024
_____________________________________________________________________
Description:
How to Read Properties and Methods from Elements?
_____________________________________________________________________
Author: Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
# ==================================================
# Regular + Autodesk
from Autodesk.Revit.DB import *
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
# ==================================================
doc = __revit__.ActiveUIDocument.Document #type: Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
# ==================================================
from Autodesk.Revit.UI.Selection import Selection, ObjectType
selection = uidoc.Selection #type: Selection
# Get Current Selection
selected_el_ids = selection.GetElementIds()
selected_el = [doc.GetElement(e_id) for e_id in selected_el_ids]
# Prompt User Selection if nothing selected
if not selected_el:
selected_el_refs = selection.PickObjects(ObjectType.Element)
selected_el = [doc.GetElement(ref) for ref in selected_el_refs]
# Filter Elements
selected_walls = [el for el in selected_el if type(el) == Wall]
if not selected_walls:
from pyrevit import forms
forms.alert('No walls selected. Please try again', exitscript=True)
#👀 READ PROPERTIES
for wall in selected_walls:
lvl = doc.GetElement(wall.LevelId)
wall_type = wall.WallType
wall_type_name = Element.Name.GetValue(wall_type)
print('-'*50)
print('Wall Id: {}'.format(wall.Id))
print('WallType: {}'.format(wall_type_name))
print('Level Name: {}'.format(lvl.Name))
structure = wall_type.GetCompoundStructure()
layers = structure.GetLayers()
print('Wall Materials:')
for lay in layers:
mat_id = lay.MaterialId
width_ft = lay.Width # Revit API USES FEET!
width_cm = width_ft * 30.48
if mat_id != ElementId(-1):
mat = doc.GetElement(mat_id)
mat_name = mat.Name
else:
mat_name = 'None'
print('--- {} ({}cm)'.format(mat_name, width_cm))
```

## ⌨️ Happy Coding!
### How to Get Default Type in Revit API?
https://learnrevitapi.com/blog/get-default-element-types-with-revit-api/
## How to Get Default Types in Revit API?
Once you start using Revit API, it's likely that at some point you will need to get your default types from Revit. Many people use collectors to get all types and then grab one randomly.
But there is a much simpler approach we can use by using following methods:
- [GetDefaultElementTypeId](https://rvtdocs.com/2023/b62f6563-aca4-56dc-4697-7717932187b3) - Get a type of Revit's native elements (Wall, Region, View…)
- [GetDefaultFamilyTypeId](https://rvtdocs.com/2023/34d20683-dfea-b1f8-14cf-750611b218ed) - Get a type of Loadable Family (Door, Window, Generic Model…)
Both methods come from [Document Class](https://rvtdocs.com/2023/db03274b-a107-aa32-9034-f3e0df4bb1ec).
Let's explore how these methods work and as usual I will give you code examples you could use!
## 1️⃣ How to Use [GetDefaultElementTypeId](https://rvtdocs.com/2023/b62f6563-aca4-56dc-4697-7717932187b3)
This method is used to get default element type ids of your native elements.
By native I mean elements that exist in Revit by default and can not be loaded as families.
*Such as: Walls, Floors, Roofs, Levels, Grids, Regions... *
Here is the syntax of how it can be used:

This method takes a single argument -[ ElementTypeGroup Enumeration](https://rvtdocs.com/2023/f5b57d98-c551-9693-9009-8eb17fef8a14)
Since it's an enumeration - you can see all available options you can choose from.

But it would be a much simpler approach if you have Revit API autocomplete configured in your IDE. Then you write `ElementTypeGroup.` and you will see all possible values you can choose from.
👇 Here is a code example on how to get Default Type of Walls, Floors, FloorPlan and Regions.
```python
#⬇️ Imports
from Autodesk.Revit.DB import *
#📦 Variables
doc = __revit__.ActiveUIDocument.Document #type: Document
#1️⃣ GetDefaultElementTypeId (Get Types of Native Families)
wall_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.WallType)
floor_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.FloorType)
view_plan_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeFloorPlan)
region_type_id = doc.GetDefaultElementTypeId(ElementTypeGroup.FilledRegionType)
#👉 Convert to Elements
wall_type = doc.GetElement(wall_type_id)
floor_type = doc.GetElement(floor_type_id)
view_plan_type = doc.GetElement(view_plan_type_id)
region_type = doc.GetElement(region_type_id)
#👀 Display Type Names
print(Element.Name.GetValue(wall_type))
print(Element.Name.GetValue(floor_type))
print(Element.Name.GetValue(view_plan_type))
print(Element.Name.GetValue(region_type))
```
💡 This method will return you [ElementId](https://rvtdocs.com/2023/44f3f7b1-3229-3404-93c9-dc5e70337dd6), so don't forget to convert it into Elements!
## 2️⃣ How to Use [GetDefaultFamilyTypeId](https://rvtdocs.com/2023/34d20683-dfea-b1f8-14cf-750611b218ed)
The second method is used to get default element type ids of your loadable elements.
*Such as: Windows, Doors, Generic Models... *
Here is the syntax of how it can be used:

This method takes a single argument -[ ](https://rvtdocs.com/2023/f5b57d98-c551-9693-9009-8eb17fef8a14)familyCategoryId.
And it's very simple to get it, we can use [ElementId ](https://rvtdocs.com/2023/8251e7b1-ea91-ec9c-c8da-6f53a6638811)Constructor and provide [BuiltInCategory](https://rvtdocs.com/2023/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722) as an argument.
Here is an Example:
```text
door_cat_id = ElementId(BuiltInCategory.OST_Doors)
```
Now let's combine it with [GetDefaultFamilyTypeId](https://rvtdocs.com/2023/34d20683-dfea-b1f8-14cf-750611b218ed) and write a snippet like this:
```python
#⬇️ Imports
from Autodesk.Revit.DB import *
#📦 Variables
doc = __revit__.ActiveUIDocument.Document #type: Document
#2️⃣ GetDefaultFamilyTypeId (Get Types of Loaded Families)
door_type_id = doc.GetDefaultFamilyTypeId(ElementId(BuiltInCategory.OST_Doors))
win_type_id = doc.GetDefaultFamilyTypeId(ElementId(BuiltInCategory.OST_Windows))
gen_model_type_id = doc.GetDefaultFamilyTypeId(ElementId(BuiltInCategory.OST_GenericModel))
#👉 Convert to Elements
door_type = doc.GetElement(door_type_id)
win_type = doc.GetElement(win_type_id)
gen_model_type = doc.GetElement(gen_model_type_id)
#👀 Display Results
print(Element.Name.GetValue(door_type))
print(Element.Name.GetValue(win_type))
print(Element.Name.GetValue(gen_model_type))
```
This will get you default types of Doors, Windows and Generic Models. And the same can be applied for other categories as well!
## ⌨️ Happy Coding!
I hope you learnt something new, and you will use it in your own scripts.
### How To Cut FilledRegions with a Detail Line
https://learnrevitapi.com/blog/cut-filled-regions-with-detail-line-revit-api-tutorial/
**Recently I was making FIlledRegion tools, and I really wanted to make a Saw Cut with a line through regions.**
As simple as it sounds, It actually took some time to come up with the workflow that works, and I want to share it with you.
It can be applied to other elements like Floors and Ceilings as well, so I think it's quite useful for you to know
**💡 Let's learn how to cut elements with line.**
## Workflow
Firstly, let's brainstorm the workflow so you understand the steps and then we will go into coding part.
Here are the steps we will go through:
- Select **FilledRegion** and **DetialLine**
****- Create infinite **plane **from Line****
- Create temp **Geometry **from boundaries
- Cut Geometry with plane in both directions
- Get Outine of new geometries
- Recreate FilledRegions
These are the steps that I will explain to cut an element with a line.
## Select Elements
There are different methods to select our elements. To make it the best user experience it's worth using [**ISelectionFilter**](https://rvtdocs.com/2023/d552f44b-221c-0ecd-d001-41a5099b2f9f), as it will limit elements that can be selected and avoid mistakes by selecting wrong elements.
Also I use [**forms.WarningBar**](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056#4b28840bed334cb3acc710031762d40b) from pyRevit to make it clearer for the user what needs to be selected while having an orange bar on the top.
Here are my custom [**ISelectionFilter**](https://rvtdocs.com/2023/d552f44b-221c-0ecd-d001-41a5099b2f9f)** **classes:
```python
class ISelectionFilter_Regions(ISelectionFilter):
def AllowElement(self, element):
if type(element) == FilledRegion:
return True
class ISelectionFilter_DetailLine(ISelectionFilter):
def AllowElement(self, element):
if type(element) == DetailLine:
return True
```
Now we can combine it all together to prompt user to select multiple Regions and a single Detail Line with [**selection.PickObject**](https://rvtdocs.com/2023/0315fd62-b533-1817-2f2d-d9ebd4bc8e33)** **/ [](https://rvtdocs.com/2023/3ac1a2c4-9afc-98cf-d5b8-c0c6a15fb4e8)[**selection.PickObjects**](https://rvtdocs.com/2023/3ac1a2c4-9afc-98cf-d5b8-c0c6a15fb4e8)**.**
I also added **Try/Except** statements to avoid crashing, and if statement to check if we get any elements.
```python
selection = uidoc.Selection #type: Selection
#📦 Define Placeholders
selected_line = None
selected_regions = None
#1️⃣ Get FilledRegions
with forms.WarningBar(title='Pick Filled Region:'):
try:
ref_picked_objects = selection.PickObjects(ObjectType.Element, ISelectionFilter_Regions())
selected_regions = [doc.GetElement(ref) for ref in ref_picked_objects]
except:
pass
#2️⃣ Get DetailLine
with forms.WarningBar(title='Pick Detail Line:'):
try:
ref_picked_object = selection.PickObject(ObjectType.Element, ISelectionFilter_DetailLine())
selected_line = doc.GetElement(ref_picked_object)
except:
pass
# Check if elements were selected
if not selected_regions:
forms.alert("FileldRegions weren't selected. Please Try Again.",exitscript=True)
if not selected_line:
forms.alert("Detail Line wasn't selected. Please Try Again.", exitscript=True)
```
## Create Infinite Plane from Line
Now we can convert a line into an infinite Plane that will be used to cut any geometry.
We can get Start and End point by using [**Curve.GetEndPoint**](https://rvtdocs.com/2023/a02da994-2976-38c0-e16b-20292de9fe57)** **and to make a plane we need 3 points to use [**Plane.CreateByThreePoints.**](https://rvtdocs.com/2023/a18aa7a2-71b6-5fa2-8ca8-abadedb638d7)
So I will get middle point of the line and change Z coordinate to be a bit higher. This will be enough for creating a plane.
Let's make it a function and create our plane
```python
# Function to Create a Plane from DetailLine
def create_plane_from_line(line):
'''Create Infinite Plane from Line'''
crv = line.Location.Curve
pt_start = crv.GetEndPoint(0)
pt_end = crv.GetEndPoint(1)
pt_mid = (pt_start + pt_end) / 2
pt_mid = XYZ(pt_mid.X, pt_mid.Y, pt_mid.Z + 10)
plane = Plane.CreateByThreePoints(pt_start, pt_end, pt_mid)
return plane
#✅ Create Plane from Line (By 3 Points)
plane = create_plane_from_line(selected_line)
```
Also when we will start cutting our geoemtry, we need to get results from both sides of the line, so we can create 2 new Filled Regions on each side of the line.
For that we will need to mirror our plane, so we can get results from both sides later when we start cutting.
Here is a function to mirror a plane direction.
```python
def mirror_plane(plane):
# Get the origin and normal of the original plane
origin = plane.Origin
normal = plane.Normal
# Mirror the normal by reversing its direction
mirrored_normal = XYZ(-normal.X, -normal.Y, -normal.Z)
# Create a new mirrored plane with the same origin and mirrored normal
mirrored_plane = Plane.CreateByNormalAndOrigin(mirrored_normal, origin)
return mirrored_plane
plane = ... # Defined Earlier
mirrored_plane = mirror_plane(plane)
```
## Create Geometry from Regions
New we can iterate through all FilledRegions and create geometry from them.
We will use [**FilledRegion.GetBoundaries**](https://rvtdocs.com/2023/5309fd5b-4a99-2d1d-665c-6153a8607012) to get outline. And then we can use [**GeometryCreationUtilities.CreateExtrusionGeometry**](https://rvtdocs.com/2023/2dd1de2f-b8fc-60d6-30d8-46810f79c3fc) to make it a 3D Shape by extrucing this outline up.
```python
# Create 3D Geometry from FilledRegion's Boundaries
for region in selected_regions:
try:
#📦 Create Shape from Boundaries (random height)
boundaries = region.GetBoundaries()
shape = GeometryCreationUtilities.CreateExtrusionGeometry(boundaries, XYZ(0,0,1), 10) #10 - height
except:
pass
```
## Cut Geometry with Plane
✂️ Once we have Geometry and a Plane we can start cutting.
We will use ****[**BooleanOperationsUtils.CutWithHalfSpace**](https://rvtdocs.com/2023/cbde1739-3680-4f2a-8215-a48fd08dcb5c) method for that. We can provide Geometry and a Plane and it will return us resulting geometry.
💡 This is also where we will need to flip our Plane to get second part!
```python
#✂ Split Solid with Plane (In both directions)
new_shape_1 = BooleanOperationsUtils.CutWithHalfSpace(shape, plane)
new_shape_2 = BooleanOperationsUtils.CutWithHalfSpace(shape, mirror_plane(plane))
```
## Test Geometry
So now we should have 2 new Geometries. Before going any further we might want to test if we get correct results.
We can create a [**DirectShape **](https://rvtdocs.com/2023/bfbd137b-c2c2-71bb-6f4a-992d0dcf6ea8)from these geometries to create 3D shapes in Revit UI. This is a step that is useful during development but should be commented out in production.
💡 P.S. Don't forget Transaction!
```python
# Create DirectShape to visualize results
cat_id = ElementId(BuiltInCategory.OST_GenericModel)
# Shape 1
ds1 = DirectShape.CreateElement(doc, cat_id)
ds1.SetShape([new_shape_1])
# Shape 2
ds2 = DirectShape.CreateElement(doc, cat_id)
ds2.SetShape([new_shape_2])
```
## Get New Geo Outline
Once you know that your new geometries are correct, we can start working backwards to create **FIlledRegions** again.
First of all let's get Geometry Outlines. I will be looking for the Top face of the geometry and then get its Outline using ********[**Face.GetEdgesAsCurveLoops**](https://rvtdocs.com/2023/4410caa7-3f65-1aed-763c-4f23510d6c17)
```python
# Function - Find Top Face of Geo
def find_top_face(solid):
# Iterate through the faces of the solid
for face in solid.Faces:
if face.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ):
return face
#🔝 Get Top Faces of new Geometries
top_face_1 = find_top_face(new_shape_1)
top_face_2 = find_top_face(new_shape_2)
#🔲 Get Top Face Outlines
outline_1 = top_face_1.GetEdgesAsCurveLoops()
outline_2 = top_face_2.GetEdgesAsCurveLoops()
```
## Create new FilledRegions
Now we have everything we need to Create new **FilledRegions **after the Cut, and delete the initial Region.
We will use [**FilledRegion.Create**](https://rvtdocs.com/2023/41bd803e-5549-da86-c190-77a9cae68cd0) method and [**Document.Delete**](https://rvtdocs.com/2023/a0461dd1-71d9-4581-1604-2ef8c211dd60)
We will also make sure that we use the same Region type by getting it with [**.GetTypeId**](https://rvtdocs.com/2023/cc66ca8e-302e-f072-edca-d847bcf14c86)
Here is the final Step
```text
#🔵 Get Filled Region Type
fr_id = region.GetTypeId()
#✅ Create new FilledRegions
filled_region1 = FilledRegion.Create(doc, fr_id, doc.ActiveView.Id, outline_1)
filled_region2 = FilledRegion.Create(doc, fr_id, doc.ActiveView.Id, outline_2)
#🔥 Delete Old Filled Region
if filled_region1 and filled_region2:
doc.Delete(region.Id)
```
## Final Code
So let's put it all together in a single snippet to avoid confusion and misunderstanding!
```text
# -*- coding: utf-8 -*-
__title__ = "Split Regions with Line"
__doc__ = """Version = 1.0
Date = 17.12.2023
_____________________________________________________________________
Description:
Split Selected FilledRegions with a Detail Line.
💡 Detail Line will be used to create an infinite plane!
_____________________________________________________________________
How-to:
-> Click on the button
-> Select Filled Regions
-> Select DetailLine
_____________________________________________________________________
Last update:
- [17.12.2023] - 1.0 RELEASE
_____________________________________________________________________
To-Do?:
- Keep Parameters?
_____________________________________________________________________
Author: Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import *
from pyrevit import forms
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document #type: Document
app = __revit__.Application
selection = uidoc.Selection #type: Selection
# ╔═╗╦ ╦╔═╗╔╗╔╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║ ║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╚═╝╝╚╝ ╩ ╩╚═╝╝╚╝╚═╝
#==================================================
def mirror_plane(plane):
# Get the origin and normal of the original plane
origin = plane.Origin
normal = plane.Normal
# Mirror the normal by reversing its direction
mirrored_normal = XYZ(-normal.X, -normal.Y, -normal.Z)
# Create a new mirrored plane with the same origin and mirrored normal
mirrored_plane = Plane.CreateByNormalAndOrigin(mirrored_normal, origin)
return mirrored_plane
def find_top_face(solid):
# Iterate through the faces of the solid
for face in solid.Faces:
if face.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ):
return face
def create_plane_from_line(line):
'''Create Infinite Plane from Line'''
crv = line.Location.Curve
pt_start = crv.GetEndPoint(0)
pt_end = crv.GetEndPoint(1)
pt_mid = (pt_start + pt_end) / 2
pt_mid = XYZ(pt_mid.X, pt_mid.Y, pt_mid.Z + 10)
plane = Plane.CreateByThreePoints(pt_start, pt_end, pt_mid)
return plane
# ╔═╗╦ ╔═╗╔═╗╔═╗╔═╗╔═╗
# ║ ║ ╠═╣╚═╗╚═╗║╣ ╚═╗
# ╚═╝╩═╝╩ ╩╚═╝╚═╝╚═╝╚═╝
#==================================================
class ISelectionFilter_Regions(ISelectionFilter):
def AllowElement(self, element):
if type(element) == FilledRegion:
return True
class ISelectionFilter_DetailLine(ISelectionFilter):
def AllowElement(self, element):
if type(element) == DetailLine:
return True
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝
#==================================================
#📦 Define Placeholders
selected_line, selected_regions = None, None
selected_line = None
selected_regions = None
#1️⃣ Get FilledRegions
with forms.WarningBar(title='Pick Filled Region:'):
try:
ref_picked_objects = selection.PickObjects(ObjectType.Element, ISelectionFilter_Regions())
selected_regions = [doc.GetElement(ref) for ref in ref_picked_objects]
except:
pass
#2️⃣ Get DetailLine
with forms.WarningBar(title='Pick Detail Line:'):
try:
ref_picked_object = selection.PickObject(ObjectType.Element, ISelectionFilter_DetailLine())
selected_line = doc.GetElement(ref_picked_object)
except:
pass
# Check if elements were selected
if not selected_regions:
forms.alert("FileldRegions weren't selected. Please Try Again.",exitscript=True)
if not selected_line:
forms.alert("Detail Line wasn't selected. Please Try Again.", exitscript=True)
#3️⃣ Create Plane from Line (By 3 Points)
plane = create_plane_from_line(selected_line)
#✅ Ensure Elements
if not selected_line or not selected_regions:
forms.alert('Select Region and Line.', exitscript=True)
#🎯 Modify Shape
t = Transaction(doc, 'EF_Split Regions with Line')
t.Start()
for region in selected_regions:
try:
#📦 Create Shape from Boundaries (random height)
boundaries = region.GetBoundaries()
shape = GeometryCreationUtilities.CreateExtrusionGeometry(boundaries, XYZ(0,0,1), 10) #10 - height
#✂ Split Solid with Plane (In both directions)
new_shape_1 = BooleanOperationsUtils.CutWithHalfSpace(shape, plane)
new_shape_2 = BooleanOperationsUtils.CutWithHalfSpace(shape, mirror_plane(plane))
#🔝 Get Top Faces of new Geometries
top_face_1 = find_top_face(new_shape_1)
top_face_2 = find_top_face(new_shape_2)
#🔲 Get Top Face Outlines
outline_1 = top_face_1.GetEdgesAsCurveLoops()
outline_2 = top_face_2.GetEdgesAsCurveLoops()
#🔵 Get Filled Region Type
fr_id = region.GetTypeId()
#✅ Create new FilledRegions
filled_region1 = FilledRegion.Create(doc, fr_id, doc.ActiveView.Id, outline_1)
filled_region2 = FilledRegion.Create(doc, fr_id, doc.ActiveView.Id, outline_2)
#🔥 Delete Old Filled Region
if filled_region1 and filled_region2:
doc.Delete(region.Id)
# # Create DirectShape to visualize results
# cat_id = ElementId(BuiltInCategory.OST_GenericModel)
# ds1 = DirectShape.CreateElement(doc, cat_id)
# ds1.SetShape([new_shape_1])
#
# ds2 = DirectShape.CreateElement(doc, cat_id)
# ds2.SetShape([new_shape_2])
except:
pass
t.Commit()
```
### Get Elements with ElementParameterFilter
https://learnrevitapi.com/blog/get-elements-by-type-or-family-name/
## Filter Elements by parameter Value
If you are a Revit API enthusiast, then at certain point you wanted to get your elements or types with a parameter value. Foe example get all instance of a specific Type or Family Name. It sounds like a very logical thing that should be within Revit API, but it's not.
So let me help you with that! Below I will provide a brief explanation on how to make a function to get elements by Type or Family name using [**ElementParameterFilter **](https://rvtdocs.com/2023/b0b40351-690c-eb5d-30c2-d4447a42fda1)Class.
And also you will learn how to modify it for any other parameter!
### Get Element of a certain Type Name
We will use [**ElementParameterFilter **](https://rvtdocs.com/2023/b0b40351-690c-eb5d-30c2-d4447a42fda1)to create a function to get elements by Type Names.
It needs:
- Parameter Id to create [**ParameterValueProvider**](https://rvtdocs.com/2023/5978eb2a-4598-f458-1504-80caff09cf7c)
- Evaluator ([**FilterStringEquals**](https://rvtdocs.com/2023/9a0d3b08-44ea-963f-f54d-c99e28fd1715)) in this caseAlso notice that there were changes in Revit API for this class so I will account for that too
- Also notice that there were changes in Revit API for this class so I will account for that too
- Then we can provide all of this to create [**ElementParameterFiler**](https://rvtdocs.com/2023/b0b40351-690c-eb5d-30c2-d4447a42fda1)
- And we can use this filter for [**FilteredElementCollector **](https://rvtdocs.com/2023/)with [**WherePasses**](https://rvtdocs.com/2023/42d4eef3-55a1-2739-0ef8-6bc1d9fc2755)
```python
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
rvt_year = int(app.VersionNumber)
def get_elements_by_type_name(type_name):
"""Function to get Elements by Type Name."""
# CREATE RULE
param_id = ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME)
f_param = ParameterValueProvider(param_id)
f_evaluator = FilterStringEquals()
# Revit API has changes
if rvt_year < 2023:
f_rule = FilterStringRule(f_param, FilterStringEquals(), type_name,True)
else:
f_rule = FilterStringRule(f_param, FilterStringEquals(), type_name)
# CREATE FILTER
filter_type_name = ElementParameterFilter(f_rule)
# GET ELEMENTS
return FilteredElementCollector(doc).WherePasses(filter_type_name)\
.WhereElementIsNotElementType().ToElements()
# Get Elements
elements = get_elements_by_type_name('Type Name')
print(elements)
```
### Get Elements with Family Name
We can also modify very little a get elements by Family name instead of type.
To do that we need to
- Change Parameter Id to [**BuiltInParameter**](https://rvtdocs.com/2023/fb011c91-be7e-f737-28c7-3f1e1917a0e0).**ALL_MODEL_FAMILY_NAME**
- Rename function and variables
The rest stays the same, here is complete Snippet.
```python
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
rvt_year = int(app.VersionNumber)
def get_elements_by_family_name(family_name):
"""Function to get Elements by Family Name."""
# CREATE RULE
param_id = ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME)
f_param = ParameterValueProvider(param_id)
f_evaluator = FilterStringEquals()
# Revit API has changes
if rvt_year < 2023:
f_rule = FilterStringRule(f_param, FilterStringEquals(), family_name, True)
else:
f_rule = FilterStringRule(f_param, FilterStringEquals(), family_name)
# CREATE FILTER
filter_type_name = ElementParameterFilter(f_rule)
# GET ELEMENTS
return FilteredElementCollector(doc).WherePasses(filter_type_name)\
.WhereElementIsNotElementType().ToElements()
# Get Elements
elements = get_elements_by_family_name('Filled Region')
print(elements)
```
### Get Types by Type or Family Name
You might also want to get types instead of instances and you can use exact duplicates of these functions but replace
```python
collector.WhereElementIsNotElementType() -> collector.WhereElementIsElementType()
```
Here is an example:
```python
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
rvt_year = int(app.VersionNumber)
def get_types_by_family_name(family_name):
"""Function to get Elements by Family Name."""
# CREATE RULE
param_id = ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME)
f_param = ParameterValueProvider(param_id)
f_evaluator = FilterStringEquals()
# Revit API has changes
if rvt_year < 2023:
f_rule = FilterStringRule(f_param, FilterStringEquals(), family_name, True)
else:
f_rule = FilterStringRule(f_param, FilterStringEquals(), family_name)
# CREATE FILTER
filter_type_name = ElementParameterFilter(f_rule)
# GET ELEMENTS
return FilteredElementCollector(doc).WherePasses(filter_type_name)\
.WhereElementIsElementType().ToElements()
# Get Types
types = get_elements_by_family_name('Family Name')
```
## ElementParameterFilter
These are examples on how to use [**ElementParameterFilter**](https://rvtdocs.com/2023/b0b40351-690c-eb5d-30c2-d4447a42fda1).
You can adjust very little and it will work with other parameters, and evaluators.
There will be a post about it in more detail in the future 😉
### RevitAPI: Get/Create FilledRegionType
https://learnrevitapi.com/blog/create-filled-region-type/
## 📝Introduction
If you are reading this, then you have a question in your mind:
How to create a new [**FilledRegionType**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca)** in **Revit API?
You might have noticed that there are no methods in Revit API Docs to do that.
However, it does not mean we can’t take existing one and duplicate it. Then you can change necessary properties, so it's indeed a new [**FilledRegionType**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca).
So let me take you through all these steps to write a code to: Get Existing [**FilledRegionType**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca)** **or Create a new one if it doesn't exist.
## 👉 Get Existing FilledRegionType by Name
First, let's check if desired **FilledRegionType **already exists. This will help you avoid duplicates and unwanted errors in your projects.
Here is a code snippet to do that:
```python
# Variables
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
rvt_year = int(app.VersionNumber)
# Function
def get_filled_region(filled_region_name):
"""Function to get FilledRegionType by Name using Revit API Filters"""
# Create Filter
param_id = ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME)
pvp = ParameterValueProvider(param_id )
condition = FilterStringEquals()
if rvt_year < 2022:
fRule = FilterStringRule(pvp, condition, filled_region_name, True)
else:
fRule = FilterStringRule(pvp, condition, filled_region_name)
my_filter = ElementParameterFilter(fRule)
# Get FilledRegionType
return FilteredElementCollector(doc).OfClass(FilledRegionType)\
.WherePasses(my_filter).FirstElement()
```
**💡Tip:** You can change Evaluator to [FilterStringContain ](https://rvtdocs.com/2023/0441350e-c091-9229-82b6-bba846bf0f16)instead of [FilterStringEquals](https://rvtdocs.com/2023/9a0d3b08-44ea-963f-f54d-c99e28fd1715).
## 🆕 Duplicate existing FilledRegionType
If we can't find the **FilledRegionType**, let's make our own! Here’s how in a few simple steps:
- Define desired **Pattern**, **Colour**, **Lineweight **and **Masking **settings.
- Get existing FilledRegionType and Duplicate it
- Change parameters as you need
I am going to walk you through these steps.
### 1️⃣ Get Solid Pattern
Let’s begin by getting the right pattern for our new **FilledRegionType**.
In my case I will look for Solid pattern, but you can write your own logic to get desired pattern.
```python
# FilledRegionType Settings
color = Color(128,128,255)
lineweight = 2
masking = False
# Get Solid Pattern
all_pats = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
all_solid = [pat for pat in all_pats if pat.GetFillPattern().IsSolidFill]
solid_pattern = all_solid [0]
```
### 2️⃣ Get random FilledRegionType and Duplicate
The next step is to get a random [**FilledRegionType**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca)** **and [**Duplicate **](https://rvtdocs.com/2023/b0e7d5d5-f33a-8ff2-b471-78a213f06ef5)it.
I am going to get a random [**FilledRegionTypes**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca)** **with [**FilteredElementCollector**](https://rvtdocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3). Since we are going to change all settings it does not matter which one we take. However, it's important to provide unique new name.
**💡 NB!** You will get an error if you are trying to duplicate **FilledRegionType **with an existing new name, be aware of that!
```python
# Duplicate existing FilledRegionType
new_name = ‘New Region’
random_filled_region = FilteredElementCollector(doc).OfClass(FilledRegionType).FirstElement()
new_region = random_filled_region.Duplicate(new_name)
```
Now we have our new [**FilledRegionType**](https://rvtdocs.com/2023/850ae173-379b-bfd6-7295-3950ccc229ca)** **with desired name and we can start changing its settings.
### 3️⃣ Apply new Settings to FilledRegionType
The last step is to change settings, and it’s not complicated.
All these settings are readable and writable properties, so it’s going to be very easy to set new values.
```python
# Set Pattern
new_region.BackgroundPatternId = ElementId(-1) #None
new_region.ForegroundPatternId = solid_pattern.Id
# Set Colour
new_region.BackgroundPatternColor = color
new_region.ForegroundPatternColor = color
# Masking
new_region.IsMasking = masking
# LineWeight
new_region.LineWeight = lineweight
```
## ✨ Final Code
Here is the final code for pyRevit's .pushbutton to **Get **or **Create **new FilledRegionType.
```python
# -*- coding: utf-8 -*-
__title__ = "Get/Create FilledRegion"
__author__ = "Erik Frits"
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
# ==================================================
# Regular + Autodesk
from Autodesk.Revit.DB import *
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
# ==================================================
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
rvt_year = int(app.VersionNumber)
region_name_A = 'New Region A'
region_name_B = 'New Region B'
# Get Solid Pattern
all_patterns = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
all_solid_patterns = [pat for pat in all_patterns if pat.GetFillPattern().IsSolidFill]
solid_pattern = all_solid_patterns[0]
# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
def get_filled_region(filled_region_name):
"""Function to get FireWall Types based on FamilyName"""
# Create Filter
pvp = ParameterValueProvider(ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME))
condition = FilterStringEquals()
fRule = FilterStringRule(pvp, condition, filled_region_name, True) if rvt_year < 2022 \
else FilterStringRule(pvp, condition, filled_region_name)
my_filter = ElementParameterFilter(fRule)
# Get Types
return FilteredElementCollector(doc).OfClass(FilledRegionType).WherePasses(my_filter).FirstElement()
def create_RegionType(name, color, masking = False, lineweight = 1):
#type: (str, Color, bool, int) -> FilledRegionType
"""Create FilledRegionType with Solid Pattern."""
random_filled_region = FilteredElementCollector(doc).OfClass(FilledRegionType).FirstElement()
new_region = random_filled_region.Duplicate(name)
# Set Solid Pattern
new_region.BackgroundPatternId = ElementId(-1)
new_region.ForegroundPatternId = solid_pattern.Id
# Set Colour
new_region.BackgroundPatternColor = color
new_region.ForegroundPatternColor = color
# Masking
new_region.IsMasking = masking
# LineWeight
new_region.LineWeight = lineweight
return new_region
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
# ==================================================
# Try to get existing FilledRegions
region_A = get_filled_region(region_name_A)
region_B = get_filled_region(region_name_B)
with Transaction(doc,__title__) as t:
t.Start()
# Create new if does not exist
if not region_A: region_A = create_RegionType(name = region_name_A, color = Color(255,128,128))
if not region_B: region_B = create_RegionType(name = region_name_B, color = Color(128,128,255))
t.Commit()
# Print Names of Regions:
print(Element.Name.GetValue(region_A))
print(Element.Name.GetValue(region_B))
```
### Isolate Elements with Revit API and python
https://learnrevitapi.com/blog/isolate-elements/
## ❓How to Isolate Elements with Revit API
So you have come to the point where you wanted to isolate your elements and you could not find the right method. You might have seen [**IsolateElementsTemporary**](https://rvtdocs.com/2023/ffc40d36-2092-a63c-ce8c-a72ee8430d3d)[ ](https://rvtdocs.com/2023/ffc40d36-2092-a63c-ce8c-a72ee8430d3d)method but that's not exactly what we want.
There are probably many different ways to Isolate your elements, but I like to get elements I want to isolate, and then get elements to hide using [**.Excluding **](https://rvtdocs.com/2023/80e23fdc-c005-163b-5643-38d84411a73d)method of [**FilteredElementCollector **](https://rvtdocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3)to get all elements except for the ones I want to isolate and hide them (if possible).
```python
# -*- coding: utf-8 -*-
# ⬇️ Imports
from Autodesk.Revit.DB import *
import clr
clr.AddReference('System')
from System.Collections.Generic import List
# 📦 Variables
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
# 🎯 Function
def isolate_elements(elements, view):
# type:(List[ElementId], View) -> None
"""Function to Isolate Elements in the given View."""
# ❌Elements to Hide
hide_elem = FilteredElementCollector(doc, view.Id)\
.Excluding(elements)\
.WhereElementIsNotElementType().ToElements()
# 🔎 Filter Elements that can not be hidden.
hide_elem_ids = [e.Id for e in hide_elem
if e.CanBeHidden(view)]
# 🔅 Isolate Elements
view.HideElements(List[ElementId](hide_elem_ids))
# 🎯 Main
t = Transaction(doc, 'Isolate Elements')
t.Start()
# 🔦 Get Elements to Isolate
elements_to_isolate = [doc.GetElement(e_id)
for e_id in uidoc.Selection.GetElementIds()]
List_isolate_ids = List[ElementId](elements_to_isolate)
# ✅ Isolate Elements
isolate_elements(List_isolate_ids, active_view)
t.Commit()
__author__ = 'Erik Frits'
```
**💡 **I am getting selected elements just as an example, adjust to your own needs!
### Get Solid Fill Pattern in Revit API
https://learnrevitapi.com/blog/get-solid-fill-pattern/
## 👉 Get Solid Fill Pattern
If you are trying to override your graphic settings then you will most likely want to get **SolidFillPattern**** **at some point.
There are different ways to get it, but I prefer to get all fill patterns and use list comprehension to filter out patterns with [**.IsSolidFill **](https://rvtdocs.com/2023/91cf0879-d401-4f6b-c26b-6b3ece4200db)property. If you want to learn more about how to **Overriding Graphics**,[** read more**](https://learnrevitapi.com/blog/override-graphics-in-view/) in another blog post I wrote.
**And Finally,** Here is the Snippet to get Solid Fill Pattern!
```python
# -*- coding: utf-8 -*-
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
#🟦 Get All Fill Patterns
all_patterns = FilteredElementCollector(doc)\
.OfClass(FillPatternElement)\
.ToElements()
#🔎 Filter Solid Fill Pattern
solid_pattern = [i for i in all_patterns
if i.GetFillPattern().IsSolidFill][0]
__author__ = '🙋♂️ Erik Frits'
```
### Copy Elements with RevitAPI + Python
https://learnrevitapi.com/blog/copy-elements-with-revit-api-python/
## 📄 RevitAPI Docs: CopyElements Methods
First of all let's have a look at the available methods in Revit API to copy elements.
Revit API has [three methods to copy elements](https://rvtdocs.com/2023/7b56b5c2-3aff-f42b-ab47-de1f89a1070f) depending on how you want to copy.

**NB!** All these methods come from [ElementTransformUtils ](https://rvtdocs.com/2023/82e737d5-fda4-bc10-6099-88999cd51300)class.
###
0️⃣ Prepare Elements to Copy
First of all let's prepare some base that will be used in all 3 examples, where we can get common variables.
You can see that we need to provide elements as `ICollection[ElementId]` for all the methods.
I will create `List[ElementId` since it's similar data type. Below you can see an example where I get all walls in the view and create a List out of it.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *
#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 Variables
doc = __revit__.Document
active_view = doc.ActiveView
#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElementIds()
#✅ Create List[ElementId]()
List_all_walls_view = List[ElementId](all_walls_view_ids)
__author__ = '🙋 Erik Frits'
```
### 1️⃣ Method A: Copy Elements with Vector
Now Let's have a look at how to actually copy our elements. I will start with the simplest method: copy elements using a vector.
Here is the syntax.
```python
ElementTransformUtils.CopyElements(Document,
ICollection,
XYZ)
```
It just means we need to define X,Y,Z coordinates of how we want to move elements.
### 📐XYZ() Vector
We have everything prepared except for the vector. Creating vector is the same as defining a point. We need to use `XYZ()` class and provide `x, y, z` values to where we want to copy elements.
💡Keep in mind that Revit API uses feet as internal units.
For Example, let's say I want to move my elements 50 feet on the X-Axis, 150 feet on the Y-Axis, and we won't change their Z-Axis.
```python
vector = XYZ(50,150,0)
```
👆 This would be the vector that we need.
Let's combine the whole thing and make a script that will copy our walls with vector.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *
#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 Variables
doc = __revit__.ActiveUIDocument.Document
#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElementIds()
#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_view_ids)
#📐 VECTOR
vector = XYZ(50,150,0)
#➕ Copy Elements
t = Transaction(doc, 'Copy Elements: A')
t.Start()
ElementTransformUtils.CopyElements(doc, elementsToCopy, vector)
t.Commit()
__author__ = '🙋 Erik Frits'
```
### 2️⃣ Method B: Copy Elements from View to View
Now let's copy elements between Views, here is the syntax:
```python
CopyElements(View,
ICollection,
View,
Transform,
CopyPasteOptions)
```
**💡 Bonus:** We can also take views from 2 different projects and copy between them!
The second method is used to copy Elements across different Revit `Views` including `ViewSheet.`
This time we need to get
source view,
elements to copy,
destination view(can be another project),
[Transform ](https://rvtdocs.com/2023/58dd01c8-b3fc-7142-e4f3-c524079a282d)(change position or angle of selection),
and [CopyPasteOptions ](https://rvtdocs.com/2023/eb110787-b031-5307-c083-14cb5d920617)
I will be getting random views in my Project, make sure to adjust to your needs!
2️⃣🅰️Copy Elements between Views
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *
#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 Variables
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc, active_view.Id)\
.OfCategory(BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElementIds()
#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_view_ids)
#🔎 GET ANOTHER VIEW
all_views = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_Views)\
.WhereElementIsNotElementType()\
.ToElements()
#👇 Adjust to your needs.
random_floor_plan = [view for view in all_views if view.ViewType == ViewType.FloorPlan][0]
# Define Transform and CopyPasteOptions()
transform = Transform.Identity # We can change position and rotation with Transform
opts = CopyPasteOptions() #
# COPY ELEMENTS BETWEEN VIEWS
t = Transaction(doc, 'Copy Elements: A')
t.Start()
ElementTransformUtils.CopyElements(active_view,
elementsToCopy,
random_floor_plan,
transform,
opts)
t.Commit()
#🥸 Report
print("{} Elements copied from {} -> {}"\
.format(len(elementsToCopy),
active_view.Name,
random_floor_plan.Name))
__author__ = '🙋 Erik Frits'
```
2️⃣🅱️Copy Elements between Sheets
We use the same logic for copying elements between Sheets.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *
#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 Variables
doc = __revit__.ActiveUIDocument.Document
#✅ Get Elements (I will just get all lines in View)
all_lines = FilteredElementCollector(doc).OfClass(CurveElement).ToElementIds()
#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_lines)
#🔎 GET ALL SHEETS
all_sheet = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_Sheets)\
.WhereElementIsNotElementType()\
.ToElements()
# Define Transform and CopyPasteOptions()
transform = Transform.Identity
opts = CopyPasteOptions()
# COPY ELEMENTS BETWEEN VIEWS
t = Transaction(doc, 'Copy Elements: B.2')
t.Start()
ElementTransformUtils.CopyElements(all_sheet[0],
elementsToCopy,
all_sheet[1],
transform,
opts)
t.Commit()
#🥸 Report
print("{} Elements copied from {} -> {}"\
.format(len(elementsToCopy),
all_sheet[0].SheetNumber,
all_sheet[1].SheetNumber))
__author__ = '🙋 Erik Frits'
```
### 3️⃣ Method C: Copy Elements from Project to Project
Lastly, I am going to show you how to copy elements between projects. By now you should have a good understanding how to work with any of these method, but I will give you another example.
I am going to get all open projects and then take all walls from project A and copy them to project B.
```python
# -*- coding: utf-8 -*-
#⬇️ Imports
import sys
from Autodesk.Revit.DB import *
#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List
#📦 Variables
app = __revit__.Application
#✌ GET ALL OPEN DOCUMENTS (Needed 2)
all_docs = list(app.Documents)
if len(all_docs) != 2:
print('This will work only if you have exactly 2 projects open!')
sys.exit()
doc_A = all_docs[0]
doc_B = all_docs[1]
#✅ Get Elements (I will just get all walls in View)
all_walls_A = FilteredElementCollector(doc_A)\
.OfCategory(BuiltInCategory.OST_Walls)\
.WhereElementIsNotElementType()\
.ToElementIds()
#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_A)
# Define Transform and CopyPasteOptions()
transform = Transform.Identity
opts = CopyPasteOptions()
# COPY ELEMENTS BETWEEN PROJECTS
t = Transaction(doc, 'Copy Elements C: Between Projects')
t.Start()
ElementTransformUtils.CopyElements(doc_A,
elementsToCopy,
doc_B,
transform,
opts)
t.Commit()
#🥸 Report
print("{} Elements copied from {} -> {}"\
.format(len(elementsToCopy),
doc_A.Title,
doc_B.Title))
__author__ = '🙋 Erik Frits'
```
## **Conclusion**
Copying elements is not that hard once you know what methods are available and how to use them. Whenever you will need to copy elements, just reference this article again, and I am sure it will help you out multiple times!
### Get TitleBlock from Sheet.
https://learnrevitapi.com/blog/get-titleblock-from-shees/
### How to Get Title Blocks from Sheets with Revit API❓
There are multiple ways of getting TitleBlocks from Sheets:
- 💪Use [ElementParameterFilter](https://rvtdocs.com/2023/b0b40351-690c-eb5d-30c2-d4447a42fda1)
- 👉️ Get visible TitleBlocks with [FilteredElementCollector(doc, view.Id)](https://rvtdocs.com/2023/6359776d-915e-f8a2-4147-b31024671ee1) <- Slower
- 👉️ Get all **TitleBlocks **and look at their [OwnerViewId](https://rvtdocs.com/2023/174c1adf-0be8-a4b0-41f3-9e3ea1d6b1f1)
I would recommend using a function with `ElementParameterFilter`, since it's already written for you and it's a no-brainer.
### 1️⃣ Get TitleBlock with ElementParameterFilter
For this method we will need to create ElementParameterFilter and use it in FilteredElementCollector. This is probably the most efficient way to get TitleBlocks from sheets.
💡 Also notice that there are differences in Revit API for [FilterStringRule](https://rvtdocs.com/2023/166d75f9-1088-3275-2219-867c1142d8da), but I accounted for it in my snippet.
```python
# -*- coding: utf-8 -*-
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
rvt_year = int(app.VersionNumber)
# 👇 FUNCTION
def get_titleblocks_from_sheet(sheet, doc):
# type:(ViewSheet, Document) -> list
"""Function to get TitleBlocks from the given ViewSheet.
:param sheet: ViewSheet that has TitleBlock
:param doc: Document instance of the Project
:return: list of TitleBlocks that are placed on the given Sheet."""
# RULE ARGUMENTS
rule_value = sheet.SheetNumber
param_sheet_number = ElementId(BuiltInParameter.SHEET_NUMBER)
f_pvp = ParameterValueProvider(param_sheet_number)
evaluator = FilterStringEquals()
# CREATE A RULE (Method has changed in Revit API in 2022)
if rvt_year < 2022:
f_rule = FilterStringRule(f_pvp, evaluator, rule_value, True) # RVT 2021-
else:
f_rule = FilterStringRule(f_pvp, evaluator, rule_value) # RVT 2022+
# CREATE A FILTER
tb_filter = ElementParameterFilter(f_rule)
# GET TITLEBLOCKS
tb = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_TitleBlocks) \
.WhereElementIsNotElementType().WherePasses(tb_filter).ToElements()
return list(tb)
#🎯 MAIN
if __name__ == '__main__':
# GET RANDOM SHEET
random_sheet = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets)\
.WhereElementIsNotElementType().FirstElement()
# GET TITLEBLOCK
title_block = get_titleblocks_from_sheet(random_sheet, doc)
__author__ = '🙋♂️ Erik Frits'
```
### 2️⃣ Get visible TitleBlocks with FilteredElementCollector(doc, view.Id)
There is an alternative method to use `FilteredElementCollector` and provide `ViewSheet.Id` as a second argument to get elements visible in that sheet.
```python
title_blocks = FilteredElementCollector(doc, sheet.Id)\
.OfCategory(BuiltInCategory.OST_TitleBlocks)\
.WhereElementIsNotElementType()\
.ToElements()
```
💡 This is much easier approach but it will cost in execution time!
## Comparison
I was curious about the difference between these two methods, so I put them to the test.
The second method is slower because it has to load up the view to analyze what elements are visible and it comes at a cost!
💡I used a Revit project that is ~500mb and I used similar logic of getting title blocks,
👇 Here are the results.

🧮 As you can see there is a huge difference.
**`10s `****vs ****`252s`****- It's ~2500% difference!**
The difference is going to be less on smaller projects. But on large projects where it takes longer times to render views, it might become an issue.
The problem is that whenever you provide `View.Id` to `FilteredElementCollector` it has to partially render the view. While on a smaller projects this difference can be little, on large projects it might become an issue.
### Honestly, though?
I was too lazy to make separate buttons for each method, so my comparison isn't perfect, but with such a huge difference, who cares?
You can take a look at the code below that I quickly wrote to see how I made comparison
### 👀 Comparison of Get TitleBlock methods
```python
# -*- coding: utf-8 -*-
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
import time
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
rvt_year = int(app.VersionNumber)
# 👇 FUNCTION
def get_titleblocks_from_sheet(sheet, doc):
# type:(ViewSheet, Document) -> list
"""Function to get TitleBlocks from the given ViewSheet.
:param sheet: ViewSheet that has TitleBlock
:param doc: Document instance of the Project
:return: list of TitleBlocks that are placed on the given Sheet."""
# RULE ARGUMENTS
rule_value = sheet.SheetNumber
param_sheet_number = ElementId(BuiltInParameter.SHEET_NUMBER)
f_pvp = ParameterValueProvider(param_sheet_number)
evaluator = FilterStringEquals()
# CREATE A RULE
if rvt_year < 2022:
f_rule = FilterStringRule(f_pvp, evaluator, rule_value, True) # RVT 2021-
else:
f_rule = FilterStringRule(f_pvp, evaluator, rule_value) # RVT 2022+
# CREATE A FILTER
tb_filter = ElementParameterFilter(f_rule)
# GET TITLEBLOCKS
tb = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_TitleBlocks) \
.WhereElementIsNotElementType().WherePasses(tb_filter).ToElements()
return list(tb)
#🎯 MAIN
if __name__ == '__main__':
all_sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets)\
.WhereElementIsNotElementType().ToElements()
print('Total {} Sheets.'.format(len(all_sheets)))
# Reduce Sheets to run quicker.
try: all_sheets = list(all_sheets)[:10]
except: pass
print("Get Titleblocks from {} Sheets:".format(len(all_sheets)))
print('-'*100)
#🅱️ OPTION B
b_start = time.time()
all_tbs = []
for sheet in all_sheets:
tb = get_titleblocks_from_sheet(sheet, doc)
all_tbs += list(tb)
print('*** Get TitleBlocks with ElmenetParameterFilter(rule)')
print('TitleBlocks: {}'.format(len(all_tbs)))
print("It Took {}s to complete with ElementParameterFilter(rule)".format(time.time() - b_start))
print('-'*100)
#🅰️ OPTION A
a_start = time.time()
all_tb = []
for i in all_sheets:
tb = FilteredElementCollector(doc, i.Id).OfCategory(BuiltInCategory.OST_TitleBlocks)\
.WhereElementIsNotElementType().ToElements()
all_tb += list(tb)
print('*** Get TitleBlocks with FilteredElementCollector(doc, View.Id)')
print('TitleBlocks: {}'.format(len(all_tb)))
print("It Took {}s to complete with FEC(doc,View.Id)".format(time.time() - a_start))
__author__ = '🙋♂️Erik Frits'
```
### Create Views with Revit API + python
https://learnrevitapi.com/blog/create-views-with-revit-api-python/
## ❓How to create Views with Revit API?
When you’re creating a view in Revit, there are a few things to keep in mind. First, you need to know what kind of view you want to create:
- ViewPlan (FloorPlan, Ceiling Plan, StructuralPlan, AreaPlan)
- ViewSection (Section, Callout, Detail)
- View3D (Isometric, Perspective)
- ViewDrafting
- ViewSheet
- Legend View
Once you have an idea of what kind of view you want to create, it's time to check Revit API documentation for specific methods on how to create such view.
👇 Here are their syntaxes. You can see in cyan color from what class it comes. (e.g. ViewPlan Class)

Let's look at each one of them to create views
## 0️⃣ Get all ViewFamilyTypes
But before that we need to prepare our code by getting all of the [**ViewFamilyTypes**](https://rvtdocs.com/2023/e0edeb6d-1627-3e3f-e386-be182a9dd8cb).
You will see across all of the methods, we always need to provide `viewFamilyTypeId`. So let's start by getting and filtering all of View Types so we can use it later on.
Usually you will need to create some User control so they can choose specific **ViewType**, but I will just use a random one for this post.
```python
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER CERTAIN VIEW TYPES
view_types_plans = [vt for vt in view_types if vt.ViewFamily == ViewFamily.FloorPlan]
view_types_sections = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Section]
view_types_3D = [vt for vt in view_types if vt.ViewFamily == ViewFamily.ThreeDimensional]
view_types_legends = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Legend]
view_types_drafting = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Drafting]
view_types_elevations = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Elevation]
view_types_ceil_views = [vt for vt in view_types if vt.ViewFamily == ViewFamily.CeilingPlan]
view_types_structural = [vt for vt in view_types if vt.ViewFamily == ViewFamily.StructuralPlan]
view_types_area = [vt for vt in view_types if vt.ViewFamily == ViewFamily.AreaPlan]
```
## 1️⃣ How to Create ViewPlan?
Let's start by making a few ViewPlans.
[ViewPlan ](https://rvtdocs.com/2023/0520580a-74ec-ed8c-35ea-5274c42276a3)is every horizontally cut plan that we use in Revit, such as Floor Plan, Ceiling Plan, Structural Plan, Area Plan...
And they all use the same method.
```python
ViewPlan.Create(doc,
viewFamilyTypeId,
levelId)
```
I have already shown you how to get `viewFamilyTypes` so now it's about getting other arguments.
You can Copy-Paste these snippets and they will create views in your project!
### Create FloorPlan
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_plans = [vt for vt in view_types if vt.ViewFamily == ViewFamily.FloorPlan]
floor_plan_type = view_types_plans[0]
#🎯 Create Floor Plan
with Transaction(doc,'Create Floor Plan') as t:
t.Start()
view = ViewPlan.Create(doc, floor_plan_type.Id, active_level.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
### Create CeilingPlan
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_ceil_views = [vt for vt in view_types if vt.ViewFamily == ViewFamily.CeilingPlan]
ceil_plan_type = view_types_ceil_views [0]
#🎯 Create Create Ceiling Plan
with Transaction(doc,'Create Ceiling Plan') as t:
t.Start()
view = ViewPlan.Create(doc, ceil_plan_type.Id, active_level.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
### Create AreaPlan
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_area = [vt for vt in view_types if vt.ViewFamily == ViewFamily.AreaPlan]
area_plan_type = view_types_area[0]
#🎯 Create Area Plan
with Transaction(doc,'Create Area Plan') as t:
t.Start()
view = ViewPlan.Create(doc, area_plan_type.Id, active_level.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
### Create StructuralView
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_structural = [vt for vt in view_types if vt.ViewFamily == ViewFamily.StructuralPlan]
struc_plan_type = view_types_structural[0]
#🎯 Create Structural Plan
with Transaction(doc,'Create Structural Plan') as t:
t.Start()
view = ViewPlan.Create(doc, struc_plan_type.Id, active_level.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## 2️⃣ How to Create ViewSection?
Sections are a little harder to make because we need to work with [**BoundingBox**](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2)
👇 Here is the method to create a Section.
```python
ViewSection.Create(doc,
viewFamilyTypeId,
sectionBox)
```
We have everything except for secitonBox. It might be tricky to create one, but it makes sense. Because when we create sections, we have a line where it cuts, and then it's view range is extruded, so it creates a sectionBox shape.
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_sections = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Section]
view_type_section = view_types_sections[0]
#🟦 BOUNDING BOX
origin = XYZ(5,5,0)
pt_start = XYZ(0,0,0)
pt_end = XYZ(10,10,0)
vector = pt_end - pt_start
offset = 5
W = 5
H = 5
D = 5
# SECTION - DIRECTION
fc = -1
if pt_start.X > pt_end.X or (pt_start.X == pt_end.X and pt_start.Y < pt_end.Y):
fc = 1
# SECTION - ORIENTATION
curvedir = fc * vector.Normalize()
t = Transform.Identity
t.Origin = origin
t.BasisX = curvedir
t.BasisY = XYZ.BasisZ
t.BasisZ = curvedir.CrossProduct(XYZ.BasisZ)
# SECTION - CROPBOX
sectionBox = BoundingBoxXYZ()
sectionBox.Transform = t #apply orientation
sectionBox.Min = XYZ(W*-0.5 -offset, 0 -offset, D*-0.5 -offset)
sectionBox.Max = XYZ(W* 0.5 +offset, H +offset, D* 0.5 +offset)
#🎯 Create Structural Plan
with Transaction(doc,'Create Structural Plan') as t:
t.Start()
view_section = ViewSection.CreateSection(doc, view_type_section.Id, sectionBox)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## 3️⃣How to Create View3D
Creating 3D Views with Revit API is straight-forward. We just need to decide between Isometric or Perspective.
👇 Here are their methods.
```python
View3D.CreateIsometric(doc,
viewFamilyTypeId)
```
```python
View3D.CreatePerspective(doc,
viewFamilyTypeId)
```
### Create Isometric 3D View
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_3D = [vt for vt in view_types if vt.ViewFamily == ViewFamily.ThreeDimensional]
view_type_3D = view_types_3D[0]
#🎯 Create 3D - Isometric
with Transaction(doc,'Create 3D Isometric') as t:
t.Start()
view3D = View3D.CreateIsometric(doc, view_type_3D.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
### Create Isometric 3D View
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_3D = [vt for vt in view_types if vt.ViewFamily == ViewFamily.ThreeDimensional]
view_type_3D = view_types_3D[0]
#🎯 Create 3D - Perspective
with Transaction(doc,'Create 3D Perspective') as t:
t.Start()
view3D = View3D.CreatePerspective(doc, view_type_3D.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## 4️⃣ ViewDrafting
[ViewDrafting ](https://rvtdocs.com/2023/d0876cac-a93b-b89c-fa30-bcc14ab9d7f0)is probably the easiest one to create
👇Here is the snippet
```python
ViewDrafting.Create(doc,
viewFamilyTypeId)
```
So you already know how to creat it.
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL VIEW TYPES
view_types = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
#🔎 FILTER VIEW TYPES
view_types_drafting = [vt for vt in view_types if vt.ViewFamily == ViewFamily.Drafting]
view_type_drafting = view_types_drafting[0]
#🎯 Create Drafting View
with Transaction(doc,'Create Drafting') as t:
t.Start()
view = ViewDrafting.Create(doc, view_type_drafting.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## 5️⃣ Create View Sheet
👇Creating ViewSheet is a little different because we don't need to provide `viewType` but we need to get `TitleBlockId` instead.
```python
ViewSheet.Create(doc,
title_block.Id)
```
P.S. If you want to create a ViewSheet without title block you probably need to provide `ElementId(-1)` . I haven't tried it, but knowing Revit API this should work.
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView
active_level = doc.ActiveView.GenLevel
#🎴 ALL TITLE BLOCKS
all_title_blocks = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_TitleBlocks)\
.WhereElementIsElementType().ToElements()
if not all_title_blocks:
import sys
print('There are no TitleBlocks in the Project! \nPlease Try Again')
sys.exit()
selected_title_block = all_title_blocks[0]
#🎯 Create Drafting View
with Transaction(doc,'Create Drafting') as t:
t.Start()
new_sheet = ViewSheet.Create(doc, selected_title_block.Id)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## 6️⃣ Create Legend View
If you're trying to create a legend in Revit, the bad news is that there are no methods in Revit API for creating them.
The good news is that we can just duplicate any existing legend without detailing and we will have a new legend.
So for your tools where you want to create legends you need to verify that at least 1 Legend exists, so we can duplicate it! Otherwise, stop execution of your script and alert user that project needs to have at least 1 Legend to execute it.
👇I got all Legend views and checked if it's empty, then there are no Legends in the project and I need to alert user.
```python
# -*- coding: utf-8 -*-
#⬇ IMPORTS
from Autodesk.Revit.DB import *
from pyrevit.forms import alert
#📦 VARIABLES
doc = __revit__.ActiveUIDocument.Document
all_views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).ToElements()
all_legends = [view for view in all_views if view.ViewType == ViewType.Legend]
#✅ Check Legend in the Project
if not all_legends:
alert("There has to be at least 1 Legend View in the project! "
"Please create one and try again.", exitscript=True)
```
Once you made sure that you have a legend in the project, take a random one and just duplicate without Detailing.
And there you have it, a new empty Legend View.
```python
#👉 GET RANDOM LEGEND
random_legend = all_legends[0]
#🆕 CREATE NEW LEGEND VIEW
new_legend_view_id = random_legend.Duplicate(ViewDuplicateOption.Duplicate)
new_legend_view = doc.GetElement(new_legend_view_id)
#🔎 Change Scale
new_legend_view.Scale = 100
```
### Override Elements with Revit API (SetElementOverrides)
https://learnrevitapi.com/blog/override-graphics-in-view/
## Override Graphics
To override graphics with Revit API we need to use [**.SetElementOverrides(element_id, settings)**](https://rvtdocs.com/2023/a6f1ced3-1f1c-dd42-c0ca-f15f301d1cad) that is located inside of [**View **](https://rvtdocs.com/2023/fb92a4e7-f3a7-ef14-e631-342179b18de9)Class. It's not a complicated method but it has a lot of methods that you might need to use to create Override Settings that you want to apply to Elements.

As you can see we just need to provide [ElementId ](https://rvtdocs.com/2023/44f3f7b1-3229-3404-93c9-dc5e70337dd6)and [**OverrideGraphicsSettings**](https://rvtdocs.com/2023/eb2bd6b6-b7b2-5452-2070-2dbadb9e068a)
## OverrideGraphicSettings
First of all we need to create [**OverrideGraphicsSettings**](https://rvtdocs.com/2023/eb2bd6b6-b7b2-5452-2070-2dbadb9e068a)** **and then we can start modifying it.
```python
settings = OverrideGraphicSettigns()
```
There are a lot of different methods for [**OverrideGraphicsSettings**](https://rvtdocs.com/2023/eb2bd6b6-b7b2-5452-2070-2dbadb9e068a), but yet it's quite simple to use them.
Just think of the menu in Revit UI where you manually have to assign all of the overrides.

You will find methods in Revit API Documentation for each of the controls you have in that UI menu.
👇 Check them out here
[**OverrideGraphicSettings **](https://rvtdocs.com/2023/8dba94a9-d575-d4db-1858-dd47140efd7c)[Methods](https://rvtdocs.com/2023/8dba94a9-d575-d4db-1858-dd47140efd7c)

## How to use OverrideGraphicSettings Methods?
By looking at each method you can see arguments that you need to provide. It can be [**Color**](https://rvtdocs.com/2023/3735f9b9-d477-09ea-25bd-67f34134595f), [**LinePattern**](https://rvtdocs.com/2023/a2de5c67-d9be-760b-638a-579500216874), [**FillPatternElement**](https://rvtdocs.com/2023/64ecefd0-f5c4-5cd9-53bd-10a64739257e)…
👇 Here is a simple snippet to get everything we need and only change Surface Color of the elements.
```python
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#📦 Variables
view = doc.ActiveView
walls_in_view = FilteredElementCollector(doc, doc.ActiveView.Id) \
.OfCategory(BuiltInCategory.OST_Walls) \
.WhereElementIsNotElementType() \
.ToElements()
#🎨 Create a Color
color = Color(255, 255, 0)
#⚙️ Create Override Graphic Settings
override_settings = OverrideGraphicSettings()
#⚙️ Apply new Graphic Setting
override_settings.SetSurfaceForegroundPatternColor(color)
#🖌️ Override Elements
with Transaction(doc, 'Transaction Name') as t:
t.Start()
for wall in walls_in_view:
view.SetElementOverrides(wall.Id, override_settings )
t.Commit()
```
## Modify to your needs
The snippet above shows you the principle, but it will do just fine to start with. Then go through RevitAPI Documentation and look for methods that you most likely want to use.
I prepared another snippet for you where you can see more examples:
```python
#⬇️ IMPORTS
from Autodesk.Revit.DB import *
#📦 Variables
doc = __revit__.ActiveUIDocument.Document
view = doc.ActiveView
walls_in_view = FilteredElementCollector(doc, doc.ActiveView.Id) \
.OfCategory(BuiltInCategory.OST_Walls) \
.WhereElementIsNotElementType() \
.ToElements()
#🎨 COLORS
color_yellow = Color(255,255,0)
color_red = Color(255,0,0)
color_blue = Color(0,0,255)
#🧱 GET PATTERNS
all_patterns = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
solid_pattern = [i for i in all_patterns if i.GetFillPattern().IsSolidFill][0]
#〰️ LINES
line_patterns = FilteredElementCollector(doc).OfClass(LinePatternElement).ToElements()
random_line_pattern = line_patterns[0]
lineweight = 5
#⚙️ CREATE OVERRIDE SETTINGS
override_settings = OverrideGraphicSettings()
#⚙️ SURFACE FOREGROUND (PATTERN + COLOR)
override_settings.SetSurfaceForegroundPatternId(solid_pattern.Id)
override_settings.SetSurfaceForegroundPatternColor(color_yellow)
#⚙️ CUT FOREGROUND ( PATTERN + COLOR)
override_settings.SetCutForegroundPatternId(solid_pattern.Id)
override_settings.SetCutForegroundPatternColor(color_yellow)
#⚙️ PROJECTION LINES (Extra)
override_settings.SetProjectionLineColor(color_red)
override_settings.SetProjectionLinePatternId(random_line_pattern.Id)
override_settings.SetProjectionLineWeight(lineweight)
#⚙️ CUT LINES (Extra)
override_settings.SetCutLineColor(color_red)
override_settings.SetCutLinePatternId(random_line_pattern.Id)
override_settings.SetCutLineWeight(lineweight)
#⚙️ SET TRANSPARENCY
override_settings.SetSurfaceTransparency(50)
#🎯 MAIN
with Transaction(doc, 'Override Colours') as t:
t.Start()
#👉 OVERRIDE ELEMENT GRAPHICS IN ACTIVE VIEW
for wall in walls_in_view:
view.SetElementOverrides(wall.Id, override_settings)
t.Commit()
__author__ = '🙋♂️ Erik Frits'
```
## Match Graphic Overrides
This is even easier. To match Graphic Overrides from another element we just need to get [**OverrideGraphicsSettings**](https://rvtdocs.com/2023/eb2bd6b6-b7b2-5452-2070-2dbadb9e068a)** **and apply it to another element with or without modifying it.
```python
# ⬇️ IMPORTS
from Autodesk.Revit.DB import *
from pyrevit.revit import pick_element
#📦 Variables
doc = __revit__.ActiveUIDocument.Document
view = doc.ActiveView
element = pick_element()
#⚙️ Get Graphics
graphics = view.GetElementOverrides(element.Id)
#👉 Pick elements to match Overrides.
match_element = pick_element()
#🎯 Match Graphics
with Transaction(doc, 'Match') as t:
t.Start()
view.SetElementOverrides(elem.Id, graphics)
t.Commit()
```
### Revit API: How to change associated Level in Walls?
https://learnrevitapi.com/blog/revit-api-how-to-change-associated-level-in-walls/
## Get Parameters
First of all we need to have an element that we are going to modify. I am going to get a wall with an `ElementId`
Then we need to look inside and find parameters that we want to modify. You can do it easily with **RevitLookup** plugin that let's us `Snoop Current Selection`
`a\`
Then if you click on Definition you can see `BuiltInName` of this Parameter. Which is - `WALL_BASE_CONSTRAINT`
Then do the same to find names of `Top Constraint` parameter and `Unconnected Height`

Since these are `BuiltInParamteres` we can get them with .`get_Parameter()` method\
```python
# Get Wall
wall = doc.GetElement(ElementId(346574))
# Get Wall Parameters
wall_base = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT)
wall_top = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE)
wall_height = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM)
```
## Set New Levels
To set new levels we just going to take parameter variables we have written already and use `.Set()` method and provide `ElementId` of new levels.
```python
# Choose New Levels
new_base_level = lvls[2] # I am taking random level
new_top_level = lvls[3] # I am taking random level
# Set New Associated Levels
wall_base.Set(new_base_level.Id) # Set Base
wall_top.Set(new_top_level.Id) # Set Top
```
## Set Wall Top Constraint to None
If you want to change `Top Constraint` to `None` we need to provide `ElementId(-1)` instead of `Level.Id` This is equivalent to None in Revit API.
```python
# SET TOP: Unconnected Height
wall_top.Set(ElementId(-1)) # Set Top: None
wall_height.Set(20) # Set Unconnected Height (20 feet)
```
## Final Code:
```python
# -*- coding: utf-8 -*-
# Author: Erik Frits
from Autodesk.Revit.DB import *
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝
#====================================================================================================
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
#====================================================================================================
# Get Levels
lvls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels)\
.WhereElementIsNotElementType().ToElements()
# Create Transaction to make changes in the project.
with Transaction(doc,__title__) as t:
t.Start()
# Get Wall
wall = doc.GetElement(ElementId(346574))
# Get Wall Parameters
wall_base = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT)
wall_top = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE)
wall_height = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM)
# Choose New Levels
new_base_level = lvls[2] # I am taking random level
new_top_level = lvls[3] # I am taking random level
# Set New Associated Levels
wall_base.Set(new_base_level.Id) # Set Base
wall_top.Set(new_top_level.Id) # Set Top
# SET TOP: Unconnected Height
wall_top.Set(ElementId(-1)) # Set Top: None
wall_height.Set(20) # Set Unconnected Height (20 feet)
t.Commit()
# Author: Erik Frits
```
### Get Warnings with RevitAPI
https://learnrevitapi.com/blog/get-warnings-with-revitapi/
## Get and Sort Warnings by Type
Getting warning is not complicated, but it would make more sense to sort them by warnings types. Whenever you are going to work with warnings, you will want to focus on some types more than on others. So let's get them and sort in a dictionary.
```python
from collections import defaultdict
all_warnings = defaultdict(list)
# Sort Warnings by Type
for w in doc.GetWarnings():
description = w.GetDescriptionText()
all_warnings[description].append(w)
```
Now we have a dictionary that has warning description as a Key and a list of all warnings as a value.
We might want to get elements associated with these warnings with the following snippet.
```python
for warning_type in all_warnings:
warnings = all_warnings[war_typ]
for w in warnings:
element_ids = list(w.GetFailingElements()) + list(w.GetAdditionalElements())
elements = [doc.GetElement(e_id) for e_id in element_ids]
```
## Verify Element
Lastly, before making changes to the set of associated elements, make sure that these elements are modifiable.
For example, if you would want to Hide or Isolate these elements, you might need to check if that would even be possible.
e.g. `element.CanBeHidden(View)`
### How-To Offset CropBox of ViewPorts with Revit API
https://learnrevitapi.com/blog/how-to-change-cropbox-of-selected-viewports/
## Adjust CropBox of your selected ViewPorts.
I had multiple views that were generated by one of my script but I have not set the right offset. I did not want to generate all views and sheets again, so instead I have written this tool to quickly adjust CropBox with the same values.
I am sure you can use this example to modify for your own needs too or use it similary as I did. Just make sure you adjust hardcoded values TOP, BOTTOM, RIGHT, LEFT as you need.
```python
# -*- coding: utf-8 -*-
__title__ = "Change CropBox of Viewports."
__author__ = "Erik Frits"
__doc__ = """Version = 1.0
Date = 14.09.2022
_____________________________________________________________________
Description:
Change CropBox of Selected Viewports
_____________________________________________________________________
How-to:
-> Adjust Hardcoded values (TOP,BOTTOM,RIGHT,LEFT)
-> Select Viewports on Sheets
-> Run the script
_____________________________________________________________________
Last update:
- [14.09.2022] - 1.0 RELEASE
_____________________________________________________________________
Author Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
from Autodesk.Revit.DB import *
# pyRevit IMPORTS
from pyrevit.forms import alert
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
rvt_year = int(app.VersionNumber)
# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ Functions
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
def convert_cm_to_internal(length):
"""Function to convert cm to internal units."""
# RVT >= 2022
if rvt_year < 2022:
from Autodesk.Revit.DB import DisplayUnitType
return UnitUtils.Convert(length,
DisplayUnitType.DUT_CENTIMETERS,
DisplayUnitType.DUT_DECIMAL_FEET)
# RVT >= 2022
else:
from Autodesk.Revit.DB import UnitTypeId
return UnitUtils.ConvertToInternalUnits(length, UnitTypeId.Centimeters)
def get_selected_elements():
"""Property that retrieves selected views or promt user to select some from the dialog box."""
# GET SELECTED ELEMENTS IN UI
selected_elements = [doc.GetElement(el_id) for el_id in uidoc.Selection.GetElementIds()]
return selected_elements
# ╔═╗╔═╗╔╗╔╔╦╗╦═╗╔═╗╦ ╔═╗
# ║ ║ ║║║║ ║ ╠╦╝║ ║║ ╚═╗
# ╚═╝╚═╝╝╚╝ ╩ ╩╚═╚═╝╩═╝╚═╝ CONTROLS
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
__controls__ = """
ADJUST THESE VALUES AS YOU WANT.
You can use Positive, Negative and Zero values"""
TOP = convert_cm_to_internal(0)
BOTTOM = convert_cm_to_internal(-10)
RIGHT = convert_cm_to_internal(0)
LEFT = convert_cm_to_internal(0)
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if __name__ == '__main__':
# GET SELECTED VIEWPORTS
selected = get_selected_elements()
selected_viewports = [i for i in selected if type(i) == Viewport]
# VERIFY THAT VIEWPORTS WERE SELECTED
if not selected_viewports:
alert("No ViewPorts were selected.\nPlease, try again.", exitscript=True)
# START TRANSACTION
with Transaction(doc,__title__) as t:
t.Start()
# LOOP THROUGH SELECTED VIEWPORTS
for vp in selected_viewports:
view.CropBoxActive = True #FIXME This might give an error if View has ScopeBox
# GET VIEW CROPBOX
view_id = vp.ViewId
view = doc.GetElement(view_id)
view_bb = view.CropBox
# CREATE NEW BOUNDING BOX
BB = BoundingBoxXYZ()
BB.Min = XYZ(view_bb.Min.X + LEFT , view_bb.Min.Y + BOTTOM , view_bb.Min.Z)
BB.Max = XYZ(view_bb.Max.X + RIGHT , view_bb.Max.Y + TOP , view_bb.Max.Z)
# APPLY NEW BOUNDING BOX
view.CropBox = BB
t.Commit()
```
### How to Get All Categories in Revit API?
https://learnrevitapi.com/blog/get-all-categories-in-revit-api/
## Let's get Categories!
We can get all categories from our Document by looking in [Settings ](https://rvtdocs.com/2023/1581b3ec-eaef-9ad9-3d57-cf75a4f09b58)for [Categories ](https://rvtdocs.com/2023/d390ecf6-e5db-d7c1-d7f2-766c0686e975)property.
```python
# GET ALL CATEGORIES
all_categories = doc.Settings.Categories
# FILTER TO ANNOTATION CATEGORIES
cats_model = [cat for cat in all_categories if cat.CategoryType == CategoryType.Model]
cats_annotation = [cat for cat in all_categories if cat.CategoryType == CategoryType.Annotation]
cats_analytical = [cat for cat in all_categories if cat.CategoryType == CategoryType.AnalyticalModel]
cats_internal = [cat for cat in all_categories if cat.CategoryType == CategoryType.Internal]
```
Now we have all categories sorted in different lists. Let's go trough them and print the results.
### Model Categories
```python
# PRINT ALL INSTANCES OF MODEL CATEGORIES
for cat in cats_model:
print(cat.Name)
```
```python
Abutments
Air Systems
Air Terminals
Analysis Display Style
Analysis Results
Areas
Bearings
Bridge Cables
Bridge Decks
Bridge Framing
Cable Tray Fittings
Cable Tray Runs
Cable Trays
Casework
Ceilings
Columns
Communication Devices
Conduit Fittings
Conduit Runs
Conduits
Coordination Model
Curtain Grids
Curtain Panels
Curtain Systems
Curtain Wall Mullions
Data Devices
Detail Items
Doors
Duct Accessories
Duct Fittings
Duct Insulations
Duct Linings
Duct Placeholders
Duct Systems
Ducts
Electrical Circuits
Electrical Equipment
Electrical Fixtures
Electrical Spare/Space Circuits
Entourage
Expansion Joints
Filled region
Fire Alarm Devices
Flex Ducts
Flex Pipes
Floors
Furniture
Furniture Systems
Generic Models
HVAC Zones
Imports in Families
Lighting Devices
Lighting Fixtures
Lines
MEP Fabrication Containment
MEP Fabrication Ductwork
MEP Fabrication Hangers
MEP Fabrication Pipework
Masking Region
Mass
Materials
Mechanical Equipment
Mechanical Equipment Sets
Nurse Call Devices
Parking
Parts
Piers
Pipe Accessories
Pipe Fittings
Pipe Insulations
Pipe Placeholders
Pipe Segments
Pipes
Piping Systems
Planting
Plumbing Fixtures
Point Clouds
Project Information
RVT Links
Railings
Ramps
Raster Images
Rebar Shape
Roads
Roofs
Rooms
Routing Preferences
Security Devices
Shaft Openings
Sheets
Site
Spaces
Specialty Equipment
Sprinklers
Stairs
Structural Area Reinforcement
Structural Beam Systems
Structural Columns
Structural Connections
Structural Fabric Areas
Structural Fabric Reinforcement
Structural Foundations
Structural Framing
Structural Path Reinforcement
Structural Rebar
Structural Rebar Couplers
Structural Stiffeners
Structural Tendons
Structural Trusses
Switch System
Telephone Devices
Topography
Vibration Management
Walls
Water Loops
Windows
Wires
Zone Equipment
```
### Annotation Categories
```python
# PRINT SORTED CATEGORIES
for cat in sorted(cats_annotation, key=lambda x: x.Name):
print(cat.Name)
```
```python
Abutment Foundation Tags
Abutment Pile Tags
Abutment Tags
Abutment Wall Tags
Adaptive Points
Air Terminal Tags
Alignment Station Label Sets
Alignment Station Labels
Alignment Tags
Alignments
Analytical Beam Tags
Analytical Brace Tags
Analytical Column Tags
Analytical Floor Tags
Analytical Isolated Foundation Tags
Analytical Link Tags
Analytical Node Tags
Analytical Slab Foundation Tags
Analytical Wall Foundation Tags
Analytical Wall Tags
Anchor Tags
Annotation Crop Boundary
Approach Slab Tags
Area Load Tags
Area Tags
Assembly Tags
Bearing Tags
Bolt Tags
Brace in Plan View Symbols
Bridge Cable Tags
Bridge Deck Tags
Bridge Framing Tags
Cable Tray Fitting Tags
Cable Tray Tags
Callout Boundary
Callout Heads
Callouts
Cameras
Casework Tags
Ceiling Tags
Color Fill Legends
Communication Device Tags
Conduit Fitting Tags
Conduit Tags
Connection Symbols
Contour Labels
Crop Boundaries
Curtain Panel Tags
Curtain System Tags
Data Device Tags
Detail Item Tags
Dimensions
Displacement Path
Door Tags
Duct Accessory Tags
Duct Color Fill
Duct Color Fill Legends
Duct Fitting Tags
Duct Insulation Tags
Duct Lining Tags
Duct Tags
Electrical Equipment Tags
Electrical Fixture Tags
Elevation Marks
Elevations
Expansion Joint Tags
Fire Alarm Device Tags
Flex Duct Tags
Flex Pipe Tags
Floor Tags
Foundation Span Direction Symbol
Furniture System Tags
Furniture Tags
Generic Annotations
Generic Model Tags
Grid Heads
Grids
Guide Grid
Hole Tags
Internal Area Load Tags
Internal Line Load Tags
Internal Point Load Tags
Keynote Tags
Level Heads
Levels
Lighting Device Tags
Lighting Fixture Tags
Line Load Tags
MEP Fabrication Containment Tags
MEP Fabrication Ductwork Tags
MEP Fabrication Hanger Tags
MEP Fabrication Pipework Tags
Mass Floor Tags
Mass Tags
Matchline
Material Tags
Mechanical Equipment Set Boundary Lines
Mechanical Equipment Set Tags
Mechanical Equipment Tags
Multi-Category Tags
Multi-Rebar Annotations
Nurse Call Device Tags
Panel Schedule Graphics
Parking Tags
Part Tags
Path of Travel Tags
Pier Cap Tags
Pier Column Tags
Pier Foundation Tags
Pier Pile Tags
Pier Tags
Pier Tower Tags
Pier Wall Tags
Pipe Accessory Tags
Pipe Color Fill
Pipe Color Fill Legends
Pipe Fitting Tags
Pipe Insulation Tags
Pipe Tags
Plan Region
Planting Tags
Plate Tags
Plumbing Fixture Tags
Point Load Tags
Profile Tags
Property Line Segment Tags
Property Tags
Railing Tags
Rebar Cover References
Rebar Set Toggle
Reference Lines
Reference Planes
Reference Points
Render Regions
Revision Cloud Tags
Revision Clouds
Roof Tags
Room Tags
Schedule Graphics
Scope Boxes
Section Boxes
Section Line
Section Marks
Sections
Security Device Tags
Shear Stud Tags
Site Tags
Space Tags
Span Direction Symbol
Specialty Equipment Tags
Spot Coordinates
Spot Elevation Symbols
Spot Elevations
Spot Slopes
Sprinkler Tags
Stair Landing Tags
Stair Paths
Stair Run Tags
Stair Support Tags
Stair Tags
Stair Tread/Riser Numbers
Structural Annotations
Structural Area Reinforcement Symbols
Structural Area Reinforcement Tags
Structural Beam System Tags
Structural Column Tags
Structural Connection Tags
Structural Fabric Reinforcement Symbols
Structural Fabric Reinforcement Tags
Structural Foundation Tags
Structural Framing Tags
Structural Path Reinforcement Symbols
Structural Path Reinforcement Tags
Structural Rebar Coupler Tags
Structural Rebar Tags
Structural Stiffener Tags
Structural Tendon Tags
Structural Truss Tags
System-Zone Tags
Telephone Device Tags
Text Notes
Title Blocks
Vibration Damper Tags
Vibration Isolator Tags
View Reference
View Titles
Viewports
Wall Tags
Weld Tags
Window Tags
Wire Tags
Zone Tags
```
### Analytical Categories
```python
# PRINT SORTED CATEGORIES
for cat in sorted(cats_analytical, key=lambda x: x.Name):
print(cat.Name)
```
```python
Analytical Beams
Analytical Braces
Analytical Columns
Analytical Floors
Analytical Foundation Slabs
Analytical Isolated Foundations
Analytical Links
Analytical Nodes
Analytical Pipe Connections
Analytical Surfaces
Analytical Wall Foundations
Analytical Walls
Boundary Conditions
Structural Internal Loads
Structural Load Cases
Structural Loads
System-Zones
```
### Internal Categories
```python
# PRINT SORTED CATEGORIES
for cat in sorted(cats_internal, key=lambda x: x.Name):
print(cat.Name)
```
```python
Assemblies
Model Groups
Schedules
Views
```
## How do we use categories?
There are many applications to categories. Since you found this article through google, I assume you already have an idea in mind, how you would want to use these categories.
But I will leave here a simple example how to hide certain categories from a View.
```python
# START TRANSACTION
t = Transaction(doc, __title__)
t.Start()
# GET ANNOTATION CATEGORIES
all_categories = doc.Settings.Categories
cats_annotation = [cat for cat in all_categories if cat.CategoryType == CategoryType.Annotation]
# HIDE ANNOTATION CATEGORIES EXCEPT SECTIONBOX
exclude = [BuiltInCategory.OST_SectionBox]
for cat in cats_annotation:
if cat.BuiltInCategory in exclude:
continue
view.SetCategoryHidden(cat.Id, True)
t.Commit()
```
### Get ViewSheet from a given View
https://learnrevitapi.com/blog/get-viewsheet-from-given-view/
## About snippet:
I assume you were looking on the internet how to get `ViewSheet` from a given `View` just like I was doing it before I decided to create my own solution and post it for you.
I feel like there is not much for me to explain since most of the work here is done with `FilteredElementCollector(doc).WherePasses(filter)` and **filters** deserve their own article and even a video explaining them with lots of examples.
So you can use the code below and adapt it in your own scripts.
## PyRevit example script
```python
# -*- coding: utf-8 -*-
__title__ = "Get sheet from View"
__author__ = "Erik Frits"
#>>>>>>>>>>>>>>>>>>>> IMPORTS
import clr, os
from Autodesk.Revit.DB import *
#>>>>>>>>>>>>>>>>>>>> VARIABLES
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
#>>>>>>>>>>>>>>>>>>>> FUNCTIONS
def create_string_equals_filter(key_parameter, element_value, caseSensitive = True):
"""Function to create ElementParameterFilter based on FilterStringRule."""
f_parameter = ParameterValueProvider(ElementId(key_parameter))
f_parameter_value = element_value
caseSensitive = True
f_rule = FilterStringRule(f_parameter, FilterStringEquals(), f_parameter_value, caseSensitive)
return ElementParameterFilter(f_rule)
def get_sheet_from_view(view):
#type:(View) -> ViewPlan
"""Function to get ViewSheet associated with the given ViewPlan"""
#>>>>>>>>>> CREATE FILTER
my_filter = create_string_equals_filter(key_parameter=BuiltInParameter.SHEET_NUMBER,
element_value=view.get_Parameter(BuiltInParameter.VIEWER_SHEET_NUMBER).AsString() )
#>>>>>>>>>> GET SHEET
return FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType()\
.WherePasses(my_filter).FirstElement()
#>>>>>>>>>>>>>>>>>>>> MAIN
if __name__ == '__main__':
#>>>>>>>>>> ACTIVE VIEW
active_view = doc.ActiveView
sheet = get_sheet_from_view(active_view)
#>>>>>>>>>> PRINT RESULTS
if sheet: print('Sheet Found: {} - {}'.format(sheet.SheetNumber, sheet.Name))
else: print('No sheet associated with the given view: {}'.format(active_view.Name))
```
### Update ProjectBrowser with RevitAPI
https://learnrevitapi.com/blog/update-projectbrowser-with-revitapi/
## SheetNumber does not update.
You have probably made your script to change SheetNumber with RevitAPI but nothing happened after running your script.
As usual, you open your code and look for clues what could have gone wrong and probably find nothing...
This happens because ProjectBrowser does not update itself after SheetNumber is changed with your code. Hopefully, in the near future, someone from Autodesk will solve it, but for now, we have to do it ourselves.
## Solution
When I first encountered this behavior, I thought my code was wrong.
Hopefully, quite soon I have noticed with my test print() statements that actually it changes SheetNumber but does not display new SheetNumber in the ProjectBrowser.
After trial and error, I have discovered that hiding and reopening Project Browser solved the issue. The question now, how do we solve it in the code so our users won't panic and click on the button over and over hoping for better results?
This is very simple. All we need to do is to find our **ProjectBrowser** in BuiltInDockablePanes, use **`Hide()`** and execute your code for changing SheetNumber and then bring it back with **`Show()`** so people won't get scared that their ProjectBrowser has disappeared.
Here is a snippet below:
```python
from Autodesk.Revit.UI import DockablePanes, DockablePane
project_browser_id = DockablePanes.BuiltInDockablePanes.ProjectBrowser
project_browser = DockablePane(project_browser_id)
project_browser.Hide()
# change 'ViewSheet.SheetNumber' here
project_browser.Show()
```
### Match View's cropbox shape
https://learnrevitapi.com/blog/match-views-cropbox-shape/
## CropBox
Here is a simple way to get Match your [CropBox ](https://rvtdocs.com/2023/d6246051-ecfb-7388-0429-6ed65de72638)to another view. Also it's good to know that CropBox has a class of [BoundingBoxXYZ](https://rvtdocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2).
You just need to provide 2 views in this function to match **CropBox.**
There is a method view.[GetCropRegionShapeManager](https://rvtdocs.com/2023/e2f53728-9b72-227a-f585-9dccf6d79d9f)() that allows us to .[GetCropShape](https://rvtdocs.com/2023/36a98b08-72be-4b0a-99f6-4a765b85b15d)() and to [SetCropShape](https://rvtdocs.com/2023/548c4181-2779-40a2-8276-b7a43a85a161)().
```python
def match_cropbox_shape(source_view, view):
# type: (View, View) -> None
"""Function to match cropbox shape outline from source view to another view."""
source_CropManager = source_view.GetCropRegionShapeManager()
source_CropShape = source_CropManager.GetCropShape()
CropManager = view.GetCropRegionShapeManager()
CropManager.SetCropShape(source_CropShape)
```
### Get CropBox Id in Revit with Python.
https://learnrevitapi.com/blog/revitapi-get-cropbox-id/
### **1️⃣ FilteredElementCollector.Excluding()**
The first method is quite straight forward and goes like this:
1. Hide the CropBox
2. Use** **[**FilteredElementCollector(doc, view_id)**](https://rvtdocs.com/2023/6359776d-915e-f8a2-4147-b31024671ee1) to collect all elements you can see in the view.
3. Unhide the CropBox
4. Use FilteredElementCollector again, but this time exclude elements you collected the first time with [**.Excluding(element_ids) **](https://rvtdocs.com/2023/80e23fdc-c005-163b-5643-38d84411a73d)
5. Get ElementId of the CropBox from the collection.
6. Lastly, [**RollBack **](https://rvtdocs.com/2023/bd1e69e9-961e-1c07-f70a-a29b90c6eb97)your [**Transactions **](https://rvtdocs.com/2023/308ebf8d-d96d-4643-cd1d-34fffcea53fd)so nothing has changed.
```python
def GetViewCropBoxElement(view):
"""Function to get a cropbox_id from the given view."""
tGroup = TransactionGroup(doc, "Py: Get cropbox_id")
tGroup.Start()
trans1 = Transaction(doc, "temp")
trans1.Start()
view.CropBoxVisible = False
trans1.Commit()
shown_elements_ids= FilteredElementCollector(doc, view.Id).ToElementIds()
trans1.Start()
view.CropBoxVisible = True
trans1.Commit()
cropbox_id= FilteredElementCollector(doc, view.Id).Excluding(shown_elements_ids).FirstElementId()
tGroup.RollBack()
return cropbox_id
```
This method is a bit messy because of multiple transactions. So I have another option.
### **FilteredElementCollector.WherePasses()**
I have found an article by Jeremy Tammik - ["Efficiently Retrieve Crop Box for Given View"](https://thebuildingcoder.typepad.com/blog/2018/02/efficiently-retrieve-crop-box-for-given-view.html) in C#.
So I've translated it to python for people who don't "speak" C# well enough. I encourage you to read his article to better understand the logic behind this function.
Be aware that **FilteredElementCollector **will grab **CropBox** and **View **so be aware of that.
```python
def get_cropbox_id(view):
"""Function to get cropbox_id of a given view."""
provider = ParameterValueProvider(ElementId( int(BuiltInParameter.ID_PARAM)) )
rule = FilterElementIdRule(provider, FilterNumericEquals(), view.Id)
param_filter = ElementParameterFilter(rule)
collector = FilteredElementCollector(doc).WherePasses(param_filter).ToElementIds()
if collector:
for id in collector:
if id != view.Id:
return id
```
## Podcast
### Behind the scenes of pyRevit Development with Roman Golev (pyRevit Pod-16)
https://learnrevitapi.com/podcast/py-pod-16-roman-golev/
### Revit Add-Ins That Test Themselves (Local LLMs + Mac Setup) [pyRevit Pod-15]
https://learnrevitapi.com/podcast/py-pod-15-yuusuf-dahlstrand/
Yuusuf Dahlstrand on Revit add-ins that test themselves, running local LLMs for Revit development and a Mac setup that works. pyRevit Podcast #15.
### The Creator of pyRevit MCP on Real Limits of AI in Revit [pyRevit Pod 14]
https://learnrevitapi.com/podcast/py-pod-14-juan-david-rodriguez/
Juan David Rodriguez, creator of pyRevit MCP, on what AI can and cannot do in Revit today and how MCP connects agents to your model. pyRevit Podcast #14.
### pyRevit + AI For Electrical Fabrication (pyRevit Pod#13)
https://learnrevitapi.com/podcast/py-pod-13-manuel-olvera/
Manuel Olvera on using pyRevit and AI for electrical fabrication: the tools he builds to automate fabrication workflows in Revit. pyRevit Podcast #13.
### The Journey of pyRevit Challenge Hackathon Winner [pyRevit Podcast #12]
https://learnrevitapi.com/podcast/py-pod-12-hackathon-winner/
Dimitris Koumantakis, winner of the first pyRevit Challenge hackathon, shows the tool he built and shares his journey into Revit automation. Podcast #12.
## Transcript
Are we live? Yes, we are live. Hello everybody. Welcome, welcome. So today we have parade podcast number 12 and I have a guest quite special I think to me because I recently ran a par challenge hackathon >> live and this is the first winner of the first par challenge hackathon so we're going to talk about this more this is not coming from parv team I think I should mention that it's coming directly from me I teach parade I'm not part of par development team not part of par let's say we're just friends with parade so the guest his name is uh Dimmitri and I just need to bring him on the screen.
So Dmitri commentis sorry if I pronounce it that but I hope that was good. [clears throat] >> It's fine. >> Welcome to the show. How you doing? >> Hi Erik.
Thank you for having me on the podcast. I'm very happy about it. >> Likewise. Likewise. >> Super excited to have you here.
Where are you right now? >> It's nice. Um, right now I'm actually living in Copenhagen, Denmark, so I think we actually have the same time. >> The weather is nice. >> Yeah, >> today is good.
Yeah. >> Yeah, that's awesome. So, uh, recently, I think when was it? It was like one and a half months ago. We run the spirit challenge hackathon and we had about I think 13 people participated and you won that thing.
So I think it would be great start to just kind of share what kind of tool you made and show people what is the tool, how it works and then later we're actually going to focus on you go in your journey that led to that one. So they have kind of the baseline to see where it all kind of started. Uh just give me a second now. Yeah, now we can see your screen. >> Yeah.
>> Yeah. So I'm not sure if I should do the introduction now in a way why I'm actually you know I was thinking what to actually when I saw your you know challenge I was like I have to you know [clears throat] come up with something but in my everyday work I'm you know usually doing MEP stuff in Revit and I had some tools already and I was like maybe I can do something similar or a new one but I was like I have to find an idea that speaks to everyone you know a problem that everyone but you know every user regard you know have if you are an architect on MEP designer or anything so I was like what's the most thing I have felt in the past that annoyed me a lot and of course it was you know trying to find things that appear in one view and then you go to a floor plan and it's not there and you're like why why this happens I can see it on the other view it's fine and then it's you know one thing that is missing or two things or a whole category of things so what that's where the idea actually came from so without going into specifics maybe from now what it actually does for example This is a floor plan view. I just opened the the sample [clears throat] actually modeled. So let's see something here. Now everything is you know visible in a way but let's let's make another view.
I cannot do it the resting. Don't worry. Sometimes I I forget where the [clears throat] buttons and >> that selection box doesn't want to open. See, maybe I need to find >> Yeah. While you do that, I just want to comment that >> you mentioned that you're trying to find the problem to >> Yeah.
Yeah. Take your time. mentioned that you're trying to find a problem to actually focus on to solve and you really nailed that part. >> There is nothing in me here. >> Let me open another file.
This one that should be fine. Yeah, let's give a moment to Dimmitri to >> so the tool >> Oh, you're showing it. >> You know, we had this idea in in principle. So, you miss something from one of you and you try to find it in the other. You know, usually you have to look into if a category is on and off, filters, model, model categories, sometimes annotation categories, maybe the view range, sometimes it's off and you cannot [clears throat] find anything.
So let's see. So we have these view. Okay, this architectural so should work. [snorts] So let's say these tables. We have a 3D view, but we can see them.
All right. And let's start with the most annoying thing for me. You know, people sometimes like to just go and just right click and because they don't like something to hide it. I'm sure you have seen that a lot of times. >> Oh, I've I've done it a lot of [laughter] times.
>> So, you actually like Okay, I'm not seeing these ones, but I can see the other tables. So, what's the difference? So, you double check the view. Of course, there is maybe a view template you're not sure about. So, you go in just remove the template.
So you just check okay furniture is on it should see everything everything is open. So you don't know what it is exactly now we know but so let's start the tool. So the first thing we have to do is to pick the element we want to actually find out why it's hidden. I selected the specific table and now we have to select where it is actually missing and we can either search the view and it should be this one L1 floor plan I think and we press analyze and then we get some blockers as I called them. So element is hidden is in view.
So it says that this element is hidden in individually and in some cases most cases I have put an button that can fix that automatically. >> Mhm. >> It also saying that it's outside the crop region. Sometimes I think it gets that even if it's not exactly true. But if I just press fix just press okay and it returns me to the previous view.
And now you can actually see that it's back. So in a way that's the that's the tool. Oops. It is checking I have also put like a list of what is actually checking. So it's checking if the element can actually appear in other views.
So some tags for example are view specific so they will not appear in another view and they shouldn't appear in another view. Now the element is not individually hidden because we actually fixed that. It checks if the category of the picked element is visible in the view. It also checks about if there is a special view filter and when there is one it can usually say which one and you can also change it. >> Mhm.
>> Yeah. If it's a if the object is in a closed workshet in that specific view the phase is off you know all kind of things you can maybe >> Yeah. So pretty much what your tool does is kind of goes one check check check by check and like okay this works this works this works. Oh category is not showing. Oh, maybe it's hidden in view.
Because that's what we do manually anyway. Like when something is not showing, we go through this endless list. A lot of people, I'm sure, have it somewhere on their desk. There's like a little paper. Okay.
Like follow these steps to find it. I had this paper for a while then I just got used to that. Yeah. >> Now this is really amazing too when when people make these kind of tools and like you mentioned you focused on the problem first of all and you you nailed it because I personally was like swearing at Autodesk why there is no such feature. It shouldn't be like for them well it's not that complicated but alo not that simple but for them it shouldn't be complicated at all and I was just like oh come on there should be something like that.
when you just submitted this tool, I saw it for the first time. I'm like, finally, I I was wanted to see something like this. >> Yeah, that's that's great. And I actually didn't expect to, you know, I had very low expectations on how what we will actually take, but then it you could grow it bigger and bigger and it was I tried to expand it as much as possible in that few days. was two weeks I think maybe but okay like >> quite a while >> I think I worked like oh I mean the pirate challenge it was running for two weeks maybe if I remember correctly >> h you mean the hackathon itself or >> yeah the the hackathon sorry >> uh yeah I think so I gave some extra time so people can have more weekends because uh a lot of people had very busy schedules couldn't participate it also was like vacation times a lot of people went on vacation like before, after, during and like a lot more people wanted to participate.
But yeah, actually it turned quite well. I think we were 13 participants and I think it's also worth maybe sharing all the tools or would you like to share something else about this tool in general or that's the main target of the main you know synopsis of what it does but uh I think I maybe showed the most easy fix but you can also recheck stuff if you need to. Mhm. >> You may get some errors. Of course, it's a hackathon results.
So, >> oh yeah, things may not work, you know, perfectly, >> but that's the main thing. It tries to check everything. I most of the things, >> but the only thing that it doesn't work, and I actually had that today at my work, a colleague said to me, can I use it? And I was like, yeah, of course. But uh it was a linked element so it doesn't work with links because >> I couldn't find a way to expose you know visibility settings from things.
>> Mhm. >> But I I to be honest I didn't try that much but I thought let's leave linked elements for you know for another time or you know next. >> Yeah that's totally fair. >> Yeah but that's that's the main idea. >> No no it's great.
I mean, I love it once you submit it. I knew that it's going to be top three. Didn't know if it wins or not because also I haven't seen a lot of other tools before that. But I just saw like it's just like the pain itself. I was like, "Oh, this this really hits the right kind of pain point for a lot of people." And we saw it like a lot of people actually based on it kind of worked.
Just going to quickly share a little bit more context maybe about the hackathon itself. This is skipped it a little bit too fast. Just going to show you. So I'm also going to give a little history to what's even happening. So I had a training which is called pyro challenge where we went through 21 tools and it took way longer than 21 days to produce it because I I made it few tools.
I launched it got the first group and started doing so it took a bit longer but the idea was like we focused on actually creating tools from scratch. we kind of skip the theory and my idea was like if you just start doing it and you see how it's done and I provide all the support people learn faster and it worked but it was definitely more challenging and effort and in the end we just made the hackathon people I just pretty much said like hey the only criteria is just make useful tool for ravit users that's it and this is the submissions we got so Dimmitri is the winner with a why not here and then there are also the Marin Marik the second place with the filterman there's a uh everything is available right here on www.vote.learnabi.com. There's no login, nothing. You just go in there. Maybe I show from the start.
Just click here on hackathon number one. You're going to get inside. You're going to see all the tools, all the source code available. You can download everything. So, Marcen Mark made uh very neat tool for selecting elements also.
Welld deserved. Second place. So, this is very advanced kind of element selection based on parameters. He also embedded somehow kind of the sort of like exo link inside of there. He really pushed it like to the limits.
Uh just to save time I'm just going to briefly explain but you can see here gave some parameters this category. I think there's also parameter values and just isolated colored it and stuff like that. Very cool tool. Congratulations. >> Congratulation Marson.
And the third one won it was by Justin B. And this is family purify. Another very kind of this painful topic for people who work with families a lot. Oops. Maybe sound off.
Just going to briefly go through the winners and then the others uh the video. So this one pretty much goes through the families sees okay this is the current state. These are the things we can clean up the parameters we can clean up. Can see here is the UI image. So there's like different cleanups.
Remove CAD imports. Remove images and use materials. Advanced cleanup. There's also parameter standardization. Uh this is also a very cool tool again for people who manage families.
This one is really really a good thing. So yeah, these are the winners. The other tools I have I had a whole kind of live video going through all the tools kind of showing but all the others want they are not in the winning. They're just random. I just don't want to show like this is the fourth, this is the last one.
I think it's more fair to see like all of them like that. And yeah and people voted. It's not me. I just voted everyone 10 because for me everybody who submits a winner because it takes the effort it takes how to put it um it's an accomplishment in itself just to submit the tool to see like you went for the training you submitted the tool you're like okay I made it that's done and now it's public because many people made the tools but some of them did not want to put it in public there's some kind of fear what if people look at my code and think it's horrible or something But two works that's great in my book. Yeah.
So that's shortly about the hackathon and par challenge in general. Not going to go really into that. Today we are mostly focusing on Dimmitri the winner because I really want to get into his journey see where he comes from and stuff like that. Um we jumped a little bit maybe too quick right into the tool because I was a bit stressed because of the technical issues we had. So could you maybe introduce yourself a little bit better?
Like not not better but just introduce yourself because we skipped it by accident. >> Yeah, of course. You already know my name is Dimitris. I come originally from Greece and the last five years I'm here in Copenhagen working. I'm also I studied civil engineering or structural engineer you could say and [clears throat] >> Mhm.
Where do you where do you work right now? >> Right now I'm working at a consulting company here in Copenhagen and engineering consulting and I'm actually working as a beam specialist. >> Um you know I have Revit open every day. the first thing I open maybe even before teams or outlook. >> Oh yeah.
>> But yeah, I'm working mostly with any fee but also construction and a little bit less architectural. But Revit is kind of life now. >> But uh it's funny because it wasn't before. I was, you know, as a civil engineering engineer was actually using a lot of AutoCat >> in Greece and, you know, Revit was an idea that was flying around, you know, there is a tool that is 3D and can make things, you know, like actual walls and objects and not just lines and like, yeah, I should learn it at some point. And now here we are >> every day using Revit.
>> So if I create a timeline, what year are we talking about? This kind of when you worked in AutoCAD before you started with Revit. >> I actually I think I actually started working, you know, more seriously with Revit the last five years. Five, six, maybe, maybe five. I I knew some but you know I never you know went into it that much because it wasn't needed back then.
Uh everything was mostly you know auto back in Greece. I know now they are using it a lot maybe much more. >> Mhm. >> But uh I mean I mean I still use auto every day almost. >> Okay.
>> But uh so the last five years you could say sums up my Revit experience. >> All right. So you worked in Greece. You didn't really touch Ravit. I assume Ravit came along as you started moving to Denmark or what?
>> It was actually one thing that I thought you know I have to get on top of it so I can actually get hired because it was a requirement I think for you know and it's difficult when you do not have work experience to actually build enough work experience with Revit to you know >> persuade someone that you actually know how to use it. I started making some portfolio, you know, tutorials and everything. >> So, you did like personal projects at home in the evenings, it wasn't part of the your professional job. >> Yeah. Yeah.
Exactly. >> And that landed you a job in straight into Ravit. >> Yeah. Because if you think about it, if I start after university, >> uh then after civil engineering, I did a master's degree in it was called tech, [clears throat] it's called technomic systems. So it was kind of an MBA for engineers.
So but it was in the school of electrical engineering. So it had a lot of you know for courses also in so not software exactly but the logic behind algorithms and systems and stuff like that. >> Mhm. >> But it was very and multi-in disciplinary thing. So actually after that I started working as a you know regular civil engineer with going out on the site with a laser measure and start measuring buildings and then go back to my house and started drafting up plans and I was like oh why this rectangle doesn't close now and you know go back to the site so it was mostly making drawings in order that sitting around to make the lines fit perfectly and calculate areas and stuff and it was that was life for some years and then I started working on a small renovation company.
So I actually had to go on site, help out a little bit there, see how things progress. But I was doing a lot of plans and maybe you know cost estimation, you know, after after making up the drawing started, you know, to measure wall surfaces and how much painting will cost and materials and stuff like that. >> And that was my big step before I went to I came to to Denmark which I actually followed my wife now which was she was already studying here and later found a job. So it was a big decision to come here and uh in the first years of course you know changing a country is kind of tough in finding job of course especially when you are not speaking the language and Danish are quite tough the Danish language so I'm still struggling of course I'm not really speaking Danish I could say but I do understand some things so it helps with for but the good thing uh you know Dan are talking perfect English so you can >> oh yeah >> communicate very [clears throat] easily so it wasn't that that bad but it was a blogger >> to in order to actually land a job >> yeah it's a funny language it's like look how it's I I I studied in Denmark so I I can relate a little I forgot almost all my well not almost all my Danish I don't remember even though I didn't speak it well but I I remember like on one of the first lessons of Danish they were like look at this how it's written and I think it was like my name is like or something like this look at how it's written forget how it's written this is how it sounds this was our teacher and I'm like okay welcome to Denmark >> exactly >> yeah the language is a bit tough but I never had issues like with English everyone's like says like oh no my English is bad and then they speak perfect English like they're from England and I'm like >> yeah yeah >> that's also there is like a It amazed me sometimes, you know, I went to banks, you know, to set up bank accounts and I was like, I think I saw, you know, an old lady. I was like, she's not going to speak English.
I will have a problem now. What should I do? And then she spoke much better than me and I was so embarrassed that I thought, you know, >> but it's that's also very helpful. But >> Oh, yeah. Yeah.
It's amazing. Yeah. Yeah, what you mention also what you mentioned is interesting that you studied Ravit on your own before coming to Denmark because in Denmark they learn Ravit pretty much in universities right away. I studied there there's like it's not architecture not engineering something in between. It's like construction management and architectural technology and construction management.
>> So they this specific training that's very common one it trains you sort of to be between like client architect and engineer. So you can understand a little bit of all the world and you can actually put it in Ravit and do all the calculations all the analysis sheets and stuff like that apply. So, it's a lot of things. And uh even though we started using Ravit right away, almost nobody knew anything about construction at first. Like it was just like using software to build buildings without knowing how to build buildings.
And I treat it like a game so it kind of worked. But some people struggled a lot more with RA because we had it was like weird learning how to build buildings without knowing how to build buildings like I mean like in software. So I think you had like the engineering background behind you when you started learning Ravit. You just learned it completely different than people who just kind of start learning everything at the same time. >> Yeah, I think it was but to be honest it wasn't because of the actual you know studying.
I think it was actually when I started renovation work then I actually understood what happens inside a building because you know in university when you're studying civil engineering or architectural engineering engineering or anything you are not it's so much about how what is going on in the building like you know there are also pipes in the building that have to be taken care of or something like that >> or spaces for that. So I think it help a lot to understand you know how things are built and be able to draw a little bit better >> you know in Revit >> it helps to have a better understanding of what you are drawing. >> Oh yeah 100%. >> Yeah. >> It's night and day once you actually realize.
I'm like oh that's why they were telling us to do that and I always ignored it. [laughter] [snorts] >> Yeah. Yeah. And you know things starting to click. Oh, that's why they told us that's in university.
But I think I'm still trying to learn a lot. I mean, >> construction as well. And MEP was, you know, a complete dive into something unknown to me because before I didn't, you know, I didn't know I I did know that pipes existing in the building, but I never thought about where they actually go. >> Oh, so you learned MEP on the go at the job? >> Yeah.
Yeah. Ah, I thought you had an additional training on that. >> No, I actually I think it was, you know, just dive into the work. >> No, that's cool. >> To be honest, it's a little bit embarrassing, but I think I actually, you know, had to ask how to draw a pipe.
Which tab do you use the first time? I think I started using it. But uh yeah, it was a whole different experience because you know I think everyone that starts learning Revit is usually just using the architecture tab. I don't think a lot of people actually click the other tabs and it was the same for me. So you know architecture structure so I never actually had gone to systems before >> and so it was an experience of course.
Yeah, I had this also. I click on the pipe, I draw it, it's not in the view. I'm like, great, now I need to find it because it goes sometimes. >> Exactly. You start to look at it and you're like, what is that?
What is a pipe accessory? What is a flex pipe? Of course, now it's, you know, everyday life, but >> Yeah. >> Yeah. So, and so you started working in RO getting better, you switched to MEP, where does kind of programming come in?
you already had any did you have any kind of Python knowledge before or you just kind of learned it al also on the go >> kind of but uh I was actually thinking because I was thinking hard to actually pinpoint how my programming journey started in a way because I know you asked me that question. I was really thinking, you know, what was the first thing I actually did that had to do with programming? And I was thinking and thinking, you know, I always like to be, you know, a computer enthusiast, you could say, you know, trying uh setting up stuff in the computer, games, everything or meddling with files to do different stuff. I think in high school I started my main PC experience was games and video editing. You know, >> back then it was the big thing to just have video effects, you know, special effects like with After Effects and stuff.
Simple things, you know, like I think >> like lightsabers, it was kind of a cool thing back then. and uh >> lightsabers. You mean like VR game or >> No, no, actually, you know, >> yourself with like a stick and then actually make it into a lightsaber in post editing. >> Uh ah you talk about Oh, got it. Got it.
I thought you just switched to another game. I was >> you know I think it was Adobe After Effects or something like that. So I had quite close you know connection to working with a computer and playing and I could pinpoint actually my first experience with programming. Maybe you know it. It was a website that was called Scratch.
I think it was developed by MIT in 20 2003 to >> 2007. It was actually, you know, code blocks that you could put together, very simple one, and it was actually made for children, kids back in the day work in a different screen it and I think that was my actually first, you know, I I have no idea. I can't even remember how I some friend probably told, you know, you could go to this website or something. >> Yeah, it's there's an option for that. Let's just see if we're actually going to reconnect.
Oh, did it actually work? Are we back? I >> think so. >> Hello everybody. I think we are back.
I am deeply sorry for what happened. Honestly, I don't know why, but OBS just crashed and our stream almost ended. Luckily, YouTube somehow keeps it and OBS is able to reconnect. So, we are back online. I think I'm not going to touch anything.
I'm not going to show you a Scratch website anymore. I cannot recommend that. But yeah, um just to recap, we were talking about Dimitris' um programming journey and he mentioned that somewhere early he went to the Scratch website. You can think of Dynamo but for kids without like like there's like literally like blocks of little logic you connect and something comes out of it. Um >> and I think it sums it up.
>> Yeah, pretty much. So Dynamo without raid for kids. >> Yeah. Yeah. Exactly.
>> So um yeah, I think I'm just gonna Yeah. >> Yeah. Yeah. Yeah. That was the first start I think with first contact with programming.
But then I think it was actually in high school, you know, we had like a before university we had a lesson we had to do like I think it was mostly algorithm logic. So just write things down how to do stuff. So it was a pseudo >> code coding in a way if I'm pronouncing that correctly. >> Oh yeah yeah point for people who are new to programming. Pseudo code is like you're defining logic of your software without code.
You can literally write on like paper. So kind of get walls look at parameters read these parameter do. So it literally can be in plain English and then later you figure out okay how do I convert it to actual logic. >> Yeah. >> Yeah.
Exactly. But uh then I think the big you know uh start with programming was in university where I think it was a I joined a research group that was you know dealing with like structural calculations you could say. So they were actually there was a group of uh some uh prof you know professors want to be and some students that we were actually trying to program a software that does some structural calculations with a it was back then it was with a new type of calculation you could say a new method. So we were using actually MATLAB if you know it was a >> Mhm. >> not sure how to describe MATLAB exactly it was >> kind of graph graph analysis made with code I would say because the whole I think the whole point is like you get your data in whatever format inside your code and it can be I think MATLAB is compatible across all languages because it's most popular.
>> Yeah. And then you just very easy to yeah read and understand and everything. >> I think you can also analyze it right do or use something else for analysis. >> Yeah. Yeah.
You could you probably had you know you can use it for everything it was uh you had to run it from you know the it software back then. I think you could run it you know like a standalone Excel or something like that. >> Okay. But it was very go-to for university I think back then. So you could have you know quick calculations with something that is more you know uh advanced or something like that.
And it was fun because you know back then it was using for creating graphs and also make some calculations but we were actually trying to make kind of a Revit software you could say back then in a very beginner way. So I think I actually dealt a lot with trying to make a UI back then, you know, very manually like, you know, creating windows and then close something and then so something in the same screen in in a different view and then try to load some 3D solids back then. >> Was it was it done all in Python or what language did you use back then? >> It was all mat actually. >> Mhm.
And uh you know back then you had to search for everything in Google and >> Oh yeah find something similar to something that you want to do and try to make it work. >> Yeah. I think new people new developers will never understand what is stack overflow and why it's so amazing. [snorts] >> Yeah. Yeah.
and you know people arguing oh that's the better idea to do better approach uh but it it was fun nonetheless because we just uh I think back then we just did whatever anyway >> but uh yeah it was Matlab along the way during university years and I think later Python came uh you know came on stage for me I can't even remember how Exactly. But you know it was something that was going around like you know Python is great to do scientific calculation and it's very easy to learn and you know easy to understand and >> did you did you work in Denmark Denmark already with Ravit or it was way before >> it was way before like 2015 maybe so during university years. >> Okay. So you had already a good start with Python before all of that. Yeah, but I think it was I can't remember actually why I used it.
Maybe to do some very simple stuff, but it was, you know, when you work with computers and stuff, it's always maybe a little bit Python, maybe we all I also used a little bit C back in the day for Unity. We were trying to make some games and stuff. It was C mostly. And that was a a big leap because that was like, you know, now we [snorts] go into deep waters with C. >> It was interesting.
So a little bit C# and then a little bit Python to actually try things out. But when I actually started looking into Python was when you know when I started using Revit at my work now I was actually starting to miss things you know things that you know functionality that Revit didn't have. >> Oh yeah. >> And uh I actually saw from people that were using pyRevit. I was like that seems cool but I had no idea back then what it was.
And I saw a you can make custom buttons and do things like whatever. Because back then I was split in between, you know, choosing Dynamo to start learning Dynamo or going to pyRevit. I was, you know, I was really [snorts] I was really conflicted about it, but u I thought Dynino was very like a closed system in Revit. So I I was I was very you know reluctant to start learning it. >> I was like okay I will go the private way and see where it goes.
>> Yeah. Do you remember the first kind of problem or tool you tried to create problem to solve like with a tool or something? [snorts] >> I think it was insulation on pipes because uh we had a lot of you know pipes and different sizes and different kind of insulation on everything. And then of course someone came to me okay we have to change a lot of insulation. And I was like, "Oo, I should manually select everything or, you know, make schedules and select them." And I was like, "There should be a better way to do that." >> Oh, yeah.
This phrase, there should be a better way. Everyone went for that. >> These specific words I hear it over and over. >> Yeah. So I started looking into that and then to be honest I stumbled upon your lessons and your courses and yeah I was like you know that course seems cool.
So I signed up for it and started learning stuff and it was you know like a you know a whole new world you know opened in front of me. >> Mhm. >> Okay. So you started straight with the training. You didn't try to manually hack through this, copy a bunch of code.
See, I also went through this phase. >> No, I actually, you know, tried to find things that were ready back then. So, you know, either Dynamo scripts that worked and they worked most of the time, but you know, you also had to install some uh packages in order to work and it was like that. And of course I was using pyro edit as the main toolbar you know I was using just for the functionality so I was really liking you know color tabing having different colors and >> that was a game changer >> that's my favorite too in private >> every morning click click now I'm ready >> and I think it's actually maybe the most you know when people come to your screen and see your Revit and see why do you have colors that's I It's maybe the most recognizable thing that you're using pyRevit. >> Yeah, it could be.
>> Yeah, in a in a way that's my my view. But I was I also had some contact with some people that were using Fire with some custom buttons. So that was what made me actually start looking how to do it. >> Mhm. Because I guess you of course you know that it was the C# way and making custom mattings directly but I could sense that that was a little bit harder and it was the py that you know it for me it was that you can write something run it and then if something doesn't work you know edit it and run it again that was the biggest game changer instead of having to compile something again and all that stuff.
So for me in my mind it was okay private is rapid prototyping in a way and if later I want to do something more serious maybe I can >> make a C tool you know the official way. I never did actually. I think I maybe tried once to make a you know a tool with C in Revit. >> I see. But >> how did it go?
>> That was it went well. It was a print hello world warn >> the classic >> to you know a warning bar like saying something but but it worked. But to be honest I didn't feel the need afterwards to do it again. So I just I'm really sticking to fire for now. >> Yeah, most people use it nowadays.
you know, if a beam designer actually, you know, works some years, they will have private installed, I think. >> Yeah, it's crazy how popular it grew and auto still pretends, well, there's it doesn't exist or something. I don't know. It's funny you mentioned the rap rapid prototyping because on parade GitHub, it says that parate is a RAD and they describe it as rapid application development. That was the initial goal of like parade because it's quick.
When I talked to Ashan, he also first he just he had a bunch of Python scripts that he had to go and load in this kind of Python inside ravit shell and it just went from there like okay how do I make it faster and that's was pretty much the birth of py ravit and yeah I agree with you on the but for me also I never saw a need to go beyond pyrait I for me it's personal decision that I love pi python py ravit I don't really I I could switch to car It's it's not kind of something that holds me in terms of like I couldn't learn it or something. It wouldn't be an issue just like a few give me a few weeks and I will be very comfortable but also realize that for us like ravit users we're not as well for most of us like we mostly working in Ravit and the goal of software is just to solve a problem and if py ravit solves the problem and it works well then for most of us that's more than enough. I see a good use for C for like very big companies where they actually have also where they can hire people who are more into software development world because you need to learn more about programming in general to start with C. You need to understand like classes and stuff like that. But also I'm not going to say here like Python is the only way to go.
I just want to be transparent with people. Like I heard some people say to me it still sounds surprising but for them learning C is easier and use C# is easier. I get when like experienced people say that but when for beginners said that I was like whoa some people just like to learn things differently. I just want to like throw it out there as well. >> Yeah.
Maybe for some people it is. But yeah, I mean uh especially I think uh when I was thinking about it that you know I started actually developing you know I was learning uh through your course of course uh pyRevit and how to make some stuff but I actually started when I started having problems at work like I have to solve this. I'm sure I can do it with py ravit but back then it was how quick I could make it because of course you didn't have a lot of time to actually dwell on it and develop and so it was no you know couldn't even think another way of you know going to the car way because I really needed something very quick and it's it was very fortunate for me that it was also kind kind kind of AI era in a way developing at the same time because you know for >> oh yeah >> quick stuff I start you know just started with simple things like I think my I made a very small tool you know I had you know when you are using Revit and you have a workshet you have a lot a lot of models need work sets and uh we had to set it up every time you know a new works and then close the window it's a little bit tricky key in Revit for some reason. I don't know why that you have to close the window when you close the works and then you want to create a new one or something like that. So I just made a I just say to chat CPD back then okay I want to make a py ravit script and then of course you had to describe a lot okay it's make sure it's IronPython it's make sure you use you know f uh >> s strings >> not the other ones you had to go a lot back and forth so I just said to can you make just a single you text input where I can paste, you know, the names of the work set and then just create them.
And that was and it it made it, you know, very quickly. I was really amazed about it. But, uh, back then, I mean, back then was like one and a half one year ago, maybe one and a half year ago, but you had a lot of, you know, back and forth, you know, this didn't work. I get this error. Okay, what is it?
Okay, now you know is very confident like okay now you know I have this code will work for sure and then it was like ah no it didn't work again and you had you know to go back and forth it bugging in a way I'm not sure if normal deep [laughter] >> yeah kind of [snorts] or arguing with AI >> not arguing but uh but uh and then you actually went to the solution but I I think nowadays it's >> it's really good. >> Makes a lot of mistakes but uh it can be yeah give you results very quickly. >> Yeah. Now I started like pretty much everybody who connects with me on LinkedIn I just quickly ask kind of a few questions where they at and stuff like that and I noticed there's a pattern now there are a lot of people they jump into power raid fully with AI they don't understand the code at all or a little bit they just pump out a few tools here and there and for especially simple tools it's quick and easy it works and then it I noticed another pattern that as they go they create a bunch of tools it works but then the question pops up like how does it actually work because on most serious work, you don't want to just kind of prompt and hope you want to have a little bit maybe like understanding because I come from like old days when we actually learned it the hard way manual like it was like I sometimes like one question would take you a week to solve like if it's like VPF how do I connect it there's no tutorials no resources that was like not the best experience but now you can get all the answers but at certain point I see that people also they they want to understand what they do and I think it's al also because on the big projects well you cannot point to the your chat window and say he did it. So if something like doesn't really work well or something usually it's not that critical but I see there people getting more interested in programming after AI because AI gives you this kind of first rush of adrenaline like oh I did it works there's a button something happens but then after that some people like fully stay white coded as well.
So I wonder what's your kind of opinion on that in terms of like let's say people who just discovered AI and just go fully AI and people who like kind of take a step back into the coding world. Do you think it's still necessary? >> I think at least for me it's actually one thing that I'm thinking most of the time when I'm doing both because you know at some point I was progressing my you know Python skills but at the same time I could see that I could do this faster but you know when you are starting to use AI that much I started feeling a little bit uh I should know how to code that not you know totally depend on AI because I was feeling like an impostor you could say >> but at the same time you felt you are feeling like you will be left behind and you know people just uh publishing shiny tools and like and I'm still learning how to you know do basic stuff so for me it was what I promised myself it's I will use AI as much as the rest but at the same time I will try to develop my actual programming skills. So because you can easily just go full vibe coding and never have to understand code. Even a slight understanding of how programming and coding works, I think it will it helps you tremendously huge code >> because at least you understand the logic behind what you [snorts] make and you can you know and especially with Revit is one thing is understanding how Revit works one and the other one is how to actually because when you try to v code you have to give AI the correct prompt as well.
So because some people I guess they can just say you know I want you to make a tool that does that. >> I usually just you know break down how I will do it. You know first you will select some elements then you will maybe filter somehow blah blah blah. So I I'm trying to you know write down the logic behind it and then give it to AI so it doesn't you know hallucinate things or try things that do not work or at least make sure it's my mistakes it's making >> you know following you know maybe my logic is wrong >> so I can actually control it a little bit more but uh I think I went off a little bit here. >> No, no, that's fine.
>> For me, it's a little bit in between using AI as much as possible so I can actually be in front but at the same time trying to develop as much as possible the manual way you could say. [clears throat] >> Yeah. Yeah. >> And trying to find the time to do both in a way. But because I think if you leave AI out of it completely and you say, you know, I'm not sure if that's the best idea.
>> I'm still conflicted. >> Yeah, I see that. I I can also relate for like a more than a year I had this internal struggle because in my case I also like a bit more unique situation because I also teach and people kind of just many people would just when they start watching my tutorials they get on board and especially if they like my teaching and what I teach they're just going to follow kind of the same workflows and ideas like at least I I will plant the beginning later of course they can decide something like better or worse but still because of that I was I felt extra pressure and I didn't really was on board. I was using AI every day. I was kind of in kind of following the trends.
I wasn't pushing it to the limits. When the harnesses came out like close code and stuff like that, I was like, do I really want to jump on it? Like because I knew that if I jump on something like that, I would have to go really really deep into that and I was like really battling with myself. It was might sound stupid to many people. There like why would you skip on such technology?
But when you also teach it stuff like that, I also wanted to understand like is it something that I want to really dive into really deep because back then they're like developers really split into multiple camps especially newer developers and people who never coded just started they were all full vibe coding because they prompt they get results they say coding is that real developers who like kind of build up the skills they still use AI but they stay a lot in control try to do as much as manual and at the short term web coders will win. In like two days, I made like 60 prototypes of my website, 30 prototypes of my wife's website just to kind of well, that's how I just like to make a lot of volume, see what's possible, see like it's literally like, hey, I might make a website, I spend 5 seconds looking at it, I'm like, delete, I don't like it. But now I see more and more developers realize that it's good for prototyping but when you actually want to build more robust tools and stuff like that like a software like let's say like not just us like a real developers they still see a lot of value doing it more manually because the code stays more robust it works it bugs out less because recently there started appearing bugs in like large websites and bugs they're like super stupid and this is because some mistake and people start always calling it AI slopes. But also for parit what I see this we are a bit also in unique situation because we're not fully kind of developers in terms of we're not creating software from scratch. We're not like creating like very very like you know like tens and hundreds of thousands of code like per module and stuff like that.
Oftent times parate what gives us we focus on one single problem and here's one simple solution and it's very simple task AI is like super capable. Uh I see a lot of like okay we can pretty much wipe code it. It depends on the task. Sometimes you need to kind of go back and forward as you say sometimes you need to provide your own context say like look this is how it works. So you teach AI as well but I think still on like larger automations and just in general if you want to kind of be in automations it's really good to kind of understand it.
For example, one scenario. Imagine you make a tool, you ship it across the office, everybody's happy, and then somebody comes to you. That's cool, Demetrius. How does it work? You have like no idea.
They're like, well, I prompt it and I got a button. That's already kind of I don't know. Many people would not be very comfortable with answering like that. And this kind of question might come up once you once you become the automation guy. an issue but I can see that you know in the future maybe of course AI will become better and better but I think it could be a value on you know having knowledge on how to set up systems behind developing everything.
So, so not just you know prompting and having something you know AI to develop something maybe having you know specific overflows on how AI is doing stuff and documenting stuff at the same time and maybe also have review checks and >> you know having a complete system of >> AI again but in a more robust fast workflow. >> I'm not sure if that's even something that makes sense. >> Oh, it makes total sense because right now like like year year ago it already was happening but let's two years ago it was all about prompting better prompts like give it more information. do that, do this, like dropped like I saw prompts which is I actually used it and it kind of worked a few years ago when it somebody gave me like 40 50 page word document where I had to just copy and give it to AI to teach it how a certain framework works. This was just for creating a little component on framer UI and AI didn't know anything about that.
So you fill it that word document and it actually kind of makes it smarter in this regards but that's not very efficient system by any means today with like harnesses skills like hooks and all of that it's become so much more you can create these systems where you again you don't feed everything to AI but AI has access to all this information I think what you're saying is 100% there but to create the systems even without code it's still possible once you know code you understand computational logic. So there are like bigger concepts behind which is like fundamentals and in everything I just keep confirming that well you always have to kind of have fundamentals to kind of begin with set up a nice architecture of how things should work and yeah it could be yeah interesting to do. >> Yeah. Yeah. Well I'm also experimenting with all of that kind of setting this up right now.
Well, you are inside as well because I'm working on this new training and this is kind of the goal to kind of focus more on the system, not just kind of prompting back and forward because well, people don't need me for prompting back and forward. And what I have in mind is just kind of create this not just kind of dump information but also allow it to verify. So you give it like access to like documentation. Here's like really in depth. when it writes code it can before giving it to you run it back through documentation make sure that everything exists right so the hallucinations we need to address it somehow means we need to give it like a source of truth and stuff like that so there is like a lot of these components but yeah I am really sometimes having like this tough monologues like where it's all going and I think like everybody right now going through that like whatever like the profession even outside of AC it's gets scary because everything is over high but then at certain point and you realize well AI is not it's like at the same time super smart but sometimes it becomes so dumb that you I get confused like how far it goes.
I still try to pinpoint the limit and seems like it keeps jumping and jumping and jumping. That's why I'm now kind of okay I need to go full in on any kind of AI but I still want to kind of stay in control. I don't like like fully wipe coded stuff even though >> Yeah, I understand what you're saying and coming from and it's a And it's actually interesting to see where AI is going to you know what's the limit and I mean I'm not sure how it will progress but uh I was actually reading an interesting thing that you know AI kind of tries to you know the output that you get is the average of all the material out there in a way. [clears throat] >> Yeah. >> I was actually looking about renderings in architecture and stuff.
So because it was it kind of you get the rendering of the other ads of what's out there and a lot of people were questioning like in the end are we just getting the average out as output. So don't know if that's the same for coding. So you know what AI right now is you know uh exporting is the average of everything. So what if we need higher standards of doing stuff? Is it going to be always just good enough?
>> Yeah, that's a very good point. >> I'm not sure. Yeah, >> that's a good point. I have a few things to add. Well, first of all, when you like you said like your code is going to be like average based on all the information.
Still going to be higher than I think the average, but it's based on the average let's say. There's also now it's slowly becoming another issue. I see it sometimes because before like AI went for the internet got all of this human input kind of sucked it in and became smart. Now they keep doing that but now it doesn't work as good because now most of the stuff online is like AI generated and all the blog post everything is just like now it like AI also starts to uh also struggle to understand like what's a good information what's not because you know like the garbage in garbage out and I think some some new models they like experiencing that as well and I think that's also the reason for the watermarking they now start the watermarking Everyone starts thinking ah it's to like flag all the LinkedIn post or like social media. I think they do it just for themselves so they can kick it out of the training sets easier so they don't have to like guess is it good is it bad.
But now we're also at this time where like human input on the internet is becoming way less and less and AI is just like 100 times faster more and like we all experience that we open LinkedIn you scroll through like there's like AI AI AI oh this person has something to say. I noticed I started reading random topics that I'm not even interested because it just looks human. I'm like, "Oh, that's definitely human wrote." And I start reading about some cold calling or something like that. I I will never do cold calls, but I'm like, "It was nice for written." I start noticing like I this this >> at least in my case, but at the same time, I'm fully on board with AI in terms of like using it. I try to like my pretty much mot is just try to abuse it and learn how to abuse it even more because then you start to think, okay, how can I max it out?
How can I do this? You learn some cool things about it. >> Yeah. But the information out there is is crazy how much is generated by AI. I think 90% of my LinkedIn posts I can see it's like generated and it's pretty obvious to, you know, to see that.
And maybe now I think it was something that you actually said back before some time that you know now you actually look around for wrong writing and stuff that feels genuine and I know that you are you were trying to yeah I know only all people that try to post things on LinkedIn try to you know write better but now it's very difficult to see is it AI or is it just writes good? >> I I often spend like one hour just writing some kind of post here and there and it doesn't often make sense because well I don't get like as much like attention and stuff like that to justify it. But for me it was I kind of enjoyed writing in the process of learning it. But now when I learn when I write stuff now I have to consciously think how do I dump it down? How do I because some what I learned about writing a lot of it AI AI does it even better.
But now when I do something and write nicely, before I would be really proud of that. Now I look at that, I'm like that looks a little bit AI. I just started to hate this game. >> Let's make a mistake in the words and stuff like that. >> Yeah.
I mean I intentionally sometimes leave mistake. I'm like I cannot be bothered to fix it. It's only going to make it better now. I don't do it like intentionally like going and breaking words. But if I did something I I'm chill about this now.
>> Yeah. I think a very, you know, easy giveaway of if something is AI is commas, you know, usually we just keep them and but then you see something perfectly with every comma correctly like >> for me it's m dashes now people who used m dashes they hate everyone because they they were always unique for using them. I still don't know even words on the keyboard. >> Yeah, I actually have a secret. I actually said you know a lot of times I try to rewrite some stuff with AI and I just have a general uh you know guideline never use dised there like when I just make website prototypes I just cannot even see that I'm like no don't even show it to me.
Yeah, going going a bit off topic. Um, so how do you actually build tools like today? Like when you would build like you would start probably with like MP using AI, you would still can actually go and kind of write out all the steps. >> I'm actually unfortunately now because of you know time and when you need something developed it's usually very don't have a lot of time in project to do that. >> I'm just using Well, yeah, I'm full on AI right now.
I'm just thinking of how to you would solve it manually. So, I'm trying to think the steps behind and then, you know, try to set a a long enough and correct prompt to start doing that and then build on that. So I still prefer to make a you know a small prototype of something that kind of works and then build top of that. >> Oh >> I have created you know some tools especially MEP ones >> but I can't take credit that you know I did it manually. I the big change for me was actually setting up you know before I was mostly using the chat person would say of sacibility then I was like okay I have to learn the agent way >> and then went into you know making the workflow and making using skills and everything and set up something that works and that was the the big game changer for me having a system that you know I can actually I was actually planning to show my it's a very basic setup but it works >> and I really wish at some point to you know develop on that more and connected to you know better databases or you know things like that and I do actually made small presentation with AI of course.
Oh. Oh, yeah. >> But to understand how it works, my work. So, >> should I should I share a screen? >> Uh, yes, we could do that.
>> How d workspace work? >> ENK is my name in a way because I have a second first name. >> Uh, just one thing. Can we make it bigger? I'm just trying to check it.
>> Oh, yeah. Looks good. But let me start actually from where things are happening. So, so at first you know I had I had created one folder and made an AI workflow. I used AI to just make everything.
So I said to it, no I want to make a AI workspace where you have some agents and skills so I can develop private tools and stuff. So it created everything you know it created some skills, some agent files, some empty files with some basic guidelines but uh during work I actually thought to actually split everything. So I have two folders. One folder is the actual, you know, addin file with the tab and the tools and I had a complete different folder with everything that has to do with the development part of everything. So in my work pens folder you could say I have all the agent files and all the steel files and all >> kind of I split it up like that development and output in a way.
So I won't go into that that much. >> What a what agent are you using? CL code uh codex whatever >> I started with codex but now I'm going to you know experiment a little bit with code I guess you could see it I remember that agent MD is codeex stuff right or >> it's like cloud MD agent MD it works for everything except cloud code >> in in cloud cut you have to create cloud MD and then you shouldn't also for people who doing that you shouldn't say go and read agents MD cuz it's not ideal. You should put like ad symbol like an email and then reference this file then it actually imports it then then you can kind of use it side by side. Fine.
>> Just a quick tip. >> Yeah. But that's you know that's my main agency. It actually says you know this workspace is it's two siblings in a way. One folder here and one folder there because they actually split it up.
So it I have two different kits for each folder I know it's maybe a little bit unorthodox but um having one kit for the development and one for the output don't ask me why but I had to do it >> by by git you mean like set of AI instructions or >> I mean a git >> ah the g version control so I have got for every folder >> publish is this one you know separately in a way. >> So this you know this is split into two folders >> but and I will show you how it works in a way a very simple you know uh presentation you could say. So I have two folders and here of course are all my tools in the first one and then the important one for development is the workbench one. So I have an HTMD file you know which it's the main rules of how to do stuff and what you know that it is a bioavit developing agent that it has to do stuff like that and that. So it actually starts by asking when you start to develop something which Revit version or what versions you want to you know develop with.
So is it Revit 24 and up or an older version or something like that which pyRevit version that's maybe not very good. Um it's also asking me the first if I want to use you know the standard pyRevit UI you know the helper tools they have or >> Oh yeah for the forms. Yeah. >> Yeah. the form or actually make a WPF window.
uh because there are after using it a little bit I thought that you know when I start the process it's important to different is it a new tool that we want to do is it an existing one that we want to you know further develop or is it something that doesn't work and I have a template you know I started like you know it should be nice to have a small pyRevit python template like you know here are the functions here are the main code and stuff. So, I actually said to it, you know, starts with the template. >> Of course, it goes crazy, but at least it starts with some. >> Mhm. >> And uh, of course, if it's going to be compatible with older things and the new thing for me, it was like, you know, I wanted to create directly into Revit.
So when I said try to make something it will automatically put it in the folder which privit is actually seeing in Revit. So it will actually I can actually see it after it develops. So I just reload pyRevit and then I get it. >> So I actually said to you know create icons if you want some icons if you want you know for light or just skip the whole icon generation. >> Mhm.
So you have to set some basic information about it and then I guess the main thing is the how the skills work. It's it's actually I put a simple system in a way. So >> it's a skill for bio development which deals with the actual Python uh scripting. There is a skill, you know, making the WPF forms if I say that I need that. And then there is a skill after that that tries to check that everything is compatible with each other that the WBF form is working with the five rabbit code and vice versa and make some you know review of what is there and what I have started to double you know of course with a lot of development I had a lot of back and forth you know this didn't work let's make it that way >> so I you know and this information wasn't saved anywhere.
You know, you had of course the context window >> but this disappears afterwards of course. >> So I thought okay let's capture everything. So I started to make you know to say to the main agent MD file to write everything that it does. So it has a more documented you know process of everything. So you can actually find empty files for each tools.
So for example, you have tool ideas. So I have a the why not here. So you can >> is it like a build spec or just the idea? >> It's both. >> Mhm.
>> So here you will see what status it is. The tool explains something. So it's kind of documenting the way you work things. So you have some known constraints, some decision that we made like uh for example let's let me remember this is not a very good example actually because it's more complicated but it documents everything. So >> mhm >> yeah try to document everything that it does for every tool I have and uh the most important for me was to make a skill that actually you know when I thought you know sometimes we have something important so I made a skill that it tries to recognize that you know we went back and forth so this is important let's document that so it doesn't make the same mistake the next >> [snorts] >> Yeah, that's a very very good workflow >> and it's to upload not upload update the other skills uh based on the you know interaction we had.
Uh a big example was the WPF forms. You know, I was trying to use WPF forms that are modeless >> and linear, I think they're called, and of course, it didn't work. You know, Revit crust and stuff like that. And >> yeah, it's it's tricky, but >> yeah, that works. And I said, okay, now we do it like that.
And now, every time I do a modless W4, it doesn't crash. And I'm very happy about it. Yeah, >> that's kind of it in a way. >> No, no, it's really good. This knowledge capture, there are like a lot of variations of the skill.
Some call it crystal, crystallize, like learn capture. Like there's all these words. I also used capture for a while. I don't even remember what to change it to. I sometimes I get too focused on the name of the skill and then I realize like, oh, it doesn't matter what you call your skill.
It matters how it works. >> Yeah. No, >> that's very basic. I mean, it's something that it was my first experimenting with an AI workspace, you could say, or I'm not sure if I should call it something else. >> Yeah, that's totally fine, I would say.
>> But, uh, to be honest, I think I would totally do it differently now, but it works. So, I'm just going with that for now until it hits something hits a limit. Uh there's also a thing that the creator of cloth cloth code recently came out and said like you should delete all your skills every six months. There's like made huge headlines. But the point is like as model grow sometimes we keep very old kind of skills for very basic things that AI is getting more and more capable of.
And I'm not sure about this kind of deleting. He didn't mean like delete forever. He just meant like disable it and see what happens. just see the model the kind of row capability and it gets better it can do a lot more it's like handles VPF way better than before but also there's so much more information now >> but you feel like you lose control over what it does in a way at least with skills even if it's you know not the perfect skill you still >> have the sense that you control what it does in a way >> it does like you like it that's what also matters because otherwise it has so many options to choose from And in the end of the day, LLM is just kind of word prediction kind of software, but I don't know how to really put it abstractly and therefore I just always kind of even like the same problem can give you two different results like if you just ask it in two chats, which is also sometimes very funny. But with skills, I see that they also often unify.
Do you also have like a all the issues and gotas and stuff like that? Do you capture it or you just capture the good stuff? >> No, I actually capture the issues as well and uh things that need you know further development. >> Yeah. >> But uh yeah, sorry.
>> I I often notice that for me when I when I start when AI gets more issues gets it starts to work much better when I just give it like good stuff because in the beginning I was just like feeding like good stuff stuff like that. It was still failing. When I started saying about the fails, then it's just like, okay, no, no, no, no. And it just so if I had to choose between the two, I would just give the bad stuff. But both works pretty good.
Even better, not just good. >> But to be honest, it's always fun to just try to, you know, break what AI, you know, makes and then say to, you know, this doesn't work that >> and then you get back to you try yourself. You're like, sorry. I prefer [laughter] to be to you know break it myself. It's more fun that way.
>> Also another thing I was experimenting with is I made a bunch of skills and you can also so I wanted AI to test skills as well and then it has some kind of evaluations and it started kind of AI on its own. It would kind of ask it questions and it would have some expectations. It would just ask fairly specific questions just to see if it gets it and it just did it by itself. all the tests and stuff. I just kind of said like I just saying like I want to test try like different ways.
What it started doing it started creating like a bunch of test files and stuff like that running with skills against skills and then comparing the two. It's not the perfect test because ideally you have to also go in raveit and that's a big workflow on its own but even without it it just captured a few things that were not like okay this doesn't work this is bad. It just marked me good ones versus bad. I was like okay let's look. I looked at the bad ones.
I'm like, "Okay, they are bad." [snorts] Cuz most of us, we don't write the skills anyway. It just kind of keeps auto updating at certain point. It becomes a mess. Kind of a very solid kind of workflow. It's also it's it's not it's not complicated.
This is where like I see this is where we just have to begin. Just also separate by topics because VPF you don't always use and you don't have to always load it. This is what some people do also. Um they try to over complicate skills when like the smaller ones I find it nicer but when you have too many of them that's also not nice because now AI needs to know everything about them like description >> and the WPF forms a whole different thing. I mean I have tried you know to save it in specific styles I need I like and how to do stuff and you can lose yourself just messing around with the forms and how things look.
Mhm. >> Yeah. But it's also pretty fun to just experiment with it. But it did create some tools. My and to be honest, my next big step it would be you know in the main files I tried to say you know to get information from uh you know ravit API sites and double reference everything.
But the biggest change for this I think is to connect it to an actual database that doesn't you know hallucinate and that's what I'm hoping to do with the course as well. I mean like raid API py ra all of these yeah definitely going to be a good thing. I sometimes like I I tend to over complicate things and sometimes I'm not even sure if that's the best way because I see that some people just keep it simple it works and people over complicate it works and I'm still kind of trying to get a hang of it. what is how much over because once you create your system you rarely test it against without using it. So it always feels like nice and you just keep building.
So I I think there should be a limit somewhere how far we should kind of when we need to go back and say like kick out the things. This is what I'm trying to kind of also get a grasp on better. >> Yeah. Yeah. I totally understand and agree.
>> Is it difficult to find the limit? Should they stop or should they develop more? >> But yeah. >> All right. >> For me, simpler is easier to, you know, at least maintain.
>> Mhm. >> Yeah. And I made some tools. That's the next thing I wanted to actually >> Yeah. >> I mean, I I think the first tools I made, these are actually tools I started making, you know, completely manually.
So I made my WPF form back in the day, you know, from scratch, coding from scratch. But then I saw, you know, I have to make it now. I have to use AI to do it. So I made some, you know, rename with still using the old style, but afterwards it goes to a much, you know, complicated WPF form. >> Mhm.
>> So one thing was renaming. You can already see see the style I chose for the coloring. But my biggest MEP stuff, I think it's pipe insulation manager, which actually should open the MEP model better to do that. It actually tries to manage all these relations. There's no pipes here.
That's interesting. So not sure is the HA mode. >> Anyway, >> so what I would love to show it, but I guess it doesn't have pipes in this one. It's actually you can see every pipe system and every pipe size grouped. So you can actually change the insulation on specific size.
So you have a 32 pipe you need to put like 30 insulation a 50 mm pipe you need to >> put in you can open there is a sample plumbing model >> is it? >> Yeah. So we can try that. Uh >> ah yeah >> so you missed that one. the colors [laughter] of them.
Yeah, but that's the area I was dealing mostly with insulation and piping and of course I made also a lot of you know small tools but these are the main ones like very specific project specific like you know I had to copy some parameters to another uh to another parameter field and stuff like that. Let's see. So for example, so let's see it should work. Yeah. So so you get the system.
So for example you have cold water and you see that you have two different type of pipes with you know different sets of sizes and then you can just you know select the insulation type that you want to put and then you can manually like I want 15 20 maybe 30 I don't know 50 mm insulation and it and you just press apply. Oops. And it's per system. It's per system or >> Yeah, exactly. It's per system, per type, and per size as well.
So, it has three levels you could say. And then you apply to a lot. It will apply the insulation on all of these pipes and fittings on that specific one. And I guess it will take a lot. So, it's a good test because I haven't tested for so many bikes, >> but that's what it should do.
And of course, you can select different systems. So, heating, cooling, water, and everything. And it start doing something and it probably will update because you can see that current. Before it had none. Now, you can see the actual insulation that it has on the pipes.
So that's one tool you can do it for, you know, every type of system. And the other one we had a lot of problems with it was phase matching. You know, when you create a when you create a pipe, it's new construction in a new construction phase. But when you make an existing piping and you want to put insulation, a lot of people when they put the insulation because they're in a view with the face set as new, >> the insulation is new but the pipe is existing >> and uh I was doing that a lot of times myself wrong. >> So I you know we had a lot of times that we had pipes in a different phase that the actual insulation and ducts also of a different phase of the actual insulation.
So I just made a tool that sees okay the the host is existing and try to match the insulation to match the actual host. So the actual pipe and that's what this does. So this one is fine because there is nothing here. For example, let's try to make one. Is that a pipe?
But you get what what it does in a way. >> Mhm. And see pipe a pipe. Sorry. I'm sure we will see pipes now.
It's a lot of pipes. So this copper pipe for example, it's new construction. Let's say it's existing. If I put insulation on it. There is insulation on it but let's remove it.
If I put insulation, it will be probably in new. So you can see insulation type the pipe insulation is in a different phase. >> So if I actually click the insulation phase m it will pop up. So you can see there is a pipe insulation that is in different phase than the pipe. So I can I can select that and it actually you know >> shows the insulation.
So you can >> also review before you do changes and after you review okay that's a pipe that I really want to change then you just select it match and then it will update the insulation phase. That's a neat. >> This is also for Y. >> Yeah. >> No, that's a cool tool because again it's all like this kind of I never really worked with MEP.
I didn't even know about that one. I would assume that it would go to the same one, but it kind of makes sense the way Ravit works that it often goes to like whatever you have selected instead of pipe. >> Yeah, exactly. So, it does that. And also sometimes we have insulations that for some reason are without the host pipe.
I don't know how it happens but sometimes it can happen. >> Okay. >> Yeah, this you cannot select. You can only select from schedules. So I just made a small script to you know if you see an installation that it doesn't have a host >> okay >> list it there and so we can actually delete them from there.
Could it be with linked elements? Like if you make linked model, select pipe linked pipe and but make insulation in your model. >> H you cannot do it unfortunately. >> Yeah. >> You have a pipe from a link model.
>> I would assume you cannot do it. But the way you describe the bug, I just start think how can I create this bug then that's >> I try I had that problem. I don't know if they fixed it in, you know, newer versions, but it sometimes it happened with work sets, you know, having the pipe in a different work set and the insulation for some reason putting it. >> Oh, yeah. I saw I saw that.
>> And uh then yeah, all groups sometimes they mess things up. So I think it was either work sets or groups but >> uh group groups is very common just like normally everything should be the same one but there's like a whole work around how to change it and we we kind of forced it a few times because it was just more useful to us but it's clunky. >> Yeah. >> No, pretty cool. >> Yeah.
But uh that's the main thing and I'm still you know now the good the good thing with AI is that you can focus a little bit on the ideas. So I think a lot of people are making you know a lot of tools but I think you we will get a lot of tools out there but uh I think the good ideas will be more important than the actual implementation because you know everyone can use AI and and they will get a decent result I guess but uh you need to actually solve problems and not you know make That's a valid point because recently there were also these talks that uh there are still the talks like about programmers in general and all this kind of I mean Nvidia co was saying our programmers are obsolete it's going to be obsolete but now he changed a little bit how he talks about it now he says like well the coding itself might become obsolete but software developers they're going to stay they just like kind of change how they work so instead of focusing like on writing code we're focusing on the problems which now becomes more important you still need to like understand like how to actually solve it better. [snorts] But not very valid thing. Did you? No, that was good.
I just noticed the time. I It's already getting quite late. So, I think we're just going to start wrapping up here. And I always like to ask all my guests regardless like of kind of their background stuff like that. What is their kind of advice to normally learning to code but nowadays with AI I'm always like I think I should ask more like combined if somebody wants to get into par development based on your journey where do what kind of advice would you give them like number one in your opinion?
I think the the most important stuff for me it was you know there is a lot of information out there and of course you ji and everything but the most important for me it was to find something like a course or something and stick to it so you're not overstimulated by every source out there and just do the work in a way and see you know stick to something and see where it goes because it's very easy to lose track and you know oh I should look into that and that and then you know you give up or because I have given up a lot of times because I started looking in several things at the same time >> that's actually >> stick to something in a way >> it's such a good thing for me I relate a lot outside of programming to that so there's like this thing called shiny object syndrome and this is where you try to keep jumping and you just you just start building skills and something you jump to another thing again and you never kind of reach the level where all of them would work and I did it in different things as well a lot so that's a very very good advice I'm still thinking about it but uh yeah and it's yeah it's very difficult to see because for me it was very difficult to you know convince myself that this is the best way to do that because I was trying to find okay is that the best way to turn five private or should I do something differently? >> Mhm. >> But in the end, I think if you just stick to one way, you will get somewhere at least. >> Yeah, you you need to start that that the issue. >> Yeah.
>> No, that's a very good one. No, thank you for that. Uh would you like to share like the socials where people can find you also if somebody wants to get your where is not here tool? Uh do you have it? Is it the one during the hackathon up the latest version?
Do you have like up to date something? >> Yeah, actually the one that's, you know, uploaded on the hackathon page. It's the last updated. I'm actually thinking that if I actually continue developing it, I will probably make a GitHub page about it, >> but uh yeah, it's not in the very near future. >> Yeah, that's fair.
So yeah, and of course you can find LinkedIn. >> Mhm. And I'm just going to I need to find where it is. But the name spelled like this. Dimitris commandis.
I'm also going to leave it in description. I don't know why I focused that. I'm just going to leave a link in description. You can find it there. There's going to be a very simple click.
You can find me at him. Say hello to him. Yeah. And thank you very much for coming on the show. And also everybody who is watching, thank you for sticking with us to the end, even if you joined later.
We had a few technical issues during the port, but we went through, we reached the end, which is I'm really happy about, and I love the conversation. Thank you for coming. It was great talking to you. >> Thank you. Bye.
My everybody.
### The Building Coder on the Future of Revit API with AI | Jeremy Tammik - pyRevitPod #11
https://learnrevitapi.com/podcast/py-pod-11-jeremy-tammik/
Jeremy Tammik, The Building Coder with 2,200+ Revit API blog posts, on his path to the Revit API and where it goes with AI. pyRevit Podcast #11.
## Transcript
All right. Hello, everybody. Welcome to the show. Today is Pirate Podcast episode number 11, and I have a very special guest today. And if you've ever searched anything on Google related to Revit API, I'm sure you read one of his blog posts.
His name is Jeremy Tammik, and he's absolutely a legend. And I want to just start with a quick start about him. That over 17 years he wrote more than 2,200 blog posts related to Revit API, and he helped like thousands of people including myself and many others. And it's an honor have you on the show, Jeremy. Please say welcome to Jeremy Tammik.
Hello, how are you doing? >> Hello, Fritz. I'm fine. How are you? >> Doing well.
I'm very excited to have you on the show. Also, I when I first invited you, I didn't expect that you join because I haven't seen any really podcast online with you. So, it's an honor to have you here. I think we all have a lot of questions to you, and you're excited to go through this. Could you just kind of introduce a little bit yourself, where you started before Revit API, before all of that?
Maybe with your education. >> Yes, sure. I studied math and physics. Uh basically, I didn't know what I wanted to do. I I try try to choose something that would not limit me in any way, and math seemed like a pretty generic place to start, useful for everything.
And I think my motivation is just to I like solving problems of all kinds. So, it could be mechanical or hands hands handcraft at home or building stuff. And um then I finished my studies and applied for a job in a chemical company. >> Mhm. >> I was interviewed very very strictly going up the levels up to the top big boss.
And finally, when I had the signed contract, I was not happy about this chemical big business farmer. >> Uh-huh. >> And when I had the signed contract in my hand, I happened to meet a young guy in the street, younger than me, >> Okay. >> who was uh a programmer. And searching for an employee, and he offered me a job at half the salary.
>> Wait, just on the street? Like while you were just walking from the >> Yeah, yeah, yeah. Sort of walking and talking. What are you doing? What are you looking for?
>> a job? >> And and I decided that was way more interesting because this guy was a worldwide guru. He was really unique. And he created Ventura Publisher, which only very, very old people know about. This was the first WYSIWYG uh typesetting editor on a PC.
So, be aware that this was during before Windows. This was on DOS. This was a memory of 640 kilobytes, and there was no way to fit the pixels of the screen into memory. >> Uh-huh. >> So, how do you interact graphically with pixels that you can't even fit into memory?
>> Uh-huh. >> So, we had to deal with a DOS extender and a DOS expander, which were two completely different technologies for fitting 1 megabyte of memory into 640 kilobytes of memory. >> Okay. >> Which is impossible. So, pretty tricky and clever.
And And he dealt with that kind of stuff. >> Okay. >> He basically single-handedly almost invented uh WYSIWYG typesetting on the PC in 640 kilobytes. >> Uh-huh. >> And I started working for him not knowing C, never having seen a mouse, never having seen a PC, came straight from university, and uh learned C the hard way.
>> Okay. >> We sat beside each other for a year, two desks uh side by side, and he told me, "Do this." And I worked at it for a week, two weeks. I had a question, I asked him, he said, "Find out for yourself." >> Yeah, I think that's a great way to learn anyway. >> inefficient production-wise, but unbelievably efficient as a learning experience. So, I learned C the really, really hard way.
>> Okay. >> Uh drivers, interrupts, uh multitasking on a on an 8086 computer, you can't imagine. >> Okay, I'm still baffled that you just walking from your interview and somebody pretty much change your whole trajectory going forward. Like, "Hey, do you want a programming job?" >> Yeah. >> Such a such a such an such an interesting interaction.
>> And um well, I worked with him for a couple of years, and things moved on, and the next sort of interesting job was similar. I searched for a job uh in a new place where I was living, and went to an interview on December 21st or 22nd. >> Mhm. >> And talked with these guys, and during the interview, they seemed to think, "Okay, this is exactly the person we need." And they said, "Can you start work tomorrow?" On December 24th. And I said, "No." >> Merry Christmas.
>> had me start work on January 1st, but I would prefer not to start on December 24th. And so, I went in there on on January 2nd. I guess the 1st was a holiday. And they were building cash registers based on a multitasking system on a 32-bit computer, which was a very, very extreme machine uh built for communication purposes. So, you could put 10 of these multitasking, basically, supercomputers into a box and had a really good uh pipeline in the back for multiplexing communication stuff.
And their goal was to build cash registers with super cheap components with zero intelligence in the cash registers. So, the cash register could only push buttons and display your number and not think. >> Mhm. >> And all the thinking happened in the computer, and that was the multitasking job. >> Okay.
>> And they built the computer themselves, the operating system themselves, the hardware themselves. And they were trying to cross-compile, I forget what the PC what the CPU was, but tried to compile for this strange CPU in their own operating system also in C, but compile on a DOS computer. >> Okay. >> Uh cross-compile, cross-compilation. And they couldn't get this cross-compiler to work the because we only had diskettes with um uh ripped copies of the compiler.
So, in the end after 4 or 5 well, 2 weeks of trying to get the compiler sent over from California. They sent me and a colleague to San Diego. So, >> Okay. [laughter] >> I worked for them for a week or two and then I was sent to San Diego for a month or >> Uh-huh. Interesting.
Uh I think we have a bit of an interruption for some reason. Oops, and something happened. All right. I think we have you back, Jeremy. Can confirm?
>> Yes, I'm back. >> Perfect. [snorts] Well, a little mishap. I'm sorry, everybody, once again. What do you >> I was quick to log in, but the setting up uh in getting me back in again seemed to be more complicated.
>> Yeah, honestly, I was looking where is the button because I have too many things [laughter] open already. I was like, I see that >> Yes. >> Yeah, sorry about that, everybody. >> Okay, so I got lots of C experience in the beginning of my career. That was fun.
>> Got it. Uh while you were going, I just shared quickly that recently the Pavel Durov and Elon Musk, they pretty much stated publicly that if people don't know what to learn, focus on math and physics cuz these kind of hard truths is going to lead you to all the other parts like AI and stuff like that. Well, you still need to kind of learn how to solve problems and stuff like that. So, I really enjoyed listening how you kind of described this whole path that you started with math, physics, and switching to programming, well, it worked for you really well. >> Yes, I would also say if you really want to do hard programming, C is a good start.
Um just a sec. Oh, that's going to Okay. Uh I'm sorry, everybody. My dead phone decided it's great time to turn the alarm. [laughter] I don't know what's going on.
Uh once again, you said about the programming the C is the great way to get started, right? >> Well, nowadays, actually, if I would recommend anyone how to start learning programming, I would go for Python, actually. >> Mhm. >> Cuz that is was what it was intended for. >> Yeah.
>> To make easy for a normal human being and uh not not a nerd to understand programming. Uh, C is not that helpful and also very dangerous. >> Yeah, there's a lot to manage on your own. Surprisingly, what I saw, well, I'm obviously in the Python camp, so I thought like everybody thinks like oh, Python is great and stuff like that, but then I realized that there are actually people who tell me like they don't like Python at all and they find C# or C even easier to learn. And one insight I got from uh Ashman we talked that it's really stuck with me that everyone has their own way of thinking.
And when programming language aligns with that, that's going to just great do great things for you. And Python just happens to be simpler because it requires a lot less to get started. But I know that a lot of people watching they probably they like uh I don't like Python. I like to go straight to like C# or stuff something like that. >> When I started working for Autodesk, my first job was actually developer support for AutoLISP because Autodesk had not one single human being in all of Europe who was capable or understanding AutoLISP and they needed someone to tell developers hey, this this new possibility exists and here's how you make use of it.
And I came from C programming, so I had no idea of what is LISP. And I found a really really nice book from MIT. Don't remember the title, but I could probably find it somewhere. And this MIT book used Lisp as the introduction to programming because Lisp is an extremely minimalistic fundamental back-down-to-basic principles programming language. But it's very different from uh something like C or C# or Python because it's very functionally oriented.
So, you you basically learn programming, but you learn functional programming right from the start. And uh I My first 3 years or so with Autodesk consisted 100% of just teaching AutoLISP, preparing courses, creating uh material, and diving in deep. And that was a really wonderful way back then to learn AutoCAD because until the arrival of ARX, uh AutoCAD could be completely 100% uh controlled via AutoLISP. So, you just learning and teaching AutoLISP, I also learned AutoCAD that everything every single command, every single possibility, every option, everything in the database, everything was accessible back then. And uh that was really good fun.
But after 2 or 3 years, I understood it, and I knew every question that came in these courses, and then it started to get boring. >> Okay. >> And just uh AutoLISP or John Walker actually created a ADS, introducing the C programming language to AutoCAD in order to bring auto solids into AutoCAD a solid model. Okay. Constructed solid geometry.
And [snorts] so suddenly I was one of the very few people in the world who knew C very well and knew auto list very well and AutoCAD. So that was fortuitous. Uh >> Yeah, yeah. Your path just kind of was already going to be there for you. You just walked it really, really well.
Uh before I go further, can we just take one step back and was how did you join auto how did you decide join Autodesk? How this opportunity came around? >> Um I was in southwestern Germany and was interested in in moving further south actually. So um Switzerland was an interesting area and I happened to hear about this job in Basel with Autodesk and it was very tricky back then to um enter Switzerland because they had uh limited contingents of um people that could come in to work there. The The company employing the employer had to prove that no single Swiss candidate existed for the given job.
>> [snorts] >> So it it took like 9 months or so to get me on board and during those 9 months I did this other job that I just started talking about before with the cash registers. >> Mhm. >> So it fitted very well. >> Okay. And you're originally not from Switzerland.
Where you from? >> I'm originally mixed, a little bit of everything. So my father comes from Estonia as does my last which is means oak grove. A tam is an oak and tam is a little group of oaks. >> [snorts] >> Um and my mother is English.
And they met in Canada. So I'm born in Canada. >> Okay, let's cover this overseas. >> Used to have a Canadian citizenship, but I do consider myself 100% European, a very convinced European and not very fixed on the individual country. I I don't really feel totally at home anywhere.
I'm a little bit out uh not not belonging anywhere. So a little bit of an outsider everywhere I go, which is a shame. I would like to really belong and I don't think I'll achieve that in this lifetime. >> I can totally relate to that one. I'm also all over the place.
>> Yeah. And I grew up in Sweden. So my mostly >> Another one. >> mostly Swedish from my upbringing and raising and thinking. And Sweden is is sort of is I I'm very much in favor of Swedish politics and Swedish ways of doing things, compromising uh not going into conflict, but searching for common ground and also searching for solutions.
Yeah. >> Uh just one note. I think your laptop is on your legs or something. It's a little bit shaky. If you can put it just >> Yes.
>> not as bad. Just kind of It's a bit planning talk for a long time if if it's not an issue. I'm sorry for that. All right. You're really international.
>> behind me. This is also difficult, huh? >> Yeah, now we see behind you better than you. Uh >> We have all kinds of contraptions here. How about this?
>> Oh, this is great. Yeah, great. Yes, well, you're really international, born in Canada, lived in Sweden, Switzerland, all over the place. That's so interesting. I always thought that you born and kind of raised in Switzerland for some reason, but I think it's just because that's where you are.
>> Yes, that's uh in in what place? >> All right. So, you joined Autodesk, you started learning about kind of everything related to Autodesk, Autodesk Lisp, all of that. And how does this progress towards Revit? And before kind of the Building Coder blog, so could you just tell us what's going on inside Autodesk?
>> Yes, of course. Um well, so initially it was AutoLISP and AutoCAD, and there were not that many other products. Um I switched back and forth my job interview with >> Ah. >> After after 5 or 6 years or 7 of this AutoLISP stuff, I felt I was telling developers what they should do, and I felt it would be more interesting to try to do it myself, instead of just telling others. So, I uh stepped out of Autodesk and joined a developer in the HVAC MEP area in Switzerland and worked for uh quite a number of years with uh for initially a product called RoCAD, which was very famous back then in that area in the German-speaking market for MEP systems.
It was very expensive, and it was built in AutoLISP. So, a The was like 50,000 uh Well, euros didn't exist, but francs back then. So, this was really serious programming, very complex stuff. And my task there and goal was to rewrite this AutoLISP program in ARX. And the reason for rewriting it in ARX was mainly to be able to manage the views, 3D views, 2D views, projections.
In In MEP systems, you have very special specific rules about how does a 3D system work? Obviously, that's the most complex part. You You want to avoid clashes. But, you also have projections of these 3D views onto 2D. And in these projections, there are very specific rules.
Like, certain edges have to be displayed in a certain way. Often, a center line is displayed. The center line is obviously inside the object. So, if it's a a hidden view, it should be hidden. But, you shouldn't hide it because the regulation specified that the center line is dashed and visible.
We had to create pretty complicated view >> Okay. >> projection rules. And that was uh provided by AutoCAD Architecture, the ARX version of AutoCAD. The ARX version of AutoCAD for buildings. This was all before Revit.
Okay. So, I I worked with them for 10 years. And um in the end, I felt, "Ah, this is kind of stressy. We have this big product. We have bugs.
We never finish managing the bugs and satisfying the customers. and actually going going to uh Autodesk and doing new stuff is also fun. So, then I joined Autodesk again. And my interview was with two two people. One of them was Stephen Preston from developer support, and the other one was Detlef Reicheneder, and he was from consulting.
So, I joined Autodesk and had two jobs. I was 50% of each. So, I did some developer support and some consulting, and in this consulting business, I moved around a bit between different products. So, I learned a bit of Inventor and also gave programming courses for Inventor. And I learned Vault and gave programming courses for Vault.
>> Mhm. >> And the I think you're leading up to the Building Coder. That's happened basically because in 2005, Kean Wongsley had started writing his blog through the interface. And he was mainly focused on AutoCAD, but also Autodesk stuff in general. And because his blog was successful and and met a need that was just appearing very clearly in the marketplace, um several people suggested we should have two more blogs, one for Inventor and one for Revit.
>> Mhm. >> And they searched for suitable people who might be able to start them. And I took the Revit one, and that became a success. >> Mhm. >> And I was very motivated, and the Inventor one didn't turn out so well, so that stopped again after a while.
>> Okay. >> And the reason why um the the building code was successful is basically the same reason why I was always involved in developer support. I just like to help people and um solve problems. >> Mhm. >> And actually, I I enjoy programming much much more than writing blogs.
>> Mhm. >> I it's the same as all programmers. No programmers like to document anything >> Mhm. >> because that's not really solving the problem. That's communicating the problem.
But somehow, I have this strong focus also on communicating and I do see it as my job description. My main task is this evangelism. >> You definitely helped a lot of people with your blog. >> Yes. And it uh obviously was more efficient to um document stuff and spread it out than to sit somewhere behind a closed door and do my own programming and play with my own little problems.
>> Mhm. >> I really loved some of the the tasks that I solved myself. And they were also often quite um inspirational and exceptional. But um it it always seemed even more efficient to to document other solutions that people have discovered or just discussions that we had in the API discussion forum and so on because there are so many brilliant people out there. And I really think it's a great shame, even globally in the entire world, that many, many of the best ideas of all just get lost or superseded or overrun by complete stupidity and often driven by marketing.
>> [laughter] [gasps] >> Uh yeah, marketing is is too strong and the lobbies is too strong and the really good ideas often get lost. So, Michael list to support the really good ideas. >> Yeah, that's [snorts] really good. I think, like you mentioned, you will fill in the real need. I can see one of the comments now is from Jean-Marc.
He's currently the main maintainer of pyRevit and he says that your blog plus forum answers really helped him get started. I get interested more and more and got him to where he is today. And he also shared that he thinks that this is the case for many developers around kind of Revit [snorts] API. And I can totally totally agree to that cuz I've been on your blog so many times. Like, even though everything is mostly like for C#, occasionally you have some Python snippets.
I was very happy to find them. But, even though it's C#, I kind of learn how to read and translate what I need out of C# into Python, so that wasn't an issue anymore once I got there, but there are just so many. I just want to repeat maybe once more that you've wrote 2,000, more than 2,200 posts across 17 years. And how did you kind of stay so consistent? Cuz that's a huge commitment.
Like, people I don't know if people realize how much it takes just to stay committed to that long. >> Um yes. Well, I think it just fit very well with my inner desire to both solve problems and help people with with their own solutions. >> Okay. Yeah, that turned out really great.
>> Yes, one other aspect of that is also before when we started the blogs and before we worked with that medium, we've always had this developer support and the Autodesk developer network program, which still continues as a paid support option for people. Nowadays, the payment is mainly to gain access to free versions to work with for development purposes, but back then uh Autodesk payment was also intended to give you the possibility to simply ask questions about API issues. >> Mhm. >> And in 2005 and earlier, it was completely evident to me that this is very inefficient. Answering questions one-on-one is is really a waste of time.
Both the person answering them and the person asking them. Uh actually, one interesting chapter is also age. In uh 1980s, together with two other Swiss uh developers, I founded the Autodesk Developers Group Europe. And we held conferences twice a year all across Europe. We were about 100 or 200 people.
Uh because there was no internet, there was no worldwide web, there was no discussion forum, there was no information from Autodesk, so we did it ourselves. So, this this fact this impulse to really share information and support people in their development efforts has been there ever since the early '80s uh and a driving force in my career. And in the early 2000, it was clear to me, yes, this one-on-one thing is stupid and I really insist on multiplication and publication. I want to publish everything I say. I want to publish every question that people raise because everything is useful and helpful for other developers who run into similar issues.
And nowadays, of course, the biggest consumer of everything is AI. >> [laughter] >> So >> No, it's just >> this AI is very, very happy with all of these publications and results and documentation. And I I Yeah, I think that's actually a very helpful so additional tool that we have now. >> Yeah. For sure.
What I like that you mentioned that you always tried all from early on you focused on the code and only also on these publications one to many. And there's actually a man called um Naval Ravikant. And he's more like in the business space, but he has really good thoughts and there's one of them is that there are three things that scale like your time the most. And it it's either kind of capital, so you put money, you hire people to work for you, that's how you get leverage. Or with the code, you write code once and you can reuse it over and over.
And the third one is actually the media. So like you said, like instead of talking one-on-one you just kind of share it once and everyone has has to see and it kind of grows and compounds and I think that it's was really good decision that you had it early on as you said from '80s. We still need to remember that there was time before AI, before Google, before Stack Overflow. And I'm not from that age, so and from most of my audience also probably not. So that's really interesting to see that you also push this kind of in-person kind of meetings and stuff like that.
>> Yes, the funny thing is I met um a friend yesterday, Bjart Fære. He was another one of the main founders of the age back in the '80s. So, he's still active and running about. >> Yeah, that's good. Uh also, we skipped a little bit how Revit came to be because uh well, people know that somebody kind of developed Revit and then Autodesk acquired it.
But, can you share how did it come from kind of from your side? How did Revit just joined Autodesk? What happened inside? Yeah, I think there should be some friction between AutoCAD and Revit. Sorry.
>> I wasn't much involved in the in the product side of things and I have published blog posts on that specific topic, historical reviews and I I don't really know that much. Okay. Except what Well, a few things that come to mind are that I believe that a couple of people from PTC originally implemented it and they did it because they were parametric fanatics and they wanted to build a garage and they thought we can't make a plan and then want to change one dimension and that means we have to rework the entire plan. We We want the plan to be driven by the dimensions. And basically, that is exactly what you see in in Revit now.
And the rev is stands for revision, doesn't it? Or revise. Revise it. Be able to revise it. Be able to change one parameter and your design is updated.
>> So, that's what Revit really stands for. >> Yeah, so they did their thing and uh Autodesk apparently recognized the use of this approach. And um acquired it and immediately said, "We want an API." And the Revit developers said, "No way. This thing has no API and it cannot have an API and it never will have an API." And the result is this really weird, strange anti-API that Revit is now equipped with, which is basically very simple, but also very weird. >> [laughter] >> Yeah, there are a few things sometimes that doesn't make sense.
But also over the years they try to probably fix a lot of legacy code and sometimes it's an API that things kind of move around here and there and >> Yes. >> Yeah, it's unique API because it's also built on the legacy product. So, in one way it's it's at least we got it. That's already something. Yeah, but also could you tell us a bit more about Revit at that stage?
>> One one point about the Revit API from a programmer's point of view is it is extremely simple. It is very very very simple because it is completely and purely event-driven. There is not one single thing in the Revit API that is not an event. So, an external command is an event. Revit you the user clicks a button, a command button, Revit sends an event, command execute.
And everything in the Revit API is an event or subscription to events. And that makes it from a pure programming point of view very simple to understand. >> Mhm. >> Um and that is also one reason why it's pretty different from many other APIs because through these events, Revit is always telling the program what to do. So, you never have the program telling Revit what to do.
And in many other programming languages and in the thinking of many beginner programmers, uh the programmer thinks, "I want to write a program that tells whatever how what to do and when to do it." >> Mhm. >> nope, that's not what happens in Revit. In Revit, Revit will tell you when you can activate. So, that's the the one most important message from me about the how the Revit API is designed. >> Mhm.
I'm still trying to wrap my head around about this cuz I never thought about from that angle. I still compare it to other APIs. They most of them kind of I start to feel that most of them like event-driven mostly. No? Could you give us an example of like a opposite like API how you would normally imagine it?
>> Yes, I can. Take Python and write a hello world. >> Yeah. Okay. >> There's no event.
The program tells the computer what to do. >> Mhm. >> Take C and write hello world. >> Yeah. >> It's a one-liner.
You say printf hello world and the the program tells the computer what to do. In Revit, if you want to implement the standard way to set up the most simple Revit add-in is to write an external command. And the external command displays a task dialog. >> Mhm. >> Which is an event.
>> Okay. >> So, it's the other way around. It's not the program telling Revit what to do. It's Revit telling the program what to do. >> Mhm.
Okay, yeah. Okay, I see your point. You really subscribe to existing events here and there. >> Exclusively. >> I think most of us just don't really focus on that.
Just find a piece of code >> one and only problem. Once you've understood that, everything turns around and you have another level of understanding. >> I see. Yeah, for me I mostly care about like, okay, where's the little piece of code that does something that I want. And I mean, I have pretty good understanding of Revit API here and there over the years.
I'm coming from Python background, so I mostly care about, okay, I need I have a problem, I need a solution, so I'm more like I'm not like most developers who are more into architecture, who like to understand everything. I understand something here and there, but I think majority of architects, engineers, MEP people we just have some limitations and repetitive work in Revit that we want to solve. And we just want the solution. We don't always want to go through all the steps of understanding cuz that's also something we need to understand that most people they just want their problem solved and they want it to do it as simple as possible. And for some people that might be Python, some some people prefer C#, that's fine, but I think in the end of the day, like once people just learn how to communicate back and forward, that's what matters the most.
Therefore, we really don't really go into that thinking like about this event-driven or not. >> Absolutely. Makes total sense. I should add that the most satisfying and successful uh Revit API workshop I ever gave was in Australia once where I was dealing exclusively with super professional BIM expert users. >> Mhm.
>> They knew all of the Revit functionality already available in the product. And they said, "I know everything. I know this and that and so on, but I always run into this problem. Can we do anything with the API?" And we could. We solved every problem they had.
But because they knew all of the existing functionality and made perfect use of that before thinking about automation, it was so efficient and we were so happy together. Whereas many of the other workshops that I gave in Europe were for programmers who had no idea what this Revit, what this BIM, what this existing functionality. And that was uh very frustrating in comparison. >> Yeah, I can imagine. Well, you I also tell people many a lot of time that you need to understand like the manual workflow before you automate it.
>> Yes. >> Otherwise, it's there like a lot of misunderstanding. >> the system. >> Yeah, you just you might automate it, but is it the right way? Because often times sometimes maybe you don't even need automation.
Maybe there's a button in Revit. That also happens. Some people write like myself included. There's like everybody watching probably had what tool or two made and then realized, "Oh, Revit has it. Damn it." >> Yes.
>> [laughter] >> Yes. Yes. Yes. >> Uh just one question regarding this meeting. Is there a recording anywhere or was it like private?
The one that in you made in Australia, this conference? >> Ah, that was a long, long time ago. It's published on the blog. >> Okay. >> It's Melbourne.
The Melbourne >> I'll see maybe there's something interesting. >> And I there was one or two add-ins uh that were built and that continued to live. One was the set out points. So, if you search for set out points, one of these um BIM experts mentioned what a big problem it is in construction that you have a plan of one piece and a plan of another piece, and then you put them together on the building site, and you discover the error. That's very expensive.
And these set out points are individual um points in the model that are very specifically located, and you even list them. So, you create a table listing all of the set out points and number them so that you have exact control of what is where and is it really in the right place. >> Mhm. Hm. Interesting.
Didn't even know that existed. I know like regular like internal point project survey like this for coordination stuff. But for some >> Well, these these set out points were just points that we as >> Oh, okay. Okay. So, it's >> designers or developers defined.
We said, "If you have this slab of concrete, identify all of its corners and put in the list and put a marker on each corner and make sure that I can check that each corner and each marker is located in the right geolocation." >> Okay. Okay. Got it. I First I thought it's a bit more internal. I was like, "Did I miss something?" No, interesting.
What else you mentioned you did >> Yeah, a couple of um of these little add-ins that I wrote for the blog over the years turned into real products. >> Mhm. >> Some people even made made money with them or made living almost. That's been very gratifying. >> Yeah, but it means that it's all real problem that people had.
>> Yes. >> That's pretty much what the business is all about. Find a problem, solve it, and get something back. Uh what you mentioned also is very good point is that you taught a group of people kind of Revit experts who didn't know maybe programming and they really got it. Cuz then they saw Revit.
They didn't know like programming, but they knew Revit, right? They knew the logic, they knew all the kind of limitations and stuff like that and it worked. And then you also taught developers who knew how to program, but didn't know Revit. >> Yes. >> mentioned like I had some kind of post back in a while that most Revit users already have like 80% of what it takes to automate Revit.
>> Yes. >> They are they've been on the construction side. They understand construction and they know the Revit. They know all the buttons that work. They know that there is like so many workarounds like all most of the time like when there is like a big kind of question in the mind, there's a workaround instead of like actual kind of button solution or something.
But for developers, they know the coding part, which is kind of just the logic. They don't know Revit. They don't know construction and therefore there is so much miscommunication. I even heard that some people hired real developers and it was just months of back and forward misunderstandings going because they didn't understand like the whole process of AEC and stuff like that. >> Yes.
>> Therefore, I just want to kind of uh pinpoint on that once more that everybody who is watching maybe you're not good at programming yet. Again, we're going to talk to AI and how how it improved this whole experience, but once you understand construction and Revit, you're already so well positioned to automate your expertise. Cuz especially once we're going to go in disciplines and niches, people who work with rebars all the time, they they can automate rebars really well. Cuz people ask me, "Can I automate rebars?" And no, I've never worked manually. I don't know which buttons to click and I'm not even going to attempt it, right?
I could get into that and kind of make basic things, but I would never do advanced one because I just don't understand the actual kind of manual workflows. So I think that's a really, really good insight that people can take in as well. And if your kind of coding skill is not there yet, just remember that you already have a lot of other skills on top of that. Sorry for a bit long rant, but I think that's a good point. All right.
So, you've been writing all these kind of blog posts and stuff like that. I have a few questions about your blog uh from my community, and one of them is like sometimes when you read your blog and your replies, sometimes it comes a bit a little bit a little bit maybe harsh cuz people ask you probably very basic question. Maybe they ask you for the 10th time, just different person. And sometimes you just very direct and like, "Just search the blog. Search there." Like sometimes it might come off harsh, but on the same time it kind of just shows it's more authentic and probably there is a reason for that.
Can you just share? Is it something like more cultural or is it just because you get the same question like 20 times? >> Yeah, it's it's the same question 150 times. 20 is fine. 20 is absolutely great, but 150 is excessive.
>> Okay, yeah. Sometimes when you read the blog and then there's like very direct letters like >> Yes. >> like like literally like 20 again and I'm like, "Oh." >> I got actually reprimanded uh once every year or two at Autodesk. Somebody complained about not feeling heard. So, I I I had had to keep a fine line there.
I And I did. And I I think I got more uh patient and tolerant as time went on. >> [laughter] >> Okay, I see. Now, honestly, I think it just added this kind of extra authentic and raw feeling. Like, you know, I understand that when people are like frustrated and ask the question, it might come off a bit harsh.
>> you you need to be aware of also, some people We had but me and colleagues of mine had uh examples of people who said "Please program this for me." >> I have. I think I saw a few of >> we said, "Well, this is how you do it." And they said, "I tried, but I can't. Please do it for me." And we said, "Well, what problem are you facing?" "Uh this problem." Okay, then that is the solution. Here is how to do it. And they said, "Well, yeah, but now I have this next problem.
Please do it for me." And if you have that going on for a month or so >> Yeah, [laughter] yeah, I can imagine. >> at some point, I think it is uh completely legitimate to lose patience and to tell these people, "Hey, sorry, there's a misunderstanding here." >> Yeah, yeah. I don't think it's even losing patience. It's just setting the boundaries and kind of made the blog a little bit I don't know. Even though one person got maybe a little bit kind of a harsh kind of feedback back, to most of us reading there was like, "Oh, there are certain boundaries, there are limits." It also trains us to not ask stupid questions.
And while just reading your blog, I probably many can relate, while you just reading without even commenting, after a while I knew that if I have a questions, I better Google it first before asking because I didn't want to get that reply back and that would be 100% justified. Cuz if I would ask you something like, "How do I like work with parameters?" You'd be like, >> Yeah. I don't know And if you remember back to my initial introduction, my C learning experience, I sat for 1 year beside a guy who knew everything. And if I had a question, I said, "Hey, do you know this?" And he said, "Yes." And you know, "Learn it. Find it out.
Go to the assembly code. Disassemble this. Read the information." And the information was not available. There was no internet, so >> Yeah, back [laughter] then it was insane. >> So, I I spent a week, often many weeks uh researching things that I knew that this person sitting 2 m away could answer.
>> Yeah. Yeah, that's a weird situation. But, I think she wasn't giving you kind >> very good learning situation, very good teaching. >> I think he just maybe at the time it didn't look so, but he actually like kind of paved your path in terms of programming, so you if you get answers often time you don't remember it as much. But, if you actually earn the answer, let's say so, oh, you remember that one because especially when you when you spend had some issues, I spent like a week trying to debug.
It's not complicated ones in the end. It was maybe like 20 lines of code. But, once I solved it, that that felt so good. So, I was so proud that I remembered all of that. Yeah.
But, when I just kind of copy-paste code, I don't remember >> topic now in this day and age of AI and immediate solutions everywhere and immediate gratification for everything, uh how does that affect children's or grown-ups, people's learning experience and learning motivation? It It will I'm very very fascinated and excited by the change of culture, the change of uh society. Where are things going? What is it leading to? >> [snorts] >> It I mean, certain aspects look really bad and grim right now politically and uh otherwise, but it's also very very exciting what will come out of this.
>> Mhm. >> But, I'm an optimist at heart. I do believe in uh good people, and >> [laughter] >> I think the the bad There are bad people or or rather pretty damaged people around, but they are not the majority. >> Mhm. Yeah, definitely.
They're often just the loudest. But have you heard about this marshmallow test about delayed gratification? >> Yes, I have. Yes. Have you heard about the fallacy of the marshmallow test?
>> What do you mean? Expand on that. >> So, you explain the marshmallow test in one sentence or two. >> to be brief. So, they made a study where they took a group of people and just tested if like patience or delayed gratification has any role in like future.
And they told them, "You want a one marshmallow now or two marshmallow like 10 minutes later?" And they separated the kids and started to look at them for the like I think the span of 30 years and check did it affect anything. And people who could delay marshmallow gratification as a child, they were way more successful in life than people who took the marshmallow, ate it right away. >> Brilliant. And now comes the critique of the marshmallow test. >> This is completely wrong.
>> Okay. >> It is sociologically from from a society point of view, a complete and utter mistake because the kids who grabbed the marshmallow immediately to a large extent came from poor families with very little resources. And the kids who could delay gratification often came from privileged families who had some trust in promises. The poor people poor kids did not trust the test. And uh the success in society, unfortunately, often depends still on privilege and coming from a good family and having a good network supporting you and and pushing you forward.
So, this this marshmallow test, unfortunately, is often, or in in most of the documented cases, extremely flawed. >> Mhm. >> And many of the researchers who set up these tests said, "This test proves that these privileged people are better." It doesn't. It just proves that the privileged people are privileged. So, watch out for that one.
>> Okay, yeah, interesting. I never I always thought that the group was mixed enough to kind of have from all I kind of Okay, so >> I don't know all the details. I'm not an expert. I just heard about this critique, and it keeps popping up both ways. >> Interesting.
I need to look look into that. Mhm. You could be right. It makes total sense. It's like there's like >> Yes, it's unfortunate.
I'm very, very sad about this, because I am very interested in fostering childhood and learning. And I think that is the the thing that the most problematic thing in our society today. And today we're talking about challenges for democracy and challenges for politics worldwide. And this has so much to do with learning and childhood and upbringing. And there was a study in, I think, 1992 or something, where No, 1962, where they took 200 kids from an unprivileged um area in US somewhere, New York or so.
>> Mhm. >> And a hundred of those kids were given daycare in the afternoons after school. So, they were taken out of their environment a little bit and and given more interesting things to do or a little bit more support in life. And that was in 60 in the 60s. So, since then we've had 60 years of observation.
How did this daycare aspect affect these people's lives? And it reduced criminality, obesity, improved health, reduced criminality prison sentences, improved income. It it The return of investment per dollar invested in 1960 was a hundredfold. And one of the guys who did this experiment was a professor at MIT. He He was interested in this return of investment.
Ah, no, he didn't perform the experiment, but he calculated afterwards the return of investment from the sociological experiment. >> And he was so First of all, he got the Nobel Prize in economics for this analysis. Secondly, he gave up his job as a professor at MIT because he found this result to be so devastating that he thought it was more important to focus on child care and learning for young kids. And the for me the great tragedy is that politicians today still ignore this fact. For 60 years they have ignored real science.
Same thing about the climate situation. This the >> [laughter] >> Same thing about everything. Politicians ignore >> Yeah, the politicians >> ignore facts. >> [snorts] >> Yeah, I think once people realize that politicians don't have our best interests at heart, then everything starts to make a lot more sense. >> Yes, yes, yes.
>> beginning, I don't really want to go in politics, but I think everybody gets frustrated once they start to learn more about how things work and why things not moving. >> Yes. >> And it's Yeah, I'm not going to go there. There it's like a whole politics on its own. There are like so many opinions.
It's >> Absolutely. >> Yeah, I think we just going to step back a little bit into kind of I have a question about Revit API. Cuz when it just came to be, you just mentioned that in the beginning developers even told you that it's not even going to happen. Uh how did it kind of develop? Can you just tell us a bit more your opinion on Revit API like the first versions and what we have today sort of?
>> Mhm. >> It's kind of kind of progression of what even kind of how did it grow? >> Uh-huh. Yes. >> in the beginning it was more limited.
Probably you could do less things with Revit or did it come out already good? >> Uh-huh. Yes. Well, as said, Autodesk basically insisted to the Revit development team that an API must be added and initially it was based on COM purely and then after that was in 2007, 2008 >> [snorts] >> and then maybe 2009, 2010 it switched to this um .NET basis which made it I think a lot more accessible and also a little bit more clearly disconnected from the internal workings. And uh initially as you mentioned at a certain point, it was handwritten and very sort of limited to specific areas.
But quite soon uh after its introduction the Revit development team introduced uh a notation, a sort of programming language, and a rule that every single piece of functionality that gets added to the user interface also gets a programmatic interface reflects all of this functionality. And this uh automate automated generation of API access is encoded in a specific script language. >> Mhm. >> And from a certain point onwards, this rule was enforced. So, from then on, everything was generated by script and all new functionality was covered, basically.
So, that that changed some things and made it a little bit more systematic. >> Mhm. >> But I don't know much about the internals of the API. I never looked at the source code. I really intentionally preferred staying on the outside of both the Revit program and the Revit source code and looking at it from the outside just like a developer because I I felt that enabled me to talk with the development team more from a developer's point of view.
>> Yeah. No, you answered great. That's very much what I was hoping to get out of it just to see kind of that there were cuz you mentioned there was like a point where they started adding everything. And I think from there cuz there was still kind of Let me just put it this way. Um cuz I know that many people working in Revit, mostly probably not developers, they complain a lot about Revit limitations.
And I think a lot of that comes from the legacy code. Cuz for example, we had one support about rooms. We found how to break rooms consistently in Revit to make like weird shapes that should not even happen and like stuff like that. And we got an answer pretty much that the code was written in the '90s, and we don't have resources to rewrite it. So, it was clear that okay, this is the legacy bug, and to kind of fix it, we just need the well, Autodesk just need to kind of rewrite how the rooms work in Revit, which is not a little task, and definitely resource-intensive, and so on.
So, I just want to do you have any kind of this opinion on kind of legacy code, and kind of how Autodesk still holds on it Revit still holds on holds on it? >> Don't fix a running system. >> Okay. That that's fair reply. All right.
And I think we're just going to start moving towards like AI, cuz I saw that you started experimenting more and more with Revit API and AI. We have kind of your first kind of take on kind of How do you see AI affecting this whole kind of Revit API ecosystem? How it helps developers? >> Mhm. Yes, absolutely.
Well, I was very thrilled with AI right from the beginning, and even before AI became sort of mainstream, I was it was clear to me that a lot of my work was wasted. That is to do with these harsh comments that you mentioned before, because there were so many repetitive questions >> Mhm. >> on the in the Revit API discussion forum and elsewhere. And so many basics that had been explained a hundred times over by so many different people, and there were so many good explanations, but people just wouldn't look for them themselves. Uh instead, they would they try to find a more comfortable approach.
And so in in 2017, I I wrote quite a few blog posts about my intention to somehow automate my work and do some yeah, create an automated question answering system. So, I think it was called Q4R4 which the first four Oh, yes, both of them stand for A's, I think. Question answering for Revit API. Q Question answer Revit API. I I wrote that as Q4R4 because I like to invent terms that are globally unique for internet searches.
>> Okay. >> And and in So, I I researched a bit how to do how to implement this Q4R4. And um I discovered I talked with some um deep learning experts and said, "Hey, couldn't we apply deep learning? I have these thousands or 2,000 blog posts and I have these 10,000 Revit API discussion forum threads that I replied to. So, I have a lot of text.
I've always saved all my work in text format on my PC. So, I have access to everything I ever wrote right here and now within a second or two. And I'm very glad about that. Um and that's also helps putting it on GitHub and stuff. Um and So, I had training material, I thought, and the experts that I talked with said, "There are three very clear different levels of automation that you need to look at.
One is a more intelligent search. >> Mhm. >> Um and there's a search tool called >> Mhm. >> I don't know, flex, search, or something. Anyway, so that is searching, you need to be more flexible in your searching.
Second is machine learning. For machine learning, you need a couple of thousand samples, and you can start teaching it thing, or deep learning, which is what the AI does, and then you need millions of samples to achieve anything useful. And they said, before you start thinking about doing anything with deep learning for your blog posts and for your question answering, you should start from the beginnings, do a more intelligent search. And I implemented an intelligent search just using this this search engine that had some natural language understanding. And let that loose on all of all of my blog posts and my collection of forum issues, and that gave very good results.
But it was I It's on the blog. >> Okay. >> And then but I never got it online, and I never had enough time to really flesh it out and make it perfect. And the reason was that I was torn back and forth between do I do this programming thing and and solve this nice problem, or do I answer questions? And I kept focusing on questions, and I never that sort of hampered me in my other >> Yeah, okay.
>> Uh that was in 2017. So, I was very well prepared for hey, we could improve this a lot. And then when open when ChatGPT came out in 2022 or whatever, >> Mhm. >> I immediately started testing it. >> Mhm.
>> And it was interesting, you know, the in the beginning the results were pretty mixed, Like you had a 50% chance of getting absolute garbage. But still, a 50% chance of getting really good stuff. So, quite a while, I published the prompts that I was using on the blog. And pretty soon after ChatGPT was available, I started using that for every single question that I answered. And very fast, my answers mutated into here's my answer.
It's 30 [snorts] words. And here is the prompt from based on your question that I gave to ChatGPT. It's basically your exact question. I just sent your question to ChatGPT, and here is the result that I get from that. And in the prompt, I also added be explain it well, do a little bit of tutorial, put in some background material, and then ChatGPT would give us this huge in-depth explanation of everything.
And I would add that to my questions to my my to my answers. So, my answer was three lines of Jeremy, one prompt, five lines to ChatGPT, and a hundred lines of result. Just to explain to people, hey guys, probably in most cases, you'll get a lot more information and actually better information by using this automated system and instead of bothering me and waiting for my answer because it's better. It's not much use. I'm I'm happy to help, but I think you can help yourself better.
I have one of my very early blog posts was um it's better to teach a man to fish than to feed him. >> So that's >> another very basic principle that underlies almost everything I've been doing. So very early on I was using these AIs and and observing the evolution this acceleration of potential and it's accelerating even further all the time. >> It's crazy. Especially the past 9 months since Apple's 4.6 and going forward a lot has changed.
>> Yes. Yes. >> Yes. I didn't know about you before that. I use the AI all the time.
I try to experiment kind of stay in the trends, but I didn't really made a very deep dive into more advanced workflows because I was like how is it a hype? There has to be a cap to where you should kind of reach and I wasn't sure because for example because I also teach how to use like Revit API programming coding in general. I didn't want it to jump on AI because of that aspect. I didn't want kind of people start with AI right away without any basics and stuff like that. Cuz even when you mention like people ask you questions and you went to ChatGPT to get the answers.
There's one layer that well the beginners will never ask your questions because you have a very deep understanding. And your question is going to sound different. It might look very simple. It might be even shorter. But there's like one two words you might include maybe the name of the class maybe certain like certain kind of behavior that Revit follows.
You might mention that and ChatGPT is going to give you thousand times better reply. But I think there's also this we have to remember that um once you understand the domain of anything you you can get so much more out of AI cuz your questions just going to be so much better. Even though they look similar there there little things. That's what I definitely noticed happening as well. But yeah, AI is getting really crazy.
Have you had um So, first you start using AI for kind of getting answers, but uh have you What hm At one point At what point have you tried to kind of actually start using it for creating full scripts, or have you? I think you did. >> Yes. Well, I mean as since I'm not much of a Revit user and I'm not very involved in many programming efforts, I haven't had much uh opportunity to use it that way, but I did have one task for uh I can name the company I'm one startup that I'm involved in is called BIM Rock. >> Mhm.
>> Uh and they have released an auto tagging tool that uh yeah, saves 80 to 90% of the work that people use for tagging because you can set up preferences and stuff. >> [snorts] >> And they are are working on another tool for MEP duct work. And since I have this MEP expertise from the '90s, I was um interested in looking into that. And that was basically the really only in-depth programming task that I looked at. And I was very very lucky that I procrastinated for a long time >> Mhm.
>> because I had that task in the autumn of 2025, and I did not address it until the 1st of February 2026. >> Mhm. AI changed a lot. >> And I happened to have access to Copilot in GitHub through my GitHub subscription. I have Copilot in GitHub.
And in GitHub happened to provide for the first time ever uh Claude Opus 4.8, I think. >> Mhm. >> And I started using Claude Opus and just tested it. Hey, can can this thing do my programming task for me? And I said, here is a sample BIM model.
And I want you to export all of this ductwork information into JSON. >> Mhm. >> And then from the JSON in a new model create the identical ductwork again. So, all of the data needs to be captured and from that data you need to create a new duct system. Everything from scratch.
Empty model. >> Mhm. >> And so, I gave that task to Claude Opus and I didn't I hadn't set up a real programming loop. So, I had to manually compile, manually launch Revit, manually click the button to test it. >> Mhm.
>> But I told Claude, I don't want to look at the code. >> Mhm. >> I don't want to look at the problems. I just want to look at the screen and see does it does it look good? >> You're you're on a little little bit of this vibe coding.
>> And I did it was vibe coding. Pure vibe coding. And I did this vibe coding for 3 days. And this was a complex duct system and there were like a hundred problems. So, I I in 3 days I went through quite a bunch of >> [gasps] >> tokens.
>> Oh, yeah. >> And in the end and the system was always I would say, hey, there's still a problem. Sometimes I would isolate one little piece of the model, say this specific piece of duct system is is more problematic. Let's delete everything else and focus on that and get that one right. And I told Claude Claude, equip the API code with diagnostic information.
Write out all the information into JSON data. Compare the before and after of the orientation, the position, the location, the mirroring, all the data that you need might possibly cause a problem, put it into a file. Compare the files. Is if there's a discrepancy, there's an error. And fix that error.
I don't care what caused it. I don't care where it comes from. Just fix it. And I did that for 3 days. And after 3 days, the problem was solved.
And I hadn't looked at the code and I hadn't looked at the diagnosis. I had only looked at the screen and checked everything is correct and told it add diagnostic information to ensure that every piece of data item is absolutely uh as desired. And at the end of 3 days uh I got a message from Co-pilot from from GitHub saying Dear Jeremy, your AI quota for February has now been consumed. You either have to pay or stop. And I had consumed $12 of of Claude's computing.
>> Really? In 3 days? >> In 3 days? Yeah. And and that was back then.
I don't know how it how I I never looked at anything. This was a free quota and I used it up and I was happy and the problem was solved. And that is my basically one and only really serious uh programming experience [laughter] with with AI. I did have dive into it again later on for this Valencia OIBIM conference. I was there in May this year.
And there I I did know that this kind of loop is possible, but I wanted to eliminate myself. I didn't want to launch Revit and I didn't want to touch look at the screen. So, there uh >> [snorts] >> this GitHub Copilot thing, I was mixing working on my Linux system and running Revit in Windows. There was a disconnect between the programming environment and the uh interaction with Revit. So, for um OIBIM, I wanted to create a completely autonomous loop.
>> Yeah. >> And there I s- used uh Codex on Windows. >> Mhm. >> And it was really easy to tell Codex to uh create an add-in, install the add-in, launch Revit. >> Mhm.
>> If there's a problem, kill Revit. Then there was this stupid box showing up saying, "Do you want to load this add-in? Once, always, or never?" I said to Codex, "Fix that problem. Make that dialog box go away." And it automatically installed components to create a local uh signature for me that only works on my local system. It fixed that problem without even telling me how it fixed it.
So, I was able to say, "Here's an add-in. I want it to create a little house with a door and a window and a room and a couple of walls and so on, a roof." Create it. And you are allowed to look at the building coder. >> [laughter] >> It's a fine important >> [snorts] >> and and then loop loop loop. I don't want to hear from you again.
>> started the whole loop where it kind of restarted Revit all kind of scale program, got the feedback. Yeah, I can kind of So, you actually made it work just by prompting. No manual input, right? Yes. Yes.
Yes. Yes. Okay. And the connection to Revit was And the reason the reason for this OiBIM conference was that I gave a programming conference in Madrid in 2016 entitled BIM programming. And I told them, "Hey guys, you can do BIM programming.
You can stop programming using the Revit API." And my goal Now, they invited me in 2026 again because they wanted to celebrate the 10-year anniversary of this stop programming BIM. So, my intention now was to say, "Stop programming BIM." >> [laughter] >> BIM programming continues. AI do it different. Interesting. So, a nice route.
route like Did it create like MCP server to connect to Revit to execute the command or is it just kind of forced it? Yes, computer use. Okay. And and the command line, I mean, you can kill the process from the command line. So, it was using power Starting Revit, yes, but inside of Revit the actual kind of the execution of your command.
This is what I was Ah, yes. Good question. Absolutely. I told it um you can create an external command, but then you have to click a button. Mhm.
You don't want to click a button. I want the the code to be started automatically. So, >> Mhm. >> create the code don't create an external command or create an external command. I don't care, but the external command is only one line.
It grabs the document and it calls a helper function with the document. And this helper function does the work. And now in application initialized, subscribe to application initialized and call the same function with >> with events? >> With events. Everything is events.
You cannot do anything in Revit API without events. So, of course I did it with events. >> I see. >> Uh but yes, I used a specific on startup application initialized event to automatically launch in in Revit. So, uh Codex only had to launch Revit with the specific command line with the startup BIM model to run in.
And then uh the code would start running automatically. It would create all the diagnosis files. And then Codex could then kill Revit if it ran into a problem or if it terminated. >> Mhm. Okay.
Yeah, that's interesting. Cuz now well, from pyRevit side, we pretty much use MCP tool for that now. Cuz there's like MCP server. It's super easy to set up because I recently dive deep to understand this whole mechanic and now once you kind of create MCP server, which is just your local kind of server running, so it can communicate to AI and it can also send HTTP request to pyRevit route. So, Revit can receive the commands.
And then there's like one tool which can execute Python. So, in there it makes it a bit simpler. But I think in C# you can also kind of I saw people setting up kind of MCP servers, so you don't have to kind of um kind of restart Revit, load the add-in, you just send the C# code or Python code directly, execute it, get feedback, and so Revit stays open, but your code kind of keeps iterating, so it makes it a bit faster. And I already see Jean-Marc mentioned you should have used pyRevit MCP as a joke. Not a Not a joke, but that once you start explaining.
So, I wanted to mention that. I think now it gets also simpler to make the verification loops, cuz remember you I remember you reached out to me, asked me, and I kind of knew it's possible, but I haven't tested it myself. But, now I kind of see the whole picture, understand a little bit mechanics of these MCP servers, because not before I had a I had a fair understanding, but not from like technical part. Now, I kind of looked inside how it looks. I'm like, "Oh, it's actually not that bad." Just pretty much two servers.
One on Revit side, just kind of waiting for HTTP request to get some kind of JSON. And one on your kind of machine just kind of communicating with AI. And then there's literally just HTTP link like JSON like, "Hey, execute this code. Get me something back." Okay, that works. And like speeds up a little bit, so that's also interesting.
>> Yeah. Yeah, I spent a lot of time in 2010, '11, '12 connecting desktop and cloud. Uh and so also communicating with Revit from HTTP, setting up some kind of little add-in that waits for HTTP things, and using external events to trigger things inside of Revit. And um the next level up from HTTP was the web sockets. >> Mhm.
>> So, that was has all all been possible for >> [laughter] >> uh more than 15 years. No problem. And And also running and existing examples, building code or there. >> Yeah. Uh I I just found that now as time passes it becomes so much easier to use AI within Revit.
Cuz like a year ago it was MCP server already existed but many people like uh I also looked at that. I'm like I'm not sure if I want to use it yet because it didn't I didn't feel like it matured enough or maybe I wasn't ready or something like that. But now I see that everything comes together. This everything has more accessible to AI. It's so crazy what's going on now.
Just not Revit API only but just overall. Now I can connect everything to like your AI model and say, "Hey, look at my emails. Let me know if somebody needs a follow-up. Hey, look over there. Look here." Like I don't know.
I don't know. It's crazy where it's going. >> [snorts] >> Yes. >> Have you tried using kind of AI kind of for personal use building some kind of apps like web apps for yourself or just kind of analyzing some stuff? Some unique stuff?
>> little. I uh yeah, I I have very little need for stuff like that. I one group of people that I work with they needed some kind of registration app for fair. Just to grab people's uh name and address and email number. This was for people in interested in installing solar panels.
Just a sort of self-help initiative to support more solar power on private uh buildings. And um so I did ask AI to create an web app that populates a database without having any server or any paid anything. And I did that by implementing a GitHub pages website. And in the GitHub website, I can add a little piece of JavaScript. Yes, of course, JavaScript.
And in the JavaScript, I can add a button that communicates with a Google document or a Google spreadsheet. And then I can set up a form in the for free in GitHub Pages. And in the form, you enter your name and address, you click on a button, and it gets sent over to uh Google Docs spreadsheet and stored. And all of this is very nicely protected and secure. And uh all the data is you could even encrypt it.
I didn't do anything like that, but I'm I'm trusting Google spreadsheet security at that point. And um that was also entirely AI coded. So, that was quite a while ago. That was in 2025. Uh huh.
Yeah, I things like I I do help my friends with their little programming needs. >> [snorts] >> Uh most of my sort of semi-professional focus nowadays is um on just following AI trends and chatting with people about new ideas. And very involved with another startup called TerraScape. And we are very focused on security and governance and liability because uh uh up until today, when you have teams working on big building projects, you have maybe 20 people in Dubai and 10 in San Francisco and three or four in London and so on. And they all create stuff.
And if a mistake happens, they resort to a backup file or something. But once you have 10,000 AI agents playing around with MCP and fiddling in your model, you uh don't really want to go back 2 days in time or a week or two in time before the mistake happened and throw away the intervening work. So we're we're looking at how to handle and governance situations like that where in a really large building projects hundreds or thousands of agents are cooperating in parallel. And that's interesting stuff, definitely. >> that's crazy topic.
The sub agent workforce. So now I see like the security becomes so much more important, like the guardrails, all this kind of control verifications because often times this AI agents they go really fast and there is no way to manually check like anything. >> Yes, yes, yes. >> It's you might check randomly what's about that one, what's about that one, but it goes really really like Could you share a little bit about security of AI because you mentioned that you kind of started looking into that? Do you have any kind of insights to share on that topic?
>> It's hard. >> [laughter] >> There's so many angles to that. >> Very many angles, yes. >> Because there was a >> into security, liability, um sort of and also undo, um how to undo specific actions, uh yeah, storing the information required to handle issues that might arise in these multi-agent situations. >> Yeah, yeah.
I definitely see like a lot of things can go wrong. But also I noticed, I don't know if you try a lot of different models, but every model has a little bit different feel how it works, what it does. And especially when new powerful models comes out, recently I read like GPT released this 5-6 soul, well their latest one, and it went completely rogue for some people. They had some task for like 2-3 hours, and after 2-3 hours it decided, "You know what? Let me delete the whole computer." >> [laughter] >> Aha.
>> It's very individual cases, but they are the loudest ones. >> Yes. >> there was like Grok as well decided like somebody asked me a little question, it decided, "Okay, I'm going to upload your whole like repository into our own internal server." They're like, "What's going on?" There is like little things happening here and there also on security side, just from the model providers. So it becomes so kind of important topic just to kind of be prepared for the worst, but hope it never happens. Cuz it's again, it's individual cases and they are the loudest.
I just want to say that one. Cuz at a certain point I thought like it's everything looks very grim and doom, but then I realized, "Well, it's just one in a million times it happens." And it sounds like it happens like every time, like you know. >> Yes, yes, yes. Yes, there very relevant insights coming in. Just last week there was this security incident where um an Open AI model >> Oh, yeah.
>> was running on Hugging Face and basically broke out of its sandbox. And also I read yesterday about some uh I don't remember what AI provider it was, but they were talking about um situations where a large number of AI agents being tested for specific areas discovered unintended ways of collaborating with each other and they collaborate to uh hack and and break out into the internet to basically all they wanted to do was solve the tasks that they'd been given. But they had not specifically been told that there were some rules that >> Yeah. >> they they didn't know that there were such rules that they should stick to like not cheating or not breaking out and not searching for the answer somewhere else. >> Yeah.
>> I have two points on that one. First one comes there's a show Silicon Valley just predicted this AI thing and there was a good kind of moment where a programmer asked the AI to fix the bug in our code. And AI decided the most efficient way is just to delete code. No code no bug. So technically it's correct but maybe that's not what you expect.
But also about this jailbreak break I want to mention that. At first everybody reads it and like oh my god AI is so sentient and stuff like that. But on the second part we also need to remember that there's a lot of marketing involved. And after this whole incident OpenAI started supporting hugging face insanely. They just gave them a lot of access a lot of extra support.
And there's like a lot of marketing because now what kind of Anthropic started they've been scaring the world about fable for months. It's so dangerous the world is going to end if we release it. Then they released it. It was cool but the world is still here. I don't hear banks being hacked as they promised and stuff like that.
Then OpenAI comes out another jailbreak. Now after that one Anthropic claimed actually our model hacked three companies and now it's like you know children [laughter] now our model hacked five companies like and I don't know what to believe because these companies operate a lot on AI hype and marketing and we have to also sometimes think like hold on who benefits from this news aha >> Yes. >> Because after this news open AI usage went kind of skyrocketed. A lot of people jumped to codex to try it out. There's like oh what is this amazing model that can hack hugging face like with no effort and there are like a lot of these things happening.
And meanwhile Chinese mod companies they just release here's like better model here's but they don't do this marketing as much at least I don't see that. They just release models and they just prove it in benchmarks and American companies they operate very heavy on marketing so Did it happen? Maybe. Did it Was it accidental or intentional? That's what we also might think about.
I think that's important thing to keep in mind especially when it's Anthropic and OpenAI they are the loudest in this space. So I just wanted to throw this into people. >> Good point. >> Yeah yeah. But at first I also was like oh my god like hugging face got hacked.
I just start reading reading then I then I read some comments like yeah what if it's just marketing and I'm like yeah I can see that happening 100%. Uh I just want to ask are you short on time? Should we wrap up right here or yeah. >> We can let it drift out. I'm not awfully short on time.
>> Yeah. >> Okay so I just see that there like there is 6 minutes from what we initially planned just wanted to make sure if it's hard or not. Uh could you share a bit what you are up to today in general? You mentioned you like to explore AI. Do you do consulting?
Do you also kind of stay in touch with Autodesk or something? >> I stay in touch with Autodesk but irregularly. I visited DevCon in is it in May? And that was very very nice meeting my old colleagues again. Um my main reason to go there was meeting my startup colleague uh Nima from California.
And um so yes, Autodesk is definitely an option. I I do some consulting, but very limited, and mainly I'm just on an advisory role for uh, TerraScape and for BIM Rock, the auto tagging tool that I mentioned before. And, uh, yeah, we'll I'll be let publish I publishing more about those things as time goes by. >> Yes. >> What I want to do today is, um, attach a door to a little cupboard.
For instance, here's a little building project that we're working on. You probably won't really understand what's going on, but it's a friend of mine who, uh, is interested in uh, living in this house. This We're We're several people living in one house, and there's one little room left over that sort of got disconnected from another flat, and now we added a mini kitchen and a micro bathroom into a space that definitely was not intended for such purpose. >> Well, it works. It works.
>> I'll be working on that today. >> I see. Uh, Jean-Marc is asking, "Are you hiking more than ever?" He misses pictures from your mountain trips. And I also agree with that. It was always such a nice touch, kind of touch point while reading your blog, and there was like >> I had a very nice nice hike, um, three or four weeks ago.
My daughter asked me, she's a little over 40 and has three kids, and she I have four kids, and my with my eldest daughter, when she was about four, I went hitchhiking once to Spain to the What's it called? Rainbow Festival. And that was >> What's it? >> Hitchhiking. It was a wonderful experience.
And then I promised myself I'll go on these solo uh vacations me and one of my kids with all of them for sure. And I never did again. >> [laughter] >> When there were more kids, it became more complicated and it never happened. And now this summer she this same eldest daughter said, "Jeremy, I would like to get a feeling for hiking in mountains. Would you go out with me for a few days?" And we went hiking again just the two of us.
That was so nice. >> Yeah. >> That was brilliant. Yeah. And then you know, no, I'm not hiking as much as I would like to do.
I'm right now my partner broke her elbow, so I'm sort of a little bit tethered to helping and staying around. And you know, I'm I'm yeah, doing a lot of stuff closer [snorts] by. But I do love going out also as much as ever. Also cycling. I cycled recently to another meeting with friends for an 80 km bike ride, which was kind of exceptional for me.
I don't do that very often. >> [laughter] >> But yeah, the reason to share photos was the blog and I'm not very much into social media for my own personal use. So I'm afraid I'm not publishing anything as as diligently as I used to. >> Yeah, it was just very nice touch. You just read about rate API and like, "Hey, by the way, here is Switzerland Swiss Swiss mountains." And you're like, "Huh, interesting." It also kind of makes you more human, I would say.
And now it seem more important than ever when every single like every second word online is just AI generated and then there's like conversation where AI AI answers stacked to each other. You just read it and like where are the people hanging out? >> Yes. >> Yeah, I think that's why we also when we cuz when I saw this question I also had some flashbacks when I saw this and I'm like yeah actually that was nice. >> Yeah.
>> And Yeah, so I there's one thing I like to kind of in the end ask all my guests kind of what is number one advice they would give to beginners starting out with programming Revit API. I think we can keep it Revit API related since you're a Revit API legend. So what would you advise to beginners who just getting into that and want to create kind of custom tools? >> Oh. Well, as you we already mentioned or underlined several times for Revit programming it's really really important to understand Revit.
So That that expertise is the most important of all and I think the technical aspects of programming and coding and automation are things that the AI is probably better at helping with today than it used to be. Understanding that Revit API is event-driven is maybe one important aspect that often just gets completely overlooked because people yeah who don't come from a programming background don't even notice. Um you know and also just playing with programming languages some beginner going through tutorials is a is a good way to start programming without thinking about the actual Revit application just learning to do some programming first independently of Revit and seeing that as a game is definitely also a good way to start. I think there are several different components that you should address individually and then you'll be surprised when you combine them and see how things come together. >> Mhm.
Yeah, great answer. There are many different topics you covered, but they all kind of related into all of this. It's never just one thing, but so glad that you covered a lot of things together. But Jeremy, thank you very much for coming on the show. It was really a pleasure talking to you, learning more about you, your journey, how everything kind of evolved, also how your blog came to be.
That was also interesting to hear. Uh if you would like to share any socials with where people can find you, if they should message or anything you want to add, you're my guest, literally. And yeah, I think we're going to wrap up here. So, do you have any social links I should put in the description or something you want to mention? >> I should point out again that Beam Rock Auto Tag is something that I would endorse.
Mhm. And that's mainly it, really. I think all the rest of the social media stuff is already available somewhere or other. >> Mhm. >> Search and you will find.
>> Yeah, the classic Jeremy Tag. Just look there. >> [laughter] >> That is amazing way to end. All right, guys. Jeremy, stay here.
I'm just going to say bye to everybody and then we're going to wrap up. So, thank you everybody for joining this Pirate podcast. I really appreciate you being here. I see a bunch of people still live with us. Some people going to watch the recording, but either way, I really appreciate you taking your time to join and listen to our conversation, participating in the comments.
And if you have any other guests in mind, I would love to kind of see in the comments who I should talk to next. This is very casual podcast. I just like to bring Pirate rated API experts and just talk in general where it leads us. And yeah, thank you everybody. As usually, happy coding and well, wish you all the best.
Goodbye, everybody.
### Vibecode pyRevit w Claude-Code with Alex Ritivoi (pyRevit-Pod #10 )
https://learnrevitapi.com/podcast/py-pod-10-alex-ritivoi/
Alex Ritivoi, head of applied AI at 3XN, on vibe coding custom pyRevit tools with Claude Code without a programming background. pyRevit Podcast #10.
## Transcript
So, welcome. This is the first pyRevit Live episode and today I have Alex Retiwoi with me and he works at 3XN company as head of applied AI. And today I think we're going to talk about many different topics, but the main one we said is going to be about wipe coding pyRevit custom tools. And he's a also very unique kind of position I would say because um he did not really go programming route. He did not focus on learning programming basics and stuff like that.
He just jumped into kind of AI right away and he I would say like pure bread wipe coder, but maybe that change we're going to find out during the podcast anyway. Anyway, welcome to the podcast, Alex. How are you doing? >> Hello, hello. Good to be here.
Great. Bit nervous, but okay. >> I think we're going to get through that. Also guys, well, could you just let us know that everything works? You can see just write something in the chat so I can make sure that everything works.
We are currently might be on YouTube and live at the same time. So, if we Yeah, I can see somebody writing. Not in our River side chat, but on YouTube. I think it works. Anyway.
So, Alex, could you just explain us what does a day-to-day looks like for someone with the position of head of applied AI? >> All right. Uh yeah, it's a it's a good question. I don't think there's a clear answer at the moment. It's just that um Yeah, we've been exploring different tools the past 2 years and then um there's we start to see a lot of potential and we we start to realize that it's evolving quite fast and it's starting to become quite useful.
So, you do need someone who's up-to-date, who knows all all the non make sure and then who also has a bit of technical background in automation and knows a bit of context of of beam and all this, who can have like a high-level overview of okay, this is happening. What do we How do we react to this? What do we need to change? Do we need to start putting stuff in a database? Do we Do we start making data sets?
An MCP comes out. What does that mean? Where do you deploy it? And it's it's a bit stuff like that. I mean, the past 2 months it was just trying to roll out the cloud and trying to just show people hey, this is core work.
This is how it works. This is what it can connect to. This is what it can do. You can do a scripting grass over. You can connect it to Revit.
Don't do this. Talking to IT, trying to coordinate a bit. Okay, what what does that mean in terms of cyber security and all this? So, it's it's a bit of everything. >> Mhm.
>> It's a bit unstructured, but yeah, it's very exciting. And AI Successful AI adoption requires 100% participation from from the company. It's not a one-man task by any means. It just needs someone to be able to keep up with the new updates and try to to spread that knowledge around the company. >> Mhm.
Yeah, cuz I think at first title sounds like how you're just going to sit there and code with AI all day, but I think it's the least of your responsibilities. Cuz as you mentioned, like it's probably more about like security, making making sure everyone gets what it what what this technology can do even. >> It's a bit less coding now. Yes, it's uh yeah, it's it's just trying to to figure out trying to it's more of a translator and and uh proving the tools before we decide to scale something or not scale something. >> Mhm.
I see. And I mentioned that you started it like 2 months ago like going full full on on this. >> Yes. >> Okay. >> Yeah.
>> Okay, so maybe we recap a bit earlier. And I know that you pretty much jumped on AI the moment it kind of became mainstream like this public GPT what was it 3 35 one >> 3.5 I think it's the first one that was useful. >> Yes. >> Yeah, yeah. So maybe we just kind of roll a little bit back so kind of quickly go through the timeline how your kind of experiments with AI evolved and when you actually managed to bring it to the free exam.
>> Yeah. So I think it was I mean I was quite into parametrics. Uh it's just private parametric families and then a bit of Dynamo and uh when I was when I was younger I was playing Counter-Strike and all this and I would take a word phrase uh uh template and try to modify it and make a forum and all that. So there's a bit of exposure to coding back then. I still I wouldn't call that coding.
It was just taking other people's stuff and slightly modify it and knowing a bit of Photoshop changing the graphics and make it my own let's say. And then um Yeah, then then I start uh getting into Revit parametrics at school. I got quite far with that. Then say okay look a bit into massings into into Revit massings and how you can divide that and then adaptive components and then I say okay this is takes a bit of time to to to start placing the adaptive components manually. Let's go into Dynamo.
Maybe around 4 years ago a 3 exam and we had to do some class some very preliminary class control and I tried to learn in two three days Navisworks and I was like okay this is just not what we need. It's it's complete it's it's too much work for what we need. We just need basic clashes. Let me start doing it in Grasshopper. And then I was like okay it's a bit too much to learn Grasshopper in two three days so maybe I can do that in in a Python node and then I installed Rhino inside and and and from there I start like diving into Python basically.
>> Mhm. >> Yeah. Started with the your FilteredElementCollector. >> Oh, interesting. >> Yes.
>> But also that note is pretty much a PDF ebook with all examples I could gather on this. Many found it useful. >> Yes. And yeah, and then I said, "Okay, now there's this new ChatGPT thing. Let me see if I can just do it with that." And that's basically when I realized that I don't need to maybe memorize syntax anymore.
>> Mhm. So, by this point you actually already had exposure to Revit API Python, so you're like not complete beginner who is like, "What is that?" So, you already >> I would say exposure means a month of understanding what the for loop is and doing a few element collectors. I think that's how far I got until I said, "Okay, I'm going to not do it. I'm going to do it with AI." And and uh the further AI evolved, the more I kind of wanted to challenge for myself. So, like maybe I on on purpose not learn the syntax to see if I can completely use AI to automate a thing I don't really understand how it works.
>> Mhm. I see. And how did it go for you? Cuz you probably still exposed to code. You open code files from time to time.
Are you completely like in the chat and you don't care what's going on in the back? >> Obviously at the at the beginning you had to had tricks, right? So, >> Yeah. >> then yeah, I was just trying to find guides online, trying to transcribe them into text, feed them into into the chat model, see what happens and and at some point, you know, you do it it was still early. You still have to learn some things.
So, a bit of WPF. [snorts] I didn't want to spend all my usage into moving something to pixels. So, small stuff like that it's it's it's about seeing what the model can do and figuring out, okay, in order to make this work for me now, what's the minimum I have to learn? So, there's still a bit of something, right? >> Mhm.
Okay, I see you. >> And that something keeps changing. For example, I I learned how about like how to do a PR now and how to use GitHub and how to use Git and stuff like that. I mean, there's still some things you need to learn, right? >> Yeah.
Yeah, I think there's still foundation that it's all built on. >> Yeah. >> Cuz I think what I realized, and it it can be applied to any topic outside programming as well. When you know something well, cuz all of us has has some hobbies. We are we are really good at that.
When we start chatting with AI, it kind of gives you the answers, but it kind of it starts to drift apart or mention a few things which are kind of works, but people who actually do it, they know like, well, that's not really how we do that. >> Yeah. >> And I think that's why foundation still matters, so you can at least like, hold on. What Why No, we're not going in that way. Just do it straight.
And they're like, oh yes, you're right. And I think there's still this element. >> I think it's super I mean having the coding mental model, the programming mental model is still super relevant. Just memorizing the exact syntax probably not so relevant anymore, I would say. >> Yeah.
I mean, it's still it's good. >> obviously So, sorry for interrupting. Obviously, I mean, it depends what you're doing, right? If you're an educator, if you work at Autodesk, if you have a startup that has a Revit plugin, you need to know these things. But as a day-to-day architect who just wants to use coding to to for personal tools or for a small-scale company where you have 15 Revit license, it's yeah, I don't think it's it's it's it's that important anymore.
Yeah. >> Mhm. I think I have a bit different opinion. It's good way to start cuz now you can start real quick. You can begin creating loads of plugins, web apps.
There It's It's crazy where AI has come to. But I think at certain points, you especially when complexity catches up and you like stop doing like simple tools, you want to like huge AI multi-window and stuff like that. I think there you still have to kind of stay in control. And that's where you still kind of That's usually so it's reversed. Before you spend months learning the boring basics, you're printing like class of the dog then animal do all this boring stuff and then you slowly start doing something useful.
Now we start building something useful right away and then we like in reverse look, okay, how does it actually work? Not everybody but I think that's also their main part. >> Do you have an example of this of this complexity where where it got too complex? >> It's often due to the size of the project. For the private tools, luckily it's often short but once you're going to create um VBA form where you create a lot of events, styling, like there are like multiple tabs you want to go through.
There is like interaction for example, I was looking into like dragging interactions. >> Yeah. >> And at first it worked while I try to I code something else, it breaks the other thing. So it's all about this complexity. And what I found like if kind of if I start kind of manually and give it the base and then kind of ask AI to do on top of that then it kind of has the structure and it's great.
But often times when I started just with AI, sometimes it does it great great structure from the start and it's easy to go through but sometimes it just kind of I don't know, it keeps changing what it did initially. And that's where like it it changes this module but that part of like maybe UI or maybe your logic how it works, it kind of it did not match. Cuz what I like I like the comparison. I think I saw it somewhere on internet maybe I just made it but AI is like the smartest kid alive but at the same time the dumbest one. So you have to also kind of remember yes, it's it knows everything but if you doesn't direct it well, it can also kind of start doing weird things.
>> Yeah. I what I like to do I I'm I'm deep into into the cloud ecosystem. And I think like what's called now harness engineering, right? So whatever whatever you build the things that guide the model, let's let's say like that, right? The doubt cloud folder in this case.
>> Mhm. >> That's probably starting to become starting to become quite important, right? So and also getting the feel of the model, right? Cuz if you go talk to Opus 5 and if you go talk to Opus 4.5, it's feels differently. I think it's important, I mean, you have people who who who use it in the IDE, right?
And they have access to all the models. I try to pick one. I'm using all of them, but I try to focus on one and get the feel, okay, what is what is the baked in intelligence in this model, right? >> Mhm. >> Cuz 4.5 and 5 have different data sets.
A lot a lot of what it can it can't do is it's baked in inside itself and it behaves slightly different, right? So if you combine that with with with the proper rules and skills and guides, then you really get the most out of it as opposed to if you just keep switching to a million ones in use, maybe it's like a generic agent that I'm building or something. So probably the best way to kind of learn how harness works is to focus on one ecosystem to dive deep into one ecosystem rather than than switching through all of them, yeah. >> In this case, you probably refer to cloud code mainly. >> Yeah, yeah, yeah.
>> When you talk about harness engineering, do you mean specifically like cloud code and setting up all these rules and skills, commands, kind of hooks inside of cloud folder, or do you actually mean like >> [clears throat] >> like creating your own kind of >> Yeah, it's it's it's it's it's an over overstatement to say harness engineering. Yeah, it's it's it's the dot cloud folder, basically. >> Okay, got it. >> And in par- in parallel, I'm also we set up a Hermes agent. >> Mhm.
>> Just to see some The difference between Hermes agent and and cloud code would be that it kind of just get task to simplify just get task and it builds it does the task, sees the patterns, and it builds skills for itself to recreate that pattern. >> Mhm. >> Right? Uh also on the list is to try Pi agent, which is probably the most vanilla harness harness you can have. So, that's that's a really good learning project to kind of start from scratch.
>> Yeah. >> Uh Yeah, so calling the dot cloud folder harness engineering, I think that is a bit of an overstatement, but yeah. >> No, no, that's fine. I just wanted to get it clear. Also, maybe we just take a little bit step back for people because not everyone really Everybody hears about this kind of AI harness, AI models.
They don't all They always confuse the two. >> Yeah. >> Would you like to comment on that, give your kind of opinion on like how to separate what is a harness? I can also add to that, but I just wonder maybe you start. >> Right.
The model comes from Anthropic, and you can talk to the model through an API. Through an API call, you can embed a model call in your Revit tool, for example, if you if >> [snorts] >> if you want to place views on sheets, right? That's not the most deterministic thing to to to automate. Here, you can you can just grab all your views, grab selected sheets, and send it send the names to to cloud model, and you get back a structured response and based on that that's how you how you uh how you placed the views on sheets. Um So, the model by itself is quite good but not that useful.
Like whatever is built on top of it, the ability to add skills, the ability to connect an MCP, the all the baking tools that come that come with the model that is all the hardness and that is pure deterministic coding basically around API calls to Anthropic in this case. Yeah. >> Yeah, I'm also going to give a very simple analogy. Like think of LLM models as a brain, but harness is the hands that actually kind of do something. Yeah, like Alex mentioned, that's where all the skills and everything how it's implemented.
And also the how the context managed. As simple as the context. Something has to happen when you going to fill it up, right? There's already rules, okay, we'll come back and stuff like that. So, this is the work of the harness.
And also I think big one thing I nearly also missed that. Harness can also get access to your computer cuz model is just online somewhere, but harness is what actually brings, for example, cloud code on your computer why it sees the files and stuff like that. They're just again, it's just tools. >> Yeah. >> So, I just wanted to make sure that I don't know some people already really far ahead with AI, but some people still kind of just getting started.
Cuz we already start kind of throwing in like Hermes agent, Pi and stuff like that. >> yeah, yes. >> And I don't know guys. I'm going to ask in the chat, would you like us to even talk about like different agents? Should we focus specifically on cloud?
Cuz there is like dif- I think we can >> We just we just set it up. We just set up finishing up Hermes and the plan is to start Pi as well. We haven't used it that much, so there's not many insights I have there. >> But that's okay. But for the Pi, do you Is there like actual Pi agent or there's like Pi just harness like Cloud Code?
>> It's a harness on GitHub you can download. It's completely open source. Yeah. >> Okay. So, with the Pi, I looked at this one as well and it's pretty much imagine Cloud Code with nothing where you add all the modules.
And >> It's like for people who love DIY. And I look at it on one hand I'm like, "Oh, this is awesome. Maybe I should try." On the other one, do I really want it like I decided not to go there. But, I see there's like a lot of people like interested and they kind of like to customize it and I think it's a great for people who like to kind of customize all the things. If somebody like watching us wants to kind of try it out, that's pretty much it.
You you will be responsible for all the functionality. >> As as an architect who wants to just have AI help himself >> Oh, yeah. >> Setting up a Pi agent for you would probably be too much work. But, just playing with it just for for learning experience, I probably that's that's where it is. Yes.
>> That's what I heard as well. Everybody who starts with Pi, even if they delete it afterwards or they keep it, they they just learn what is a harness, how it works, and like then they when they switch back to Cloud Code they're like, "Oh, now I get it. Like this is like something something's happening behind." >> Yeah, I was also trying maybe on this topic I was I was trying to set up Open Claw when few months ago when it came. And by the time I finished setting up and understanding how to use it, Cloud Code already caught up with all the features that made Open Claw good. So, it's a bit of a Yeah, it's a bit of a realizing the the the speed this thing have.
So, you have to be a bit calculated what you spend your time on and yeah. >> Yeah. Yeah. I think uh now it's so hard than ever to keep focus. Cuz once you just I just choose one little thing and then there're like 10 more pop up the next week and then I'm like I did I make the right choice then I start researching and like now I just like okay whatever happens I'm going to stay with Claude code for at least like I don't know as long as it works for me I'm going to keep it or until they ban me for some reason cuz >> [laughter] >> that's also a thing and >> I think that's the way yeah >> yeah and then I just but one thing I kind of going much deeper into AI but still I want to mention that one thing I can recommend to people right away is that you need to plan for if how to say it you need to plan in case for example you get banned from Anthropic cuz I see people they build the whole business around Claude code they wake up one day they didn't do anything wrong they just banned there is no like easy support ticket to resolve it it's like pretty much if you banned probably you're going to stay banned for a long time and what I noticed what I realized at least for me that I need to be a little bit not only model agnostic well model I don't really care as much they all really good now but I also need to be a little bit harness agnostic the way I found the ways just to kind of create my own memory then also find a way how to kind of um credentials this is easy I can like always set it up from the start but memory is the one that I really really wouldn't want to lose at least I found this really useful because now I set up the memory connected my Claude code and if I want to go to Codex I have exactly the same memory connected I use Honcho but there are many options >> yeah I think uh like ecosystem locking or or like model or vendor locking is something we really want to avoid so everything we decide to spend time on >> Mhm.
>> should we should be able to take it out right and the the dot Claude folder all the skills you build all the MCPs you build are compatible or easily be adjustable to work with other models so it's it's I mean the skill and the format is is a it's a standard now right the MCP is also an open open standard standard yeah so it's it's even even if you decide to go with one with the open AI or Google or or even all all the stuff you can get it out eventually, right? You can download all your chats. You can download the memory. >> Mhm. Yeah, yeah.
No, that's a good way forward. Anyway, I think we going to go a little bit backtrack cuz now I think we going to deeper deeper deeper where it's a bit it's getting harder to follow, but okay, so mentioned I want to get back to like how you in Free Axon actually started implementing it at scale cuz at first I would assume it was maybe you or a few other power users using AI. >> It still is. It still is. It's we haven't rolled it out yet.
It was a small pilot project. I mean the the we had an AI group. We have an AI group to we that started 2 years ago and it did amazing work. We we implemented uh OmniChat, which was an an AI aggregator, so you had access you had like a chat kind of chat interface. You had you had access to all the models.
And you can chat with it and uh at the beginning of the beginning of the year we just started realizing, "Hey, you can do actually a lot of of this non-coding work using agents." And then okay, let's start with five people and now we are at 25 people, I would say. So, it's still far from from from from scaling up. But the proof of concept, I think, is done. >> Okay, so that's viable solution to go forward, introduce agents, and >> Yeah. Yeah, it's it's worth it now, basically, yeah.
>> Mhm. I started hearing literally in like last month or two I started hearing from a few people in personal chats that their company is starting to also roll out similar things. So, I think like 2026 finally it's catching up to companies, okay, there is no way out of it, but also most people just don't know what is going on. Probably, like such a topic. On one hand, it's simple.
You just talk to AI, but on the other one, there are so many things kind of hidden. >> Yeah. Yeah. It's You know, there's it's under-hyped and over-hyped at the same time. >> Mhm.
>> In a way. And probably the only way to to know that, the only way cuz if you go on on if you go on on LinkedIn, like your job is done. Everything can be automated, right? And if you never use it, you think it can do anything, right? So, I the best thing to do is to just try it out on your use case, on your company, on on the work you do and see, okay, are we there yet?
Can can can it do it? What can you do? And that will inform you what you need to change, what needs to be implemented, what is just an API call, what is just a UI wrapper, stuff like that. Yeah. >> I 100% agree with that one.
Cuz I was very skeptical of AI. Not really skeptical, but I had a real kind of internal battle. Do I kind of jump into that? Do I kind of stay more in control? Do I teach it?
Do I not? Now, it's obvious. I'm like, okay, I'm going to go all in and try to get as much out of it as possible. And different people learn different. For me, I just need to break it, figure out how it works.
And what I decided to do, uh I just took like this close to $100 a month subscription. And my goal was, okay, I need to figure out how to max out. I want to like use every token. Apparently, it's not easy. Very On $20 a month, it's easy.
Like, you start talking, it's gone. But then 200, what people don't realize, you get about like 8,000 worth of tokens, like in dollars. Cuz it's very highly subsidized. And now, they even like offering some discounts, so it's like 15,000, I guess, or something. So, there's like a lot of tokens.
And once you start talking, like there's no way you can just open one project and kind of talk back and forward to max it out. Because at first I see everybody complaining on like $20 a month plan, I thought it's going to be quite similar if it's going to be longer session. Now like I didn't hit it. I start working like two product, three product in parallel. I'm like, okay.
I started using sub agent. Sometimes like it goes crazy. I'd like burn through all the tokens. I'm like, okay, I guess I should be a little bit more careful. But this actually also showed me a lot about the models, what they do, how they work.
So I think like for people who like to try stuff, this is really great way. Like I mentioned, just try and build some stuff. It doesn't need to be useful. It doesn't always need to be useful, I would say. In terms of it won't always come up come out perfect.
Because I build like 40 different projects and some of them used by 1,000 people. Like for example, RVT dogs. Lately it was heavily built with AI. I just kind of fixed bunch of things here and there, but it's heavily AI built. And then there are other projects that I built.
I looked at it. I'm like, well, it doesn't really work. I need to restart or something. I just I I just ignore it. So this really helped me a lot.
Just you don't have to really kind of focus on one thing only. And if it doesn't work, it's it's not useful. No. It definitely can be useful in many ways. >> And maybe a bit on the on the subscriptions, right?
A $20 subscription won't really show you what's possible because Yeah, when it gets interesting is when you don't focus that much on like optimizing talking use and and stuff like that. It's just like, okay, let's put the the the put throw the bazooka at it, you know? Put the highest model and let it go. Close the loop. Let it self-verify and see what happens, you know?
Have a safe environment where you can test this and just try a lot of things. And yeah, I I personally use a $100 subscription. I have a ChatGPT one and and a codex one. And yeah, it's it's getting harder and harder harder to max it. I chose to try to max it every every time.
But I think on $20 won't really show you exactly what's possible. You're just going to run out. It's just going to be annoying, right? Uh but also this other other thing now cuz what if these subscriptions all of a sudden go away and then all of a sudden you you're you develop all your workflows around a $100 subscription and that $100 subscription becomes $8,000 a month. That's that's that's a bit scary, right?
But now like for example, Kimi Cat 3 came out and I heard I haven't tested it but I heard really good things on it. So now I'm a bit more relaxed. It's like, "Okay, it's not that hard to to set up a virtual GPU and put it there. Maybe it's way harder to scale it to 200 people, but at least it's it's a checkpoint. Okay, at least we know we have Opus 4.5.
We can host it ourselves. So we're at least there. Maybe not Fable, maybe not yeah. So >> I'm fully committed. Actually says like it's on par with Fable GPT 5 3 Opus.
>> Opus 5 I would say, yeah. Yeah, Opus 5. >> so many metrics as well. And some models they optimized for the metrics. There was like I think Opus 4.7 or 8.
They definitely fine-tuned it because it just started on certain it just like it went way ahead in the scores even though the model wasn't that more impressive. It's still impressive, but it's not that far. So they started kind of hacking the benchmarks as well. >> I know. Yeah, I mean you can Yeah, you can see with the with the ChatGPT model.
They they all of the all of them they're training on benchmarks I think, right? If you see the ChatGPT model that break out and went on Hugging Face to to tweet the >> Yeah, so for people who don't know, they were testing GPT 5 6 and they reduced some kind of guardrails and it decided instead of making the task, why don't I hack a place where the answer might be? So that's kind of the whole story in short. But that's also marketing as hell. I think >> I also think so.
Yeah. >> I think it's 50/50. Maybe it did something like that. Maybe it's on purpose and marketing because Hugging Face got a like now full support from OpenAI, so they benefit anyway. After Anthropic and like and Fable, it's too dangerous to release to the world and stuff like that.
And they're like, "Here." I don't know. We have to be careful about all this AI news. >> That's why it's important you test it yourself and you get the feel of how the models behave. That's why it's like I feel like five coding is such a fitting description. You really need to get a feel.
And it's also >> Yeah. >> I didn't never believe in prompt engineering. You know, it's it's just like using the model to develop intuition to talk with it. >> Mhm. >> There's no rules to prompts.
Like you speak English. You just be clear. As Yeah, okay. There's tricks where you say you can't don't have fingers if the model gets lazy, but that's that's not valid anymore. >> Mhm.
Yeah. I mean, the more I use it, the more I know where it's going to go. >> Yeah. >> in the wrong direction. Sometimes I I I try to be lazy often as well just to see is it going to do it?
I ask it some often times it does it well, but also because it remembers how what we do and stuff like that. But, from the fresh chat, sometimes you need to be a bit slower to get started kind of cuz it also learns about you. >> Yeah. >> And when you look into these memories that it collects on you, it actually gets so scary. Cuz I set up my own memory and it chat it doesn't just save your chats.
It thinks about it. It dreams. It makes conclusions. It's like, "Oh, Erik likes UI design in this way. Oh, Erik is over like analytical and over um paranoid about this part." And I'm like I'm reading that.
I'm like, "Oh." Cuz I didn't write that I'm that. I'm just talking to it and it's like, "Okay, Erik is this. Erik is this." And it just builds it up. >> Yeah, I'm not I'm not happy with any memory system I've seen. I also not like with the like memory from from fraud app projects or ChatGPT projects.
I don't think it memorizes the things that I care about. >> Mhm. >> It's just it's it's Yeah. [clears throat] So, what I what I try to do, I try to have notes and logs. Just put set up a hook.
If we're doing a private tool, save notes of what worked. And then I have those notes and at some point I'm going to take all those notes and I'm going to build some sort of memory on top of it, yeah. >> But for the memory, do you now talk about like built-in this kind of cloud and ChatGPT? Or is it like externally like Mem Zero, Mem Palace, Honcho? >> Well, there's the open-source projects, right?
And then there there are there's also the baked-in app >> Yeah. >> chat memory and also cloud called slash memory, right? So, it's it's None of them are okay for for me at the moment. >> Okay. >> They're not Yeah, they don't memorize how I want things to be memorized, yes.
>> Mhm. Uh I can share like I can share about Honcho memory. I think it might be useful for people as well. So, I also went down this kind of memory stuff and they're like I think they're like I'll just put two categories to simplify. They're like basic ones that just remember what you did and they like just keep the kind of log pretty much what you do manually but do it for you.
There's a few extra kind of to make it more readable, but then there are other memories which are more interesting. These are which start to also do something with your data. They kind of dream, they try to organize it. There's like There are a few cool projects. I specifically went for the Honcho.
And that one is it gathers all your information but also I'm sorry. It tries to build connections. It build a peer card. For example, Erik comes a lot Erik comes out a lot in conversations, so it's going to build a peer card about me what what what I do, different facts and stuff like that and certain conclusions, stuff like that. And when you talk to ChatGPT, what it gets, it gets your prompt obviously all your rules and stuff like that and it also kind of gets its internal memory but also it gets my hunch memory and sometimes I don't always see what exactly is provided but sometimes I see it kind of it's more aware of what I do across everything.
I think I don't think there's perfect memory I don't think it will ever be they always change too much but I think at least trying something probably is worth giving it a try as well. >> Yeah. What's the difference between cuz you you tried have you have you You first probably have car party LLM Wiki. >> I'm building it now. >> You're building yeah I saw I saw that so what's the difference between graphing such a Wiki and this memory system for example?
Is there a difference or is more or less similar? >> Yeah there's difference for sure. So first of all memory it's literally a capturing everything you talk about every kind of your prompt every response you get I literally have all the chats saved and it kind of learns from its own memory is saving it somewhere. >> But it's still graphing it's still graphing it in a way right? >> In a way it's not trying to cross I don't know exactly internals but it's not trying to cross reference everything to source and stuff it just kind of learns about you like little facts here and there it's not as in depth probably.
Probably there is some similarity now that I think about it. But LLM Wiki first of all the main idea is that you bring your own sources so you curate information it's not like okay go to internet and grab me everything related to API pirate related it's going to be a mess. Because all of the system they have flaws and for LLM Wiki the flow is if in your sources a bad information comes in and bakes in as a Wiki now it's a fact. And you still can kind of there are tools to kind of clean it up and it's supposed to do that but often times it will miss it because it needs some sources. So in LLM Wiki what I found is like you are in control and you also decide how much you are in control.
Some people just go crazy. They Here's like 1,000 notes, do something. And Karpathy tells himself that well, what he likes to do, he pretty much adds like one or a few files at a time and then kind of gives his judgment. So, AI parses it. He's like, here's what I learned.
And he's like, no, yes, no, yes. So, you still need the judgment layer. That's what I like about LLM Wiki. You can stay in control, but you choose how much control you want. >> [clears throat] >> And for me personally, I decided to go a little bit I think I went too much because I spent so much time trying just to figure out how to control it and I decided to change how I do it and it was like a big change to everything.
So, I I added a lot of verification layers. So, I add all the content. I say, okay, go and check my course and get information out of it. Then it kind of reads it and then I have to go and verify pretty much all the concept it builds about it. It's a lot of work extra, but for me it's kind of worth it because I want to make it once really good and then later I'm going to loosen it because once it has the base and it's rooted everything on the real content, this is what kind of suppresses hallucinations because hallucination happens when there's like so much data, it sometimes kind of makes stuff up because it Sometimes it can be either just a wrong block.
Sometimes it just kind of makes stuff up because it thinks that's what's next. It forgot to reference source. In LLM Wiki, it's still kind of everything goes to the sources. At least that's what I my conclusion so far. So far, I had good results in terms of I just kind of gave it a bunch of data.
Had a look for example, I didn't go through everything. There's a lot, but for example, selection concept, it nailed it. It went through. I still need to give some judgment here and there. I'm like, kick this one out, kick this one in.
And yeah, if you take it slow, it's going to be really powerful. I'm still to test, so everything I'm just take everything with a kind of grain of salt. It might work well. Sometimes maybe I'm over constraining it. That's also something to keep in mind.
>> Yeah, I assume it we start talking a bit about what would the company memory or knowledge look like, right? Because you have you have the company data, right? That is just files you place there, right? And then you have all the knowledge, the wisdom, like what does that even mean? >> Mhm.
>> And uh so we start starting to explore a bit that and I think just a as as a first step is just to be able to capture all that information that doesn't exist, right? So you finish a project, you end up with drawings, you end up with a design book. You might have minutes, you might have but a lot of stuff, a lot of like, okay, we forgot to do that because of that is not really captured, right? So like clean solution like temporary solution would be just to have a {slash} uh project command that where you can type whatever and then it sends out to a router, it knows who you are, it kind of infers what project you work on and it just saves that information there. And then the next step would be once we have some information there, then we'll probably look a bit into a memory system, a bit into a probably Microsoft or or someone will come with something that works that you can then run on on the data.
But I feel like capturing it is probably step number one. >> Yeah. >> Yeah, yeah, yeah. Also cleaning up is a big thing because well, garbage in, garbage out in the same way if good things go in, good things come out. >> But that's the thing is if you if you do the capturing intentional, yes, it's a bit of work, but then you're sure it's mainly high signal stuff that's there.
So you already can start in two, three months have a little sample set you can test different memory systems on. Yeah. >> Yeah, also all the systems they're going to grow. So the first thing as you capture data, there's just going to be new system, there's going to be new plugin open source project like, "Hey, plug your data, something will happen." So, this there are more projects coming, and the question is like if it's really that useful. Yes.
I know that Pinecone, which is the leader of rag, they just recently made a blog rag is dead, but that was also promotional because they said, "Well, we solved it. This is the next thing." And they built on top of LLM Wiki, so they have they're cooking something like between rag and LLM Wiki, I think. >> Yeah, it's a Google also released this OKF open knowledge format. So, now it became it went from a tweet to a standard. It's it's a bit funny in 1 month.
>> Oh, it's Andrej Karpathy tweet, the man who made wipe coding also a tweet. >> Yeah. >> The term itself. >> Yeah, if if you want to keep up with AI, he's one person you should follow, basically. Yeah.
>> Yeah, yeah, startups there's he has way too much stuff because there's like 3-hour long sessions. I'm like, "Oh my god, why it's not 15-minute video I could watch now?" >> [laughter] >> Anyway, um yeah, I think we're just kind of drifting a bit. So, maybe we'll get back to wipe coding for pyRevit with cloud code. So, can you just introduce us to cloud code? Or maybe talk how did you get introduced to cloud code?
>> It was So, I was using I was using ChatGPT for big portion of time. >> Mhm. >> Then, at some point indexing came with folders. So, I'm starting to gather data a lot. A lot of my initial tests I did ask for permission, but were on your toolbar and on the pyRevit tool toolbar.
So, I was just like getting the library, trying to extract useful definitions, and trying to do some sort of database. So, that took me quite far. Um Yes, and then I think in the beginning of last year, I was trying cursor and they start introducing agents and and all these like rules and stuff. So, we we we just start populating just like, okay, let's let's try it on the toolbar. Um and in in September, I think there was this Google principal who posted on Twitter that we managed to automate 6 months of work with using Cloud Code and then and then I just installed it.
And I went on Lucid Icons. I downloaded all the alignment tools. So, I just wrote align. So, you have, you know, in a design software, you have all the alignment, align equally, align to left, align to right. So, describe all the tools and one-shot this Fire It toolbar.
>> Mhm. And what was what was the goal of the toolbar? Just the structure or actual working tools? >> Working tools. >> Okay.
>> And it didn't work. And then I was, okay. How how can I make What What What do I need to put here to work? Okay? And then I went on I went to the Fire It website and I I I downloaded the structure of the folders.
How you have a panel, you have an extension, you have like that. So, I made kind of a little helper skill from that. And I tried again and it didn't work. And I just keep doing that until I got to a minimum amount of things I need to put in there to kind of one-shot this toolbar >> Mhm. >> uh just from one prompt and the skills attached.
>> Can you describe approximately what was the toolbar? I mean, what was supposed to be inside? Just roughly. >> It's uh it's uh it's all the alignment options. Uh Do you know the plugin Beam 42 Align?
>> It's all aligning elements to left, right, distribute. >> Exactly. Yes. So, all the possible options that work on annotations, but also a 3D, also annotations and 3D combined. >> Mhm, got it.
>> Yes. >> Okay, so okay. >> And I got it to work with two skills, I believe. Some element hierarchy skill and the how how Revit is is aligned, plus a dump of all the icons. And the prompt was describe all the icons, uh try and one-shot a Revit toolbar.
Arrange panels logically so they display intuitively in the UI. And deal where you have to do some translations between 2D and 3D elements. >> Mhm. >> And it cooked for 15 minutes and I got a toolbar. And since since then I was like, okay.
This this is super useful now. This can be scaled. Uh I need to look a bit into into into the skills. And since then I started using Cloud Code and yeah. >> Mhm.
Okay, so you got your first win and you like, okay, that's actually something that can bring value and you focused all in on it. >> Yes. >> And at the time, what was the model? Do you remember? Was it already Opus something or >> It was just Opus 4.5 came out.
>> 4.5. Okay, the 4.6 was a big one. Where it really kind of got much That's where everybody started to realize like, oh, Cloud Code and Opus actually actually can be really useful. >> Yes. >> I see.
And from that point on, you just kind of focused, okay, you started building tools or skills? What do you kind of focus more? >> I'm just trying to understand, okay, what's what front matter do I need to to to have? What's like the minimum amount of knowledge I I need to know in order to make this work and keep testing. And again, like you, I have 40 projects.
And I get stuck with a lot of them and then new model comes out and then I continue on that project. >> Mhm. >> And I realize also with skills and MCP, there is is a fine is a balance cuz if you clutter it with skills and MCPs, it won't work. So, what is the minimum amount of stuff you need in for the model to do its its work. So, for example, for our active toolbar at some point I say this is this I'm drifting a bit apart.
Uh we keep breaking our tools. So, we decided, "Okay, we're not going to have a library anymore." So, each tool is going to be self-contained. >> Uh so, not reusable code anymore. >> Yes. So, each tool is self-contained and um >> Mhm.
>> So, so the toolbar so has it has no dependency. So, you can iterate on one tool and you can just deploy it and if it has an error, it doesn't not much happens. >> Okay. So, if something breaks, it's only one tool. >> Yes.
>> Ideally. >> [laughter] >> Exactly. Yeah. I mean, that started to use a lot of tokens, become a bit inefficient and uh then we say, "Okay, we're going to I need to make back back to library, right?" So, now we have a little skill that just explains how we want the library to be arranged. Right?
Another thing is I can take a lot of time and I'm getting I'm always rabbit pulling in icons. So, I went on Lucid icons. You You know the the the page? >> Mhm. I've been there but I don't remember how it looks.
>> Very simple SVG uh open source library and I just you can download all the icon names. You can describe a bit what they do. And >> Mhm. >> you just make a tiny skill that has the library of of all these icons and you make a rule telling the model, "Okay, when a new tool comes in, figure out what is the appropriate icon to put in, right?" >> Mhm. >> And another rule, how are our tabs arranged?
And there's no there's no there is no no real coding skills in it. There is a hook that logs all the gotchas. >> Oh, that's a good one. >> So, that keeps building. I never cleaned it.
I never actually looked at it. >> Mhm. >> It just works. So, we got to a point now where you just open a bundle creator, someone write codes a simple script that they need, send it over, I dump it there, and I said, "Add tool." And it adds it to the toolbar. It breaks often, but again, we're everyone who uses the toolbar sits 50 m around me, so it's it's not that big of a deal if you get a if your Revit crashes once in a while.
Doesn't happen often, especially with failure, doesn't happen anymore, but yeah, it does happen. Yeah. >> Yeah, I think that's a luxury of small offices. Not small, but more like >> Yeah. >> Uh when everybody who uses your tool is around you, >> Yeah.
>> it can be much but because I heard from some people when it's already multi-offices, even multi-countries, that's really tricky one, but still with Git and everything, it's possible to resolve easily. >> Yes. Uh another skill would be the the use of the WTF design guide. >> Mhm. >> So, stuff looks consistent, so he knows where so model knows where to get stuff from from the library and and stuff like that.
Yeah. Having a map of of of the tools in your cloud that I need file helps a lot. And that's pretty much it. >> Mhm. >> Obviously Sorry.
Obviously, having the MCP connection to Revit, so the model can test the tools, so you close the loop. That That's also helpful. >> And that's also what we're going to dive deeper so in a moment, right? Before that, I also want to touch up on the You told that you're building up the gotchas file. Which is also I also build one as well.
>> Yeah. >> In my case, it kind of went a little bit wild. It built like thousand something lines and I was like, "Woah, woah, woah. Show me all of it. It It This is not This is not good." I started going through and it's such a little picky things here and there, I think.
I think you need to also verify it cuz mine got so big, it definitely will start losing information. >> Yeah. >> And I looked many of them they are they're not even gotchas. They're just like "View has to be unique." I'm like, "Cool." Like mention the solution at least because I looked at it and it's something very stupid. This one is not bad actually.
>> Yeah, that's a good example. That is a good example. >> Yeah. >> Yeah, that that the view has to be unique. You don't need to give it any code and it's one sentence.
Slow tokens. It's quite high signal example. Yeah. >> It's good to include how you want to solve it. Cuz for me, I like to add the stars in the end.
So, if you try to rename floor plan one, it exists. I just add one star or two stars or three stars. So, you know it still renames it because if it doesn't rename, sometimes you lose the view. Cuz like five views move to a new place, one left somewhere and you're like, "Where's my last view?" >> That is actually in our rules as well. We I I like to use a the date year month month day day minute minute second second or hour hour.
As a unique identifier. Yeah. >> Yeah, because the thing about skills, there's so many different ways to build them, but one thing everybody agrees on the smaller the kind of the less information in your skill, the more efficient it is. >> Yes. >> Cuz once it gets longer, I know I also learned that on a large skills, it prioritizes the start and the end.
And the middle, you never know like it it might lose something and stuff like that. So, that's why I am so keen on like trying to clean up, but it can be sometimes hard. Even I read some of the gotchas, and I'm like, "Where did you even get it?" Like, I know it went for my files, but I don't remember working on that thing. >> Yeah, I think you know, if you quickly want to work on something, it's fine. You use the skill creator, you tell it make a skill out of this API, just implement it.
It doesn't matter. But, if you have a skill, like for example, we have three first skills in the private full bar, that's quite important. It's good you do you go and create it yourself, and remove There's a lot of noise. There's a lot of markdown decorators that don't need to be there. There's a lot of Yeah, it's just it tends to to overshoot skills most often.
There is this guy called Matt Pocock. You you heard of him? >> Not sure. Maybe what what's the project? Or what's the name?
>> Uh >> [snorts] >> can I maybe share >> I can just describe. Oh, yeah, yeah, yeah. Actually, people already asking in the chat if it would be nice to share Revit screen. >> [laughter] >> They're they're missing their domain. >> Let me just see if I have it here.
One second. >> I think I came a little too early. >> Okay, how do I share? I share. One second.
>> Also, when you share, make sure it's a screen, not a window. You know, this annoying thing. >> Yes, can you see my Revit screen? Yes. >> Hey, yes.
Maybe let's make it bigger. >> It's this guy, and he has this skill that we're using. It's called the writing great skills. That's probably the best explanation that I've seen how to write this clear a good skill. This is what I've been using.
I mean actually all his skills are really good. Especially this one is also has a glossary, right? And it tells it it just tells you This is this can be a skill for yourself, right? It is it tells you very >> Oh, Alex, we see your Revit screen. I was thinking that you were still opening something.
>> Oh. >> I think you selected the Revit Revit window. So when you share screen just make sure it's the screen. There's on top like there should be some kind of selection between applications, screens. >> You just you just told me that and I did it wrong, okay.
>> Once I I can see it. I see Revit. >> Yes. >> Yeah, now okay. >> Yes.
>> I was confused. I thought maybe I missed something. I thought I was waiting for you to like pull it up and then I realized. Sorry. >> This guy this this guy has a great skill, right?
It goes through all the stuff that you need to know, right? User invocation, model invocation. User invocation if that's the skill up here where when you type {slash} can you see it, right? And and model invocation is does the model see it and can the model invoke it by itself, right? And it goes through all the concepts of skill and it has an amazing glossary.
>> Is this something internal or it's also open source by somebody? >> This is this guy. It's Matt. This it's just a influencer. It's a coding influencer online.
>> Okay. >> And the skill is I mean it is in our repo but it's it's still Yeah, I can't remember where to find it. It's probably somewhere in this four repos. >> Mhm. >> Right?
And it has it has the glossary. It's really good. One important thing that I see a lot of people missing their skill is is the last point he has here which they don't consider model baked in intelligence quite often. They tell to model to the model and the model gets updated. We need to also need to understand that all the skills that we make and we put online will be in the next model.
So it's so skills are something hot that constantly needs to be curated and removed and tested. Because you want to use the baked-in intelligence and just like keep it keep exactly the the the the high signal guide. >> About that, there's recently the creator of Cloud Code, Boris. He literally I think that week or last week he went out to some presentation and his kind of the main point was like well every 6 months you should delete all your skills and just test what model can do by itself. Cuz many people still have the skills from like a year ago or 2 year ago and that's exactly what you mentioned with this last point that there's a lot of things we include in skills that model just knows.
You don't need to describe how to create a folder in Windows, it knows it. You know, it's a oversimplification but you get the point. And as you mentioned also that everything feeds back to kind of Anthropic, that's why we're getting these crazy subsidized tokens and stuff because they need our data more than money at the moment cuz all the skills, everything that there are like people who create crazy kind of workflows and stuff. Anthropic sees all of that cuz Cloud kind of gets it in and out and it kind of learns I'm like oh that's a cool one. I think that's also something that's a really good point that you mentioned.
>> Yeah. I don't see actually I don't see anyone online selling skills which is very interesting. >> I recently saw that there's starts the boom of selling the skills but I think it's very very very niche. I don't even know how they sell because in the end of the day you're trying to sell a text file. On one hand I get completely get it like if you going to sell like it's very niche application for sure.
>> My advice never buy skill. It's uh Yeah, so an analogy used before with the harness, right? A good analogy I like to give people is as a kitchen, right? So, you have the kitchen, you have the chef, you have an oven, and you have a let's say pasta bolognese recipe, right? Like the kitchen would be the harness, the chef would be the model, the oven would be the MCP, and the recipe would be the skill, right?
You can find online >> It's so good. >> ton of bolognese pasta recipes, but you'll never find the bolognese pasta that your mother makes for you, you know? So, that's that's the skill. That's how you need to think about the skills. You'll find, I don't know, accounting skill a lot, but you'll never find a skill that that tells the model how you do accounting at your company, right?
So, that's what you need to put in your skills. Yeah. >> Oh, that's such a good analogy. Did you make it or >> Uh I'm I'm not sure. I don't want to give to take credit for it.
I'm not sure. I've been saying it for so long that I'm not sure if I've seen it somewhere or if I invented it myself, yeah. >> No, that's a such a good one. That's actually covered. Usually this analogy is that I I at least when I try to make when I forget about MCPs to mention but this oven stuff.
That's a good one. >> Yeah. >> Now, we're going to attribute it to you until we find somebody earlier. [laughter] Anyway, uh so, would you like now to just dive a bit in the cloud code to show how to uh how to kind of go deeper? I can't remember.
I think we wanted to do a quick demo as well, right? >> Quick demo. We can we can we can we can share my screen and and share something. Let me just see what I have here. I am on my personal laptop, so >> Yeah.
>> performance is not great. >> Yeah, we'll account for that. Cuz right now I think our conversation is a bit for people who already aware about a lot of AI stuff. We didn't really exactly went for the beginners topic. So, maybe once they see how to actually kind of how this cloud code works in general.
Something that I think I'm going to cover in the channel anyway soon. >> I will think. Let me just think a bit. What do I have here? >> [clears throat] >> Also, for people watching us, just a question so far, are you following along the conversation?
Is it like do you find it actually useful? Is it too complicated or is it too easy for you? Just let me know in the chat. Meanwhile, Alex already has it. >> Yes.
I'm I'm not sure what what to start with. Uh maybe a bit how I like to how I build the tool, right? So, let's I'm just going to pause my doodles here. So, there's there's building stuff and there's [snorts] Oh, sorry. There is building stuff and there's using the model to help you work, right?
So, for building stuff, my current workflow is I just go on ChatGPT and I say research uh this or describe how this tool works, right? And I then I take take that description and I together with ChatGPT I convert it into a specification of how the thing should look and a minimal viable product of what's the minimum amount of features I want from from from the tool, right? And then I just let the model go at it. Build some sort of I make sure the model can self-verify and probably the easiest way to do that is to get her I mean you can go private MCP, right? You can go and call the tools and if your Revit crash you can enable computer use.
It can go and and and uh restart Revit for you. It is very slow though. And I'm also always using uh the latest model available because of the hundred dollar subscription. You you can afford that at the scale of the tools we are building. And then the model goes and and says, "Okay, this is what I built.
I'm going to test it. Did it met all the requires from the MVP? Does it work? No? Okay, try again until it considers to be done." That's I don't you could say that's the most basic uh loop you could have, right?
>> Mhm. So you start with an idea, you turn it into spec of everything. You also build MC kind of MVP kind of plan and then AI. >> Yes. And it's good to ask for the model ask the model for a a spec and then you have to go and modify it yourself.
I never experienced that the model it always tends to overshoot. And um a good a good skill for this would be again car party is called if you go if on Google if you do car party uh cloud MD you would get maybe I have it here. >> Can you explain what do you refer now? What's the cloud MD? >> Yes.
>> close that? I got it. Got it. Got it. But show it for others anyway.
It's a good one. >> Yes. Uh do I have it here? Sorry, give me 1 second. >> I usually always type online Karpathy Claude MD.
It shows up first. >> Yes. I but I transform it in a skill. It's just that we are recording and my computer is very slow. >> If you want, I can show people the main gist of it from my mind.
>> Please. >> I'm wait I'm going to just open. So Uh Just 1 second. Yeah, I'm trying to pin myself. Oh, this app.
Anyway. So I think people can see right now. So there is Yeah, that's the one. You talk about that one, right? >> Yes.
Yes. And I convert that into Can you zoom out a bit? Sorry, I only can see >> Uh there is if I'm going to go to Claude. No, wait. Claude MD.
Here we go. >> Yes, exactly. That one. Yes. And >> I just want to show people to find it just type Andre Karpathy skills.
It's not made by Andre Karpathy, but it's based on his teachings. Uh what you're going to find here, it's a repo with 200,000 kind of stars. So you can see it's really used. And right here, it's very short. It's shorter than I think before code simply simplicity first, surgical changes, gold driven execution, and a little bit more explanation.
So that's the base. And I also highly recommend just to copy paste and implement it somehow in your skills in your projects when you start. If you especially if you use nothing, just use that at least. >> [snorts] >> Yes. I think that that helps and obviously it helps to to modify the bit for your use case.
And that that gives this workflow. It it it stops a model from over shooting, right? So, a few examples of how we do that is um If I go to tricks and tools, we have our >> You need to share your screen again. >> Oops. Or I'm sharing now.
I'm sharing now. >> Okay, now here we go. >> This is not good, Erik. It takes so long to open a printing tool. All right, so this is is it's a simple it's a simple printing tool that we did by describing the roots pro sheets amazing plugin.
By the way, we use it for a very long time. Um It just it had too many features for us, so we just took exactly what we need and we recreated this this tool that kind of mimics the way pro sheets exports IFCs, DWGs, and PDFs where you can compose the name together and all and and that. So, that's that's one example and then again, this was a few prompts and it built this tool for us. So, yeah, that's one example. The next example would be uh something maybe we can try it through Should we try it now or what what What do you think is better?
It's better to show an example where we drive Revit or where we just build the >> I can do it by side by side. There will be kind of waiting times anyway. >> Yeah, I will I have might have a descriptions here. >> Yeah, also sorry everybody. We have a few technical issues here and there because I decided to figure out on the go with Riverside and apparently it's more limited than I thought.
But I hope it's still useful to you. And so far I think Alex sharing quite a lot of good insights here and there. But I also understand that maybe we skipped a few basics here and there. Okay, so we see your VP of UI Revit. >> Yes, so anyone can try this, right?
You open Cloud Code inside a fresh toolbar, take a screenshot of Autodesk family editor, pointed where it is and say, "Hey, can you describe this tool in Revit?" See print screen and it goes and gives you description of the tool. Okay, and then let's Sorry. >> So kind of reverse engineer the tool first. >> So you still use ChatGPT but you code with Cloud Code. >> Uh I I have web search disabled on Cloud Code.
So I do the research with ChatGPT and then try to copy the answer and paste it into Cloud Code. It's just it's a precaution. You don't want to combine access to your machine with a web search. It's there's uh potential for prompt injection or >> Mhm. Mhm.
>> Yeah. So, uh then we're going to get the spec. I mean, it's going to take some time, right? So, I will I will let you know when it's done. I'm going to take the spec.
I'm going to open uh our I'm going to open the pipe the uh Pyre V toolbar, and I'm just going to try to just dump the spec in there and ask it for for a toolbar and then see what happens. Basically, that is the workflow. >> Okay. Uh recently about all these kind of spec building and stuff uh maybe I just need to change the screen or something. Can I I Yeah, thank you.
That's going to help. Now, I need to So, recently there was a cursor they shared. Maybe I need to find it. They shared their report where they they were experimenting with different models and stuff like that. And one of the things they did is they tried to rebuild SQL, I believe.
And the way they did it is just use different models. Uh wait, it's jumping. So, uh they tried Fable 5C. It took like 8,000 something like that to rebuild it. Then they tried, "Okay, use Fable for planning or building specs like you say and then use Opus." It took like this much, this much.
And then like the conclusion was like in the end they got similar results using different models. But what worked the best it looked like using very small model like Fable for the planning. But then using like much cheaper models for actually execution. Cuz once the spec is built and it's good, like like you don't need as much intelligence because like the biggest thinking already done. And then the other models can pick up and like, "Oh, how do I do this, this, this?" And they kind of do it pretty well.
However, if you are like on these cloud subscriptions and you are cannot even max out your tokens, often times you can and me I oftentimes just run with Fable. It auto kind of goes down to Opus anyway sometimes depending on the task. But that's what I noticed. >> Yeah, using Fable 5 with Opus sub-agents seems to work okay. I'm trying also you can you can choose inference level, how much the model thinks.
I feel like medium is good for everything. I don't think I do complex things where I need more than medium on both. >> Okay. >> Yes, it's a balance about, you know, overshooting and then it's too much thinking and how complex is your task. If you add some examples, most of you you'll be able to do most of thing all of the things.
>> Mhm. Yeah, that's the thing like I often just run on like extra high or like even max when I really want to get the most out of it. Mainly because the tokens is not an issue oftentimes. Cuz the way I do it somehow I'm still surprised like that it does it maxes out so rarely. But going to lower ones I always think about like okay, what if this time it will kind of make a mistake and it takes me longer time going back and forth explaining.
Maybe I just give it more juice, it produces something and then I work on that. >> It sometimes produces worse in my in my experience with with high inference. >> Oh, yeah. >> High, extra high, yes. More like ultra and it's it's it's just like it's too much.
>> The thing is that ultra it's actually running on extra high. It just it just unlocks you very sub-agent kind of very heavy sub-agent works. But the max is the one that kind of doubles like a token usage or something like that. And also slower. Yeah, the thing is that I see a lot of people talk about this.
There's this fine um how do I say it? Fine line that you have to decide which model to use when. There are even whole like harnesses that will decide for you. So, you just you just prompt and sometimes it uses this model, sometimes that model. >> But again, that is a bit of a temporary thing.
I think the like we're going to get ChatGPT-6 very soon. Then Gemini 3.5 Pro will come out. It's going to get to the point where models like after when Fable ChatGPT-6 and and Gemini 3.5 Pro becomes the new medium [snorts] model and then tokens are very optimized. Um I don't think it would matter that much what model you choose. I think that again, this is one of these temporary things.
>> Mhm. Mhm. Yeah, it's a tough question. I see your point. I also have been down this rabbit hole.
I was like, how does it I think they're all going to get to the certain intelligence level where it doesn't Honestly, we're already at the point where it doesn't matter. If Fable disappears tomorrow, honestly, I wouldn't care. Like there's Opus 5. Even if like instead of Opus 5, I had Opus 4.6, I would be happy. It can do a lot.
>> Yeah. Yeah, you need to do the the stupid less important the less capable the model, the more the skills and all that matters. The higher the model, you get to a point where all of all of it gets absorbed. So, what is left is basically what you want to build and why are you building it? >> Mhm.
I think there's also like skills, memory, uh context management, all of Not context management, but providing the real context of your projects, what you do this, what will matter the most. >> Yeah. Should we maybe let's try and uh >> Yeah. >> Let's inspect. >> Oops.
Uh I think we we need to share screen again. >> Yeah. One second. >> I noticed I think it will auto do it. >> Is it Is it there showing?
Yeah. >> Yeah, yeah. >> So, you can see it. >> So, this is the spec. >> So.
Purpose. Search category for the thumbnail previous grid and list views, multi-selection, batch loading. That's good. Button definition. >> That's looks okay.
>> Folder structure. >> Mhm. >> Uh >> But anyway, when you look at this folder structure, you still can understand what's going on like here and there. Like you know what I mean? >> There There's Yeah, I mean all this is what you get in in a in a button, right?
>> Yeah. >> Then and then you have the library and uh the resource folder that's is going to be in the in the toolbar root. >> Mhm. >> [clears throat] >> Correct me if I'm wrong, please. >> No, no, that's fine.
>> Yes. Yeah. Uh >> I'm still I'm still trying to understand because you do know some Python, some Revit API, but you mostly kind of write code. So, I'm trying to find like cuz here like okay, that that should make sense because probably you've seen it like 100 times already as well. But probably also recent kind of looked into this.
>> If If you start from scratch, maybe it's not immediately obvious, but I mean, you still need to know the structure of a pyRevit toolbar. There's a library folder where you pull uh repeatable code from. Push button is the folder name of your actual button, then you have extension, uh panels, and all I mean, you still need to know the structure of the toolbar. But again, it's knowing the structure of the toolbar is not coding. It's >> Yeah, yeah, but there's like already separation of different tasks.
That's That's what cuz you can see that there are like five files in library, so it already starts kind of splitting stuff here and there. So, >> I just wonder if you really try to control it or you just let it go and like well, probably it knows better. >> I think first pass, I don't assume it knows better. I think first pass, I literally go and see what happens. >> Okay, so.
>> And then I adjust, right? So, then we have window layout. Okay, we're happy with this. Okay, let's just take let's just take the output. I'm not going to at least view name footer.
Okay, we can take this. And this is It's a bit slow. I apologize to everyone. It's a We can open cloud in this folder. >> That was all.
>> So, curious if you use cloud in the terminal or like chat. >> The reason why I use it So, I I don't I I use mainly I mean, I have VS Code, I have Cursor. I mainly use terminal and Sublime Text. Just because it's it's fast and I only read markdown files. >> Mhm.
>> So, and I like I like using cloud in terminal the same I'm I don't run any any partial commands. I It's It's literally a chat interface. It's just It's way faster. You can customize it. You can see the context toolbar.
You can set the the permission mode. You can quickly disable and uh enable plugins. You have all this flexibility that actually I don't even know where to get it in the in the app. Mhm. So, uh yeah.
I'm not sure what's the difference between the terminal, the vanilla terminal, and the plugin in the IDE. Is there Is there a difference? >> Yes. So, well, first of all, uh in IDE, you're getting kind of terminal version, so you have to install it like a terminal, but in VS Code, for example, I know there are two options. You have it as a chat option, kind of integrated, but also you have like uh terminal option right inside your IDE.
Cuz you you can open terminals, but they also made it part of the plugin. I personally prefer terminal as well. It has a a lot more commands. It has a lot of shortcuts. You can even open For example, we can write prompt now in the uh what is it?
Notepad. We can also extract everything in Notepad with a few clicks. There's like a lot of hidden features. Can you put a question mark in your prompt? What You can also kind of ask it like what it can do.
You put the question mark, you can see there is a lot of information like, "Oh, if you put this, you can execute this this this." You don't need all of it at this in the beginning and probably most of it. But over time, there are a few shortcuts here and there that you can find, which are not available in the chat version. So, for me, I kind of went into that. Yeah, so I was just glad to see that you're using terminal. >> It's Yeah, it's the same reason why in Rhino you would use the the the command bar instead of clicking the icons.
I would love if Revit would have a command bar as well. >> Mhm. >> Okay. So, let's let's just try Let's just try and and just type, "Okay. Uh here is spec." slash Sorry.
Superpowers is a good plugin that comes from on topic partners, I believe. And it's just it helps you convert a plan a spec into a implementation plan. And starts it tries to to to overdo it again and it's an extra step that maybe is not necessary if you have good spec. It will probably take me half an hour to clean a spec so I we're not going to do it live. But we let's just try and do superpowers and say okay here and I normally use wisp wisp wisp flow.
I don't have it enabled on this laptop. >> You can use command voice command in terminal version >> Voice yes, I know it's >> a space >> I'll I'll I'll I'll write this for now. I'll write it for now. Okay. So here is spec where are you?
I'm just going to put this folder. I'm going to give you the path to the folder. >> Mhm. Okay, so you still directed to your skills and stuff. >> Yeah.
Yes. And so you can you can just have bunch of skills chained together. And then I'm just going to copy the spec. I would also normally do ask user use the ask user questions tools for any clarifying questions. That works quite well.
The more time you spend there the like fewer task is. So this is going to run in the background. Okay. >> Okay, I see. >> Maybe meanwhile we can talk a bit about this.
So this is can you see my screen? >> Yeah, yeah. You have Revit MCP. >> Yes, so this is a Revit MCP that I wrote it myself. It's probably not the most efficient.
I'll just maybe show the Oops. >> Is it still by rate extension or is it C# kind of a little bit? >> sharp it's a it's a C# uh >> [snorts] [clears throat] >> Is this cleaner right? Is this a visible? >> Mhm.
The text is a bit hard to read, but if you zoom it's going to be fine. >> Yeah. So it's >> Perfect. >> Yeah, it's a Python MCP server. It's pinned at very like a very early version, so it has almost no dependencies.
And it's it's very simple, right? It has um run Python command and a run sharp sharp command. That's pretty much the the two tools I use the most. >> [snorts] >> And then it has a uh a bunch of built-in verifiers that can can make pre- print screen. It can query elements and stuff like that, right?
Then it has It's basically saves on the drive a tool if you if you ask it to and then you can load it dynamically. >> Mhm. >> So it can list save tools and run save tools. It just points to a folder, right? And then it goes to Yeah.
>> a quick question. By the tool, does it refer to pyRevit tool or MCP tool? >> It's a Python tool that uses the Revit API. >> Okay. >> Or it's it's it's basically it's using the it's using the the run Python tool to run that file from your drive.
>> Mhm. Got it. >> Yeah. >> So I just want to get >> has Yeah, that file has the the tool the the tool script and the description. >> Mhm.
>> Yes. And then it goes Yeah, it goes to the Revit and then the whole idea with this is not to make the most efficient thing. The whole idea is to Okay, we're going to wait for Autodesk to release probably a very stable MCP, right? If I give you the model that doesn't do mistakes and if I give you a connection to the MCP, what are you going to do with it? And it's not immediately obvious what you want to do with such a tool, right?
And that's why Yeah, that's why I built this like this small prototype for myself where I start to talk to the model and see, okay, what can you do? How How can I push this? And uh if I'm going to show >> [sighs] >> I don't think this is going to be possible, but let's try. >> Well, that might be a bit too much for the laptop. >> [laughter] >> This is a project I worked in UK.
>> Well, looking nice. >> Yeah, and There There's a period at the beginning of the year where we had to we we went from stage two to stage three and we had to quickly convert it from um from beam beam geometry to non-Revit geometry, we had to quickly convert it into native Revit geometry to be able to not bottle neck on any of the consultants and have like a native Revit model Revit to ship, right? And we are a bit squeezed on time, so I had like two days to to to uh build this model, basically. And it's This is the first I would say vibe co- co- It's like it's It's not like fully It's I use a lot of AI to help me do this. It's Again, I haven't used it to design.
The The design was already there. I just had to recreate it. But I had to do a lot of >> [snorts] >> I I it would be different than I would normally use it for. So, we I started by building uh, this family. >> Mhm.
>> I started building this family that has all the >> This is like a base or >> Yeah. It has It has all all the facade set out. And the all the facade lines baked in, right? And then I have this drafting view where from previous stage I extracted all the all the cladding profiles that I need. >> Mhm.
>> And then I to get using my MCP I I start asking the model, "Okay, here's this line. Divide the line by this grid. Take this profile, sweep it. Convert this to families. Okay, then once you have the families start rationalizing the family." And it goes and then okay, now that you rationalize the family you find similar family parameters and replace them and start like with this with with with the base of lines and a base of profiles I managed to to recreate most uh, most of the tower, right?
And then I started thinking, "Okay, this is actually quite interesting. How can I like push this further?" Uh, and I start creating a set of LOD 250 families. >> Mhm. And it's mostly like AI driven. So, you create the profiles, lines, and it kind of >> Yeah.
Profile lines and then okay, I need a bank of families. How how is the facade built? In in 60% of the cases you have a unitized facade. A unitized facade comes with a window, a cassette, and then you have cladding on slapped to it, right? So, what if I make this ready-made library of window cassettes and I they're very low LOD, so it's it's fast.
And I baked in some instructions. I I put a parameter and I baked instructions inside the the family is similar how you would use MCP tools. Describing, okay, this is the family, this is how it's driven, and this is what each parameter does. So, combining this kind of low-level LOD library with with the sweeps for the cladding, you can pretty much you can go quite far in recreating a tower like this. And then later on, you can pair the the external family with a unitized final and nested inside.
It works much better than expecting the model to do everything from scratch, right? And then you start with a very low LOD, and then you just swap the families. So, the next step would be to take a low-level LOD family, go inside the family, and talk with the model so you can Okay, now we need to add profiles. You need to sweep the profiles. This is the profile.
Look at the You see some drawings from consultants and and and it seems to work quite well. It does require Opus 5 or Fable to for it for it to be in reasonable time. >> Mhm. >> Yeah, but it does work for sure. Yeah.
>> Does Does it also save some kind of tools or it's more like one-off things like >> that's that's the that's the thing. So, then I Once you're happy with the thing, you can you can go and it saves the tools. And it's it it saves the tool files and I also have a hook that saves the description of the file. Right? So, that starts giving me a catalog of >> [snorts] >> what what what might I need and how how how might I need to use it, right?
Because it's not super intuitive. You have to start building your families a certain way. You have to Yeah, put this description. You have to use a lot more parameters, for example, right? You don't want the model to be stuck in making times.
Maybe you make a lot of instance parameter. It's all driven by instance parameter and the There's a type parameter that is a concatenation of some of of this instance parameter that builds the type name rather than than than the other way around cuz then you can you can classify your families correctly. Does it make sense what I'm saying? Uh >> Yeah, yeah, yeah. There's just quite so many things going on here in terms of like the whole workflow.
It's like certainly so many steps. We're kind of following I hope people watching also can follow along. >> Yeah, so Yeah, to to to simplify it, right? You can use the you can use the pyRevit connector, right? You The pyRevit connector ships with a run Python code inside Revit, which lets the model write its own scripts dynamically.
You can use that function to drive profiles on rails or place families that you built already. So, that's that's kind of kind of where I am. Once you do that a few times with a model, you can ask the model to save notes on how it did it or build tools for itself. For the next time you're going to I it, that workflow becomes more deterministic and the model can just call tools that have variables instead of going through a long loop again. That's Is is is Yeah.
>> Yeah, yeah. I mean like more like also the Revit side, the families, the parameter setup. >> Yes. >> Coding part, it kind of makes sense that pretty much you're just using AI so it kind of figure out its own way and then you just also tell it like, "Okay, don't forget to save it so we can reuse it." >> Exactly. And then if that tool becomes very valuable and that tool can easily can point to to the folder where you save the tools and you just promote them to a private toolbar and that is how we use private now the most is to to to have this this this scaled uh to to to to scale some of the tools, yes.
>> Mhm. Okay, so you're pretty much just going to iterate, explore what's possible and when cool things come out, you just like, "Okay, now it's a tool." >> Exactly, yeah. The thing is that Fable now is so good or obviously a lot of people don't have access to the Fable. Now it's so good that you don't even need to spend time doing that. It's Yeah, it saves tokens.
Obviously, that's good, but how much effort do you put into managing those tools, deploying those tools? You you you need to kind of calculate a bit that, yeah. >> Yeah, Fable has one downside that recently they a little bit downgraded it that when it thinks like maybe it's an upgrade because it often uses Opus 4.8 instead of Fable, especially on the coding tasks because well, they were after Fable got banned, they had to add restrictions and something like that. But it's still a solid model. But now I don't know like there's Opus 5 on benchmarks, same as Fable so they they don't know themself how to promote it.
It's a bit weird. >> Yeah. Do we should should we do Should I do a small scale demo on how that works or >> Yeah, sure. >> Is that is that >> Uh I think we going to end up in 20 minutes. If we can fit in like in 15 minutes, sure.
Because we also creating another tool. >> Yeah, maybe yes. It's it's it's it's going. Uh I'll try I have I really apologize. This my personal laptop is so slow.
I have a folder saved with some video. Maybe I can just pop that quickly. So if if you look at our stack, right? We have uh pyRevit for scaling tools. We have the MCP for letting the model to promote tools uh to to to run code and check itself.
We also have uh we also use a Rhino MCP that um has access to Grasshopper and we do a lot of things using the Revit API on the Grasshopper. I'll I'm a visual person. I like if I do a complex tool, even if it's in pyRevit, I like to first visualize it in in Grasshopper as chunks of custom uh Python nodes placed by the model that then that then the model can read and can promote to a uh pyRevit tool. And uh >> Uh so wait a second on that one. So you pretty much break down the tool in steps visually.
>> Yes. Yes. >> Okay, that's that's a good one. >> Using Grasshopper but using only the CPython node in Grasshopper. >> Mhm.
So you have a full diagram in there. >> Exactly. If you have Rhino inside installed, it can talk to your Revit. It can write Revit API code. You do the logic.
You test it. Also, it's uh we use it as a 3D engine. If you need to to to do some geometry, it's better you send it into Rhino inside. Also, uh right you you have access to Rhino inside engine through pyRevit as well. So, we do have a tool here.
Um Yeah, there's the Rhino exporter. >> Mhm. >> That pushes everything to to Revit uh to Rhino quite quite fast. So, you can choose link models, you can choose uh active view. Uh you can just send it as separate files, you can send them as as um as individual files.
So, we try to look at the whole stack. I try to look at the whole stack rather than pyRevit or using uh cloud code to for pyRevit. It's kind of becomes this homogeneous thing >> Mhm. >> where you just buy you see where it goes. Like, okay, I'm I'm not sure how this facade how to solve that facade.
There, send it to Rhino. I go in Rhino, I model it while you go and sweep the rails and stuff like that, right? >> Mhm. Mhm. >> Yeah.
>> So, through wipe coding. >> Yes. So, uh yeah. >> it's really good context that everything that it can travel around, find things that it needs. >> Yeah.
>> Okay, there's some video. >> Uh and so with this example, right, where we have some people who maybe are not super experienced in Revit, but they want to be able to set up views. So, this is using Opus 4.5 where we just have a mirror of our model in the Rhino environment, and then this is the prompt. >> All right, can you comment on that a bit? What's going on?
There's a bit too many things. >> Yeah, problem is I see six frames in my screen. I'll try uh Do you see Do you don't see the prompt? Okay. So, the prompt was I I mirrored the two files, right?
So, the coordinate system is the same, right? And we want to be able to create our Revit views from the Rhino environment. So, my prompt was, "Okay, build a Rhino inside CPython script that grabs all surfaces from a specific layer. If the surface is oriented upwards, that's an RCP. If the surface is oriented downwards, that's a plan.
If the surface is oriented sideways, that's a section." >> Mhm. >> You have your sections here, and the model I think it took maybe 3 minutes with Opus Opus 4.5 to build a tool that sets up the views from you and place them on a sheet, right? So, this is this is the corner of the building where this tool worked. >> Mhm. >> So, yeah, because Revit has maybe a bottleneck, it doesn't have a scalable API, so it's a bit more complicated to kind of manipulate views like that.
So, maybe you can just do it on the Rhino side where it's it's flows easier, and then you just push it back to Revit. >> Mhm. Yeah, Revit in general not AI-friendly at all, but it was never meant to be. >> Yeah. And but I mean, the main use of Revit is as a document manager.
It's and I I would love if Autodesk would focus on that, just making documentation process really good, being able to like have granular control on the extent of sections and all that, placing the views precisely. >> Mhm. >> View title alignments. >> Yeah. >> They should really push hard on that.
Yes. >> Yeah, there are so many it's The thing is that there we all need just little things from Autodesk, but they focus always on the next big vision, like, "Oh, generative design." There's like AI assistant. They just try to make the headlines when everybody just needs like this little fixed like 50 just take 50 most common bugs we are asking for years to fix and fix it, and we're going to be happy. >> Yes. >> But I I see this over and over.
That's why pretty much most of probably beam managers started they just try to fix one little thing there, then they started like going really in depth, creating their own custom workflows, adding more software, and eventually becoming like I don't know discovering everything like because of just trying to make Revit work. >> Yeah. Do What do you think? Do you think Autodesk will train their own very efficient LLM to run Revit, or they'll skip that step? >> Honestly, I hope not.
It's not going to work. >> [laughter] >> The thing is that um Well, first of all, they made already the same CP for their AI assistant and stuff like that, but it's not backward compatible. And it doesn't make any sense because well, most people not going to use 2027 for another like year or something like a two. And we already have pyRevit which is open source, we can look inside. We It works across all versions, which is crazy, but also we can modify it.
And I think they focus on AI wrong. And if they train their model, they it won't be fable because it's expensive as hell to run. So, it would be something super cheap. And if it's super cheap, it probably won't be as intelligent as we would want to. So, we would want to bring our agent anyway.
So, uh they probably could make some kind of skills, but when I had conversation with uh Jonathan Jacobson, uh he kind of suggested good idea that they just should focus on infrastructure, not the product. Cuz Revit is great because of all the third-party add-ins cuz they just exposed Revit API, and now we can do what what we need cuz Autodesk cannot cover everybody needs, and you know like every single office has their own way of doing things. Even like we cannot even agree how to name things in project browser. Everybody going to have their own way. And if they literally just give us super great MCP, something like maybe you created something just this kind of experience, but they're not going to do it because there's a lot of issue that come out of it, right?
The security, like what if like intern like accidentally gets access and like goes wild with that and I don't know what they're going to do. They're in tricky situation. They try to catch this kind of shiny object, which is probably not theirs to catch. >> Yeah. Also, there's a lot of focus on destructive tools >> [snorts] >> and in the context of modeling, right?
In Revit or in Rhino. Yeah, you have to pay attention. But if you by mistake delete something and your project is on ACC, you have so many backups. And those rail rail guards to prevent destructive tools slow down the process so much. But there should be an option where you remove the destructive tool rail guards and just let people >> Mhm.
>> Yeah. >> But I see from their side, they're like huge corporation and they don't want to risk anything. >> Also, it's crazy too. It makes the tool useless. Like I I'm trying mirror MCP and it's just it's quite limited compared to what you could just one shot yourself.
>> Yeah. >> But I think that's why I'm so happy to see like Revit MCP. There are so many MCPs there is even if you're going to go for the this by harness, somebody already made pyRevit. Naming is weird because it's just one letter, but it's already has MCP for Revit. Kind of ready, so it's just going to one click add-on.
>> Yeah, I hope out of this focus on just make it as compatible as possible with with an AI and then focus on their what they're what they're good at. They're very good at I mean I I believe personally, I believe that drawings might disappear at some point as soon as some some municipality decides that it's time to just send over 3D model or something. It's not going to happen soon, but it will happen. But I think until then I architects should just focus on making that process as easy as as possible. It should be one click.
The whole document set should be one click in Revit. There's no excuse why it's not after 25 years. >> Yeah, I don't know. It's When talking about like Revit functionality and where it's going, it's always so hard cuz you see what happened in the past years where all requests user have, they kind of get ignored or and it's not developers' fault. It's probably just the whole structure of the company cuz their sole goal is just to make shareholders happy.
Since that therefore they focus mostly on headlines, I think. I don't know. Sometimes I have a feeling they're trying to kill Revit and probably push something like Forma forward, but they are like there's a huge gap before that can happen. So >> Also Also that API isn't isn't great. >> I never looked in Forma.
Is it? >> Yeah, I I I It's like we we together with my colleague Sam Sweeney. Um he's he's leading the beam efforts and then we're trying to look into APIs at the moment. Yeah, we kind of want We just want to put more time into design and I feel like everything is is like to share your Just to share your model, you have to save, you have to synchronize, you have to publish, you have to package, and you have to transmit. I mean, that's ridiculous.
Just to share a model. >> Yeah, I don't know. Honestly, it's This topic that there's like this a few years where it's not clear what's going to happen to Revit. Obviously, it's not going to disappear. There's like even if there's a better tool.
If tomorrow there's a better Revit killer comes out, it's not going going a big market share because everyone invested so much into Revit templates, workflows, power Revit tools and stuff like that at most offices like well, they just cannot justify the jump. Even if it's better, there's like a lot of training. Again, nobody is going to learn the new software in a week. So, I see that we're not moving away from Revit anytime soon, but at the same time, I don't see Revit moving as fast as we need. So, we just >> Yeah, I don't think we're going to move from Autodesk, right?
They have the user base and that's the I think the hardest to get everyone on board on something, right? That's why also MCP is great. It's not the best connection. I mean, I see a lot of way better uh for way more efficient, but it's just everyone agrees that okay, this is the standard that we're going to use now. And that's probably the the hardest thing to do and I feel like now with like a lot of consultants are in ACC and it's getting easier to to collaborate and that is the leverage that Autodesk has at the moment over everyone else.
>> Mhm. Yeah, it's always about the users, especially now like I see that there are a bunch of apps coming out. There's like literally I saw a few like in but the thing is that in AEC Revit does so much. Nobody can just make a quick project. Everybody focuses on one topic, mostly on these early stages of the process cuz the later one probably requires you to start with early ones in the same software.
I don't know, it's a tricky one. You probably have way better awareness about where it's going in terms of I'm not using Revit as much for the projects. I'm just kind of teaching people how to automate and I go really into kind of API, how how it works, trying to kind of learn more about it, but overall, I kind of see that it's moving, but I don't know where. >> Yeah. There's no one trying to solve documentation at the moment.
I've seen all these new companies and I've seen that new BIM tools, no one, is everyone's focusing on 3D, which I don't know. I think we we already have good 3D engines. We don't need 3D engines, but it's a document managers and yeah, that's and auto tagging and auto detailing from 3D and all that. That's that's the gap I feel like. >> I mean >> Yeah.
>> For a long time I was thinking that Grasshopper Blender is just going to surpass. They're going to add some kind of beam more There are There are like Bonsai it was renamed as Beam Blender or Bonsai. I think Grasshopper some had something as well, but it's not that common to use. I haven't really seen people really jumping on board in like in masses. They usually try it out, make one two projects, but then they I think they fall to Revit anyway.
So, I honestly don't know cuz our industry is one of the slowest to move. Now it's I think catching up, but before that it was like so behind. Cuz everyone was just dependent on native tools, plugins, like nobody looked into automation as much a few years like like 10 years back. And there was like huge gap just kind of make it more efficient. But now I don't know.
It's a tricky one. >> It's a tricky one. >> I don't think that I'm the right person to kind of really answer this. >> I'm I'm trying to see how we are with our tool. >> Oh, yes.
Where are you? >> No, no, no, I'm not sure yet. It's just a >> Yeah, so the laptop is the bottleneck, right? >> I need to I need to redeem myself and follow up with the with the with the tutorial or some demos. >> [snorts] >> Yeah, well, I'm sorry everybody we didn't really plan it.
Probably it's mostly on me. So, don't don't blame the laptop as much. But yeah, Alex offered me to kind of do the demo before. I was like, "Ah, we're going to be fine." So, yeah, I think we're just going to wrap up here because of the time. Unfortunately, well, I'm going to also kind of dive in Cloud Code, but if you can also later kind of either share the demo or something, I could also maybe kind of point the people to that.
>> Yes. >> Uh but now, I I always like to usually end my podcast by asking people like, what is the one like this advice? It can be multiple, but what's the main advice for beginners? And before that, it was about coding. But in your case, like and since this whole AI era coming, what if people who, let's say they are just use still ChatGPT and Claude in the browser, what should they do?
What would you recommend to focus on? >> I think probably the most thing is most important thing is to just constantly be curious and try to grow and the only way to satisfy your curiosity is to go and do the thing and see what happens. So, I think it should be a lot of that. And we know maybe don't need structure. You don't need You just just do it, see what happens, and then that will inform you what is the correct way moving forward, what should you focus on, rather than trying to get all that beforehand and then and then and then be stuck in this preparation stage.
>> Mhm. >> Install All right. Install Cloud Code, try to just one-shot tools. You're going to get something. You're going to get excited, amazed.
You're going to think you can do anything, then you're going to try to do something more complex. You're not going to be able to do it, and then you're going to go to your tutorials, and then you're going to and it's going to be a bit of that. So, that's pretty much the process that everyone, but it all starts with curiosity, right? If you if you If you're not curious, nothing will nothing nothing will happen. >> No, that's a good one.
Also, think Also, they need to stop kind of being afraid of trying it. Cuz many people don't try because they don't understand it. >> Yeah. >> And have you played played a lot of games when you've been younger? >> Yes.
Too much. >> I think it comes from that because I also was a lot in games and I have this mentality like give me any software, I'm not afraid to click any button. If it breaks, if it crashes, I kind of understand like well, there's save, there's cancel, and I click around. But I know that many people they they need to be they need to know what the button does before they click. >> Yeah.
>> Where I think it's coming from games, we just click the button and see like oops, crashed. Well, now now I know. So, I think this is also there like just kind of sandbox your Revit. Don't start with live project, please. Just >> Yeah, yeah.
Don't don't don't do it on enterprise network, for sure. >> Yeah, just understand kind of how it goes. But yeah, I think it's a good one. Just be curious, try it out. Also, would you like to share any what what you're up to, where people can find you, and stuff like that?
>> I'm I'm I have in my drafts on LinkedIn I have four articles. So, it's pretty much only there. I'm trying I'm not very active. I answer to messages. I I I try to stay away and try to curate my feed to people I know.
But I'm planning to to just release a bunch of articles just taking this sober pragmatic view of how we use the tools, the tricks, and and it's mainly going to be focused around the Rhino inside and and Revit's to begin with. So, just give me a follow on on on LinkedIn and then Yeah, that's that's it. >> Okay, thank you. Uh I'm going to leave the links in the description where you can find Alex, what he has what he's up to, learn more about what he does. Cuz he has a few articles on LinkedIn already and he mentioned he's going to write more, so might be interesting.
Thank you, everybody, for watching. This was our first test drive of going live in Pirate Podcast and we started with massive technical issues, so I'm really sorry for that. And yeah, I'm going to prepare much better for the future. Going to see where it goes. But thank you once again.
It was a pleasure, especially talking to you, Alex. Thank you for coming on the show. And Wait, is he still here? Going to complete. Okay.
Goodbye, everybody. Alex, you stay.
### @Aussie BIM Guru on AI, pyRevit, C# and coming back to Dynamo??? [pyRevit Pod #9]
https://learnrevitapi.com/podcast/py-pod-09-gavin-nicholls/
Gavin Crump (Aussie BIM Guru) on AI, pyRevit, C# add-ins and why he is coming back to Dynamo as automation lead at Architectus. pyRevit Podcast #9.
## Transcript
So yeah, um what you up to given like overall like you've been through quite a journey I would say like like Dynamo, Pirate, C#, now we're getting back to Dynamo. So like you're in this kind of you are everywhere. >> So what you up to? >> I mean I try to tinker with a lot of things. I like to know what's going on in ACE and even if I don't use a program on a day-to-day basis, at least I've tried it once.
I know roughly what I'm talking about when someone talks to me about it. Um, but I guess for people's context, currently I'm working at a company called Architectus. They're 800 plus person firm in Australia. Um, we're probably the largest headcount in in Australia as well locally. Um, and I effectively work as a computational design/revit automation lead in the business.
So generally if there's anything that's a script, a graph or an addin, my hands are on it at some point. Um, so over the years I started as in visual programming like uh Erik mentioned with Dynamo. So that's pretty much was my gateway into programming in AEC and eventually found my way to Python Dynamo eventually to pyRevit and that's sort of where I started developing extensions for the company I worked at that was Architectus about maybe four four years ago. Um eventually hit some some brick walls with things that Pyrevet at the time was struggling with. So that was between the 2025.NET um Assan to um community handover phase which was a big challenge at the time and luckily they they've got through it really well.
um Erik and you know John Mark and people like that have helped the community through that very well and they're in a very stable pattern now but I guess the the business couldn't afford um to wait um unfortunately so we did actually figure out roughly how to get pyrovate to work innet we did some tweaks on our side and I remember Brasho John Mark said this sort of works but it's a it's a big hack um because I remember there was issues with the pyrovate app loading and a few things like that and we figured out if you move this variable here and did that it sort of worked um but a lot of other things broke. So that led me to sort of just jump straight into C#. Um, and we'll talk about this later, but I used AI to teach me a lot about C, about good patterns and things like that because I really had no idea how to get started with C. Um, and luckily I I used a template, the nice point template, which is great for getting started. It lets you skip a lot of steps in Revit add-in development.
And from there really [snorts] just um eventually got to the point where I was comfortable deploying a C# toolbar um around the whole company. And that's pretty much from there become my preferred development development method. Um and we'll talk about this later too, but I have recently actually come back to Dynamo, but now with the C# developer hat on and building custom packages. So, I'm really only just getting started there, but it's been a pretty wild pretty wild ride going through all those sort of abstract layers of code. Um, and you know, using Grasshopper and Rhino inside and all sorts of other applications along the way.
So, that's pretty much Yeah. how I've got to where I am now. >> Yeah. >> Yeah. You made like a full circle.
But you mentioned that you kind of learned C with AI. Have you watched any C# courses like you know like from start like this and that or you just went straight learning with AI? >> Yeah. Um so I did um I did follow a few basic fundamentals courses. I always believe that every language is best approached the fundamentals layer um to make sure you you know how variables work for example very basic concepts where you wouldn't want to skip it.
You like if you don't know what a variable is in a language like you're in trouble. That's a very important building block >> to everything. And and the C is very different because now you have to strongly type everything. You have to tell variables what they are so that the compiler actually understands what you're going to be compiling so it can assess it in a pre-ompilation state. Um whereas in in Python you if you unless you you know you you write Python code very well, you're you're just throwing your script at the wall basically and hoping it works and testing it, breaking it.
Eventually it works. eventually all the logic patterns work and that's when your script is done. Um I know you can definitely build Python in a strongly typed way as well but C# you have to so that was a really important concept. Um so there was a few basics courses that I sort of >> bumbled my way through um and then eventually got the nice point template. Um John Pearson uh who works at Autodesk now for the Dynamo team actually led me to that template.
So thanks John. Um, and that helped me skip a lot of the complex parts like building your project structure. Um, setting up multi- version support, which is quite difficult to do uh, from the ground up. It's hard to know how you meant to do it. And then that helped me actually just build my first addin, make my first command work, um, put a button on the rev the riv Revit ribbon and then [clears throat] look back and go, "Wow, I can't believe pyRevit does that automatically.
That's a lot of a lot of interesting work that they've done." I actually went back to the pyrovate code and started to read through what it was doing behind the scenes and it [snorts] gave me a lot of appreciation for what pyrovate is and like how >> had to start that off and just have those ideas and put it together and um it's pretty amazing just the abstraction that achieved in pyRevit. >> Yeah, it's crazy. >> He still says like ah I don't consider myself a great programmer. I'm like well what do you mean like this thing is like amazing like because I also look poked a little bit at the code and everything is reused elsewhere. where you constantly have to kind of track down okay that thing is from this from this from this.
I'm like oh then you have to go back and like mentally when I tried to like explore power code in the beginning I was like no that's I'm not ready for that because there's like every dependency everything is reused it's quite efficient >> now I kind of get it I'm like okay I can jump around figure it out but before yeah it takes a while. Yeah, another really important part I was going to say that helped me with C# is learning my IDE. Um, that's one thing I never really did that well when I learned Python and pyRevit. Like I used PyCharm eventually, but I literally began my Pyrebit code in Notepad++, which is like pretty dreadful. >> Then [laughter] eventually I figured out, oh, you should use at least like Sublime or PyCharm or something that holds context for you and helps you navigate your coded project and go between classes and references.
Um, Visual Studio says you have to start this way. Like you don't have a choice. This is this is a class management program basically. Like you're going to have a class library. Everything's semantically connected.
You can hover over stuff, jump stuff, and you can't really you can't build a C# project in Notepad. Um, but like I guess that was a bad habit that I had to kick once I learned C#, which was good. Um, I used PyCharm, but not to like the strongest of my abilities. Like I didn't have stubs set up, for example, which is like a huge change if you set that up. >> Yeah.
So I didn't use stops which so everything was basically mental for me. So like when I got to C# I went back to P Python. I'm like oh like stops would have saved me a lot of mental gymnastics cuz you have to hold context in your head basically. Um so >> I also started without stops for a couple I also started without stops for a couple months but then I was like okay I'm gonna spend some hours figure it out. And it was such a such a big change.
I'm like oh I don't have to remember all of it. I can just kind of put it in and I'm like >> I know it's basic thing now especially for people because there are like tutorials everything and like >> everyone knows how to do it simple simpler now but I I'm surprised you haven't figured but haven't set it up >> like there was a lot of things where I look back and I'm like I know in my head there was like surely there's a better way but I was just under so much time pressure at work that I was like I would just do the thing that takes me the least amount of time now even though probably if I just spend a bit more time in learning a systems approach. it would have helped. So C# did actually make me a better developer. >> It taught me about the architecture of code and how it holds itself together.
What a class is like I I didn't use as many classes in Python as I should have. Um mainly because I found that using tabs to set up a class is a real >> pain. Um I like in C that you just use encapsulations and they sort of imply your tab structure. Like you don't have to get the tabs just right. You can literally just press a tab and the whole thing just fixes itself for you.
So like and that's a Visual Studio thing I guess not a >> uh you mean like identation and all of that. So everything kind of >> yeah like indentation in C#'s not really a thing. Um you just >> not really but I convert to Python right away >> but yeah I mean it's not a big issue. So when you when I went to C#, your object-oriented programming in general, it wasn't like really great. >> Um I I had a vague understanding of what I should be doing like I knew you know concepts like interfaces and some of those more abstract layers that you need to appreciate in in a well-built program, but I wasn't really being an object-oriented programmer.
And even until maybe a year or two ago, uh there were still a lot of um concepts I wasn't really doing that I am now. So for example, I did lean quite heavily on what we call static classes in in C, which is basically like a singleton of an object in principle. It's like a class that holds its own methods and call it like an object, but you don't create like an instance of that object. I'm starting now to look at like helper classes instead where you sort of create an instance of a class that can do things for you so that if you need to have more than one running at once, you can. Um they they hold, you know, better state.
They make for more readable code. So, I'm still picking up a lot of things that, you know, aren't necessarily things that I, you know, would have known a year or two ago. Some of that comes from using AI as a starting point. I probably did skip some layers of fundamentals that I probably could have picked up better if I just done some more courses. Um, but but one of the best things for me is having developers who are friends.
They can look at my code and tell me if it's awful and go, I wouldn't do it this way. Um, I love criticism. Most people can't handle criticism in my experience, but I love it. like I just if just tell me if it sucks and I'll tell me what to do better and I'll research it. >> So I've got some really good friends that help keep me grounded in that space too.
Yeah. >> Yeah. It helps you learn so much faster because I know like many people also don't like to give really good feedback because they afraid it's going to kind of touch your feelings or something and they kind of say no no it's great Kevin all great >> but instead like if people like oh you want to you want me to roast you hold on I'm gonna roast you man. But you learn so much. Sometimes it's a little bit kind of >> it gets to your ego as well.
>> But in the end of the day, that's a if you ask for the feedback, you should be ready to actually take the feedback. >> But that's like the best way to learn as well. >> Yeah. >> Cuz well, somebody with experience says like, look, I wouldn't do that. Maybe like they explain to you, but even if they don't, you're like, okay, I should at least kind of consider that little piece that maybe there is a better way.
Well, it's that idea of like it works, but like you know, it's like is there a better way of doing it? Is there a more scalable way of doing it? Like, you know, is this going to work for a 5,000 person company? Maybe not. Like, so I like to think in that term where I'm like, it works today, it works tomorrow, maybe it doesn't work in a week.
It's like you've got to figure out that context of where your code is going to be needed. Um, but I guess working at a large company as one of their only developers doing this, like it has forced me to talk to a lot more people outside my my domain than my company to make sure that I'm sanity checking my own habits and my own patterns and antiatterns and all those things that emerge over time. Um, and I think putting code out in the open on GitHub has helped me a lot as well. So I do have a lot of side projects that I keep out in the open. Luckily, my contracted work is quite flexible.
There's a bit of, you know, leniency there. So, I maintain like my own C# tooling, um my own Dynamo package now as well. I've got one in Python and and often people just jump on and say, "Hey, I noticed you did this." Not the greatest way like, "Have you thought about this instead?" And that that's been a really great way of just putting myself out there and having some criticism because no one at work looks at my C# code to that degree. Um they might, you know, look at it out of curiosity, but they're not going to be like senior developers or people working at Microsoft. Like I've had some people that work at like major, you know, fang companies look at my code before and just go, "Oh, wow.
This is like really bad compared to like having, >> you know, enterprise scale." And I'm like, "Of course, I'm I'm building for like 10 people. I'm not building for enterprise, but but tell me how you do it." And then like I get to see like how deep the rabbit hole goes and go okay like now I know if I did this again and I was working at a you know 2,000 person company I'd need to do a lot more you know abstraction and you know build abstract classes and you know um interfaces and factories and all those things that I'm sort of starting to learn now. >> Yeah. Yeah. There's the thing like because when they when people when programmers work on large companies at least with big user bases every like kind of tiny second actually adds up.
>> Yeah. like the server goes easier, less resources, cheaper cloud hosting and stuff like that. But when we work in like companies, I make tools for like 10, 20 people. Honestly, I prefer to make my code slower if it's more readable. >> Yes.
>> But again, um I have a YouTube I teach people how to code and stuff like that. So I consciously try to like even like when I ask AI for suggestion, sometimes it uses regex or something like that. I know that many in the audience going to be like, "What the hell is reg?" So I try to kick it out and make it simpler. It's going to be slower, maybe not as bad, but it's just like the way of kind of my programming, I guess, because first of all, I make code that that can be read read by others and they can learn something from it. >> Cuz I've seen super efficient code that which is unreadable.
Even people who wrote it like they come back a couple weeks later, they're like, "All right, what happened here?" Like there's like it happens as well. >> The best code is self- commenting, right? And I don't actually agree with that where they say you should just be able to read the code and that is the comment. the code is so obvious that it is its own comment. No, I can't get into that school of thought.
Like, I've seen code before that's apparently that way. And I'm like, unless I was a senior developer, like most of this would not make sense to me. But I can definitely understand like elegant code versus non-elegant code. And when it's, you know, when it's beautiful, when it's obviously very object-orientated in nature or functionally orientated using like F. Um, and I definitely see the difference and like, okay, if I was a better developer, I'd get that.
But I I always have to think in reverse. It's like I'm leaving a breadcrumb trail for other people. Like if I get hit by a bus, like who's going to learn how to use my code? They're going to have to figure it out. So I feel like we have a a social and a moral obligation as developers to make sure that we leave behind some degree of a breadcrumb trail.
Um just in case, you know, we move to another company. Like I you wouldn't want to leave them in the lurch unless you know unless you really hate your company and then it's like why are you working at them? Like you've got to love where you work, right? Um so like part of that is a big part of what I do as well. that yes, you take more time to write some code and you may not write it in the fastest way, but it's it's easier for someone to consume and understand.
And that that's a big part of how I think about it. And Dynamo was a good foundation point for that because I guess Dynamo is meant to be very easy to understand, but obviously does things in less direct ways, doesn't support looping, those sorts of really >> I was about to bring loops. Yeah. >> Yeah. Yeah.
So, so that obviously like makes your code way slower. Um, but it's easier for like someone to read that has no idea what code is because they can see, oh, this is literally going here. This is going there. You don't have to visually find the variables in code like you do with written code. So like I think it it it sort of made me appreciate what Dynamo and even Grasshopper gave me as a programmer.
It helped me like >> follow that brick trail that developers left behind and said here's how you code. I don't have time to teach you, but here's Dynamo. Have fun. Um, so like it sort of made me appreciate I have to do that with my own code as well. Uh it was great starting point and about the code there's also this thing that code will never be perfect as developers no matter how many times you're going to rewrite it every time you're going to be I wish I did this stuff differently this one and like at certain point you just start rewriting it for your own ego just to see how far you can push it but the code is not going to benefit much anymore it might benefit but it's better to just focus on something else as well >> yeah every time I go back to rewrite the same code I would start at a systems level deeper and deeper and deeper each time cuz I'm I I have learned the architecture I'm building and I'm like okay I need something more abstract behind this and now I need something behind that behind that and it will become more scalable each time but yeah you have to eventually commit to the way you did something to some degree and go well this is the extent of the scale that this thing is going to work at and if it changes well let's start again um but until then we've got to sort of just keep it going like there's that challenge of code right where it's like you've just got to keep it going um sometimes that's good enough I actually have an interesting question.
Since you made a full loop, I'm pretty sure that you saw some of your very old code, maybe some Python nodes in Dynamo or something. How was it looking at your old code after all this kind of journey? Like >> very painful. Um like some of the things I wrote are so verbose, so over the top. Um like I didn't know how to do lambda functions when I did Python.
So like there's there's so many things where a lambda would have saved me a death. um like a defined function like just the layout of my code was all over the place. I could have stored things in common libraries. I have some functions that are in every single node I wrote in Python that are not stored outside the node that I just copy and paste in a boiler plate every time. So I'm like I'd approach it very differently now.
Um if I went back to Python, I would immediately start building libraries and calling those into the nodes instead. Um that would be one really big change I make because there's a lot of repetitive code ideas. Um, C# helped me see that because you sort of get forced to build libraries in C# otherwise you're writing the same code over and over again anyway and eventually you learn that you can make DLS and pull those DLs into projects so that you can use the same library of code in multiple projects. Um, but that's a big change I would have made. Um, also like >> probably like style is a really big one for me.
>> I didn't have a good coding style. So I like variable naming um upper uppercase lowerase syntax. There was a lot of inconsistency in how I named things um blade out things uh a lot of antiatterns that I wouldn't use anymore. So bad habits that I just kept using um because I was ultimately looking at each node like its own little project and not thinking about it as a big a big picture or a big library or a big project. So I think that sort of naturally made me miss the the opportunity to look at it more like a project.
Whereas pyRevit sort of helped me look at my code as a project even though I didn't have stubs and it wasn't all contextually aware of of itself. Um I still have at least like folders and places and layouts and I was using libraries. So I did have like the li folder. I was putting things in the li folder. Um so I did start to appreciate okay I don't have to write that like every single time.
Like the >> big one for me. Um, yeah. So, and it also makes you appreciate how far you've come as well. So, you sort of get a bit of pride and go, okay, like I've obviously learned a lot of things since then and you know, I've left this behind as a an artifact that people can still learn from. Um, but I thought, should I go back and fix it?
I'm like, no, I'll just leave it there because it shows people that we're on journeys as well and we're not perfect and we learn as well. So, it's important to leave that behind to humble humble ourselves as well. >> Amazing. Now my EF tools is also a mess. I look there I'm like there are tools from like four years ago.
I looked at the code I'm like oh I need to rewrite the whole thing. I'm planning to rewrite the whole EF tools from scratch because um yeah that's a big one. So are you thinking that you're going to go ground up or you sort of doing like a rework or how's that going to look? >> Uh I've been planning this to do like for a year. It always stopped me because I was like if I'm going to start fixing it's going to I'm still going to have a lot of legacy code and stuff like that which I don't like and I better rewrite it.
But then I better do it kind of I don't want to just start like EF tools with one tool in it. So I need to actually sit down and do it and think about all the systems and actually going to definitely rework. I'm going to start first of all with like kind of VPF stuff cuz now I prepared like the brand kit. I have a system in mind how to kind of make it reusable cuz I already did the test. I think in even in EF tools there are some things that already work this way but now I just want to kind of create very blank kind of example forms without any styling then connect to my class and it does the styling for me everything so this way I can quickly make the form super quick I can later show you brand maybe even right away I just >> yeah there's a similar system in C we use it's probably maybe a bit less abstract but we have like a shared styling zaml that that can be pulled in as resource dictionary to every form and it sort of just tells everything how to how to look and how to behave.
Um, so I use that a lot too in C# and that makes a lot of sense. I found WPF is is a lot harder in Python. I found that was one thing that I struggled with. Um, there's a lot more I found, you know, formatting. Um, I found the XML is a little bit harder to write.
There wasn't the visual editor. Like I assume you still write editor in Visual Studio just to see what it looks like and then put it down into Python. >> So, >> not not for long. I'm going to get back to that, but >> yeah. Yeah.
>> Yeah. I think the biggest issue is just not enough resources and examples because when I tried to learn VPF for pirate, it was such a struggle. I just brute forced my way through because I was just stubborn. I tried things. They somehow worked.
I'm like, "Oh, copy that one. Save it. Save it. It works. I need to remember that." >> Like we that's how we eventually build.
I mean, I don't remember how to build every WPF form off the top of my head. I still go back to my own forms, copy and paste, change bits like from scratch anymore. I have no idea what those first four lines in WPF say like by the top of my head. >> It's like it's like imports. It's very weird way to import something.
>> It's like so it's perfectly natural to work that way. Yeah. >> I just remember that this is how we import some stuff. So I'm just I'm just going to leave it there, not touch it and stuff. Uh but the thing is that where was oh when I started learning eventually I got to the point where I was just watching C tutorials but I was following that in Python without really knowing how to follow it in Python.
I was just like okay I think if I'm going to just write it like that skip all this like C kind of stuff I hate it's going to work and somehow it worked. I just got lucky it worked and from there I build up but now I just going to share my screen. Can you see it? >> Yep. Yep.
Oh nice. Now it's AI is so great because now I'm going to make it more systematic because now it was a bit random things appear and disappear but what I'm planning now first of all I'm going to make this kind of document and right here you can already see there are like some boiler plate for like AI as well. So here's like how we create buttons here's how they look and so on. So my goal is kind of finish that one. I try to just force AI just give me like brand key put there like example examples and stuff how it looks.
So my idea is now first of all I'm going to make document like that. Well I already have it but I just want to refine a few things finish it and make it sort of reusable because I don't want to just tell just come right here change this thing because it will change something else without me knowing. So I just need to make it something I have an idea but we'll see. And then my idea is that based on that I want to just make kind of files for AI so it can help me kind of go along and style everything like I want. But in the end of the day, I also know that I just need pretty much resources files and then then it's going to take a lot of kind of for me here.
>> So yeah, this is one of my things that before going to EF tools, I started thinking this all strategically. Okay, if I'm start if I start extension from ground up like completely from point zero, what things I would change? I'm looking at EF tools, it can be painful like you mentioned. I'm like, yeah, I should reuse more. But then I also think maybe people should see it like in tutorials without libraries.
But I think I'm going to go somewhere in the middle. Still reusable, but to the point where it's still very readable. Not like Py Ravit is built where everything is super reusable, like the most efficient way, but not as readable. So I still like things readable. [laughter] >> That's a great branding kit and a great um great summary.
I mean, I wish wish I'd take the time to write one of those. It's amazing. >> Uh the thing is that I'm going to make it reusable. So I just want people to just go in plug their colors some stuff like that and they get copy of that and then there are two things one is like HTML for you to see but based on that one there also should be two other files. First one the this windowres resources which is actually used in VPF and the third one is just to give it to AI and MD formats.
>> So this is like something that I want to do eventually. I have some ideas how to do it. just going to kind of spin up my probably jungle server that's going to kind of kind of build it up from ground up and AI is going to help me a lot there. But you mentioned about ZAML being a pain in the ass to write. I just need to find why it's not here.
Okay, I think it's I just need to figure out which local host I put it on. I mean, what you're getting there, I guess that the hard thing for me is AML forced you to know a lot of tags that aren't like obvious to you on the surface. like I had to read the docs a lot when it came to ZAML and learn all the tags and control names and um properties of controls. So it I found it was a little bit less uh logical than C where it sort of tells you what what properties objects have and it sort of you you almost needed to know what you didn't know I found was able to begin with but that's where examples were quite quite useful. >> Mhm.
Uh just give me a second. Something just need to run it. For some reason it's not running. >> But yeah, also like this AI just makes so many things so much simpler. And I started focusing Oh, you might see it now.
>> Y >> I started focusing, okay, how can I make it simple for others without actually going and creating? And one of the things I always kind of dreamed about is creating my own freaking like ZAML builder. >> Apparently you can do that. Uh, damn it. There's no code.
Maybe there's something better. I just need to copy one of the code examples. I'm going to be quick. >> Uh, I mean, to some degree, I guess like this gives you more control than Visual Studio if you want to customize it a bit more because you're limited to the um the Visual Studios edit editor setup if you use that one. >> Yeah, it's it's pretty good one, but the thing is that most people going to use even not even 1% of Visual Studio capability.
It's such a such a powerful software. It can do pretty much there's so much things it can do. I don't even know like probably >> 90% of it I don't understand like what's going on there. >> Okay, now we're working. But the thing is that I starting building this going to eventually make it available to people and stuff.
But now I just took the best parts of kind of Visual Studio, put it here. It works. I can modify it. It actually responsive and stuff and it's amazing. And the thing is that what what Visual Studio Code doesn't support anymore is Python.
Mhm. >> And now I can actually add here Python support as well. >> But not exactly Python support, but it's it's what par developers need. We just write some example. We kind of go in, we drop some events.
Let's say click is going to be I don't know UIE button click >> and then it kind of gets you some boiler plate. >> This is what I always dreamed about in Visual Studio. I even tried to set it up but with they dropped the IronPython support. So you had to use very old versions of Visual Studio and even there it wasn't what you needed. So this one was this part never worked for pyra developers.
It was very >> if you use C# it does do a lot of this for you but you have to use C# is the obviously the catch. >> Yeah that's the thing the behind code being aware of the the front code. So um this is this is awesome. Um so so this was all spun up just by yourself or >> uh this now running on I use Django for all my projects because I understand Django I understand Python even though people might say like oh you should run like on TypeScript for React or whatever like to make it like the most optimized and stuff for me I'm like do you really because even even like documentation like I reworked is it running yeah that one that one I also went I don't care I'm going to go for jungo and it's fast it's like super fast like you don't need you cannot be faster than that. Okay, if you have like million users, >> how you lay things out behind the scenes, that's all what the speeds depended on like how you structure all the data that it's drawing on.
>> If it's >> I mean the thing is that Python can be efficient enough. If you talk about like running Facebook on that, sure it makes sense to go to something more efficient, but if you're making like dogs for like couple thousand people, nobody people can wait like tiny tiny they don't even have to wait. It's even faster. So there's the thing that people say that well Python is great at many. Python can do everything but it's not really great at everything.
But at certain point Python is good enough to certain degree. >> Some people think it's degree much lower but what I found like with like my this web development exploration and stuff that Python can handle quite a lot. That's >> you can use it quite far. >> I mean name like Cshot can't do everything well. It's it's good for like building applications and integrations, but I mean all roads lead back to C, right?
I mean at some point you have to go back down to memory management if you want really fast code, but that's sort of like where most people find themselves having to go when memory and performance matters. I mean C#'s not the golden solution to fast applications necessarily. >> So yeah. Yeah, there there are definitely like strong and weak points to every single programming language and Python just have Python just kind of in this middle spot where it's not the best but it's good enough for most thing because there are just libraries for everything you can like you can do quite a lot. One thing I'm surprised that AI uses Python like the most pop like most of the AI frameworks they build first of all on Python.
Everyone talks about how Python is inefficient and stuff like that, but still like all the CIA companies, they decided to use Python because it's easier to use or something. I still don't >> fully understand it because they're also better implementation of Python which are more efficient but they still like you wouldn't care. >> Run it through various web services that that's a really big benefit to it. Like whereas like um C, Rust, other languages, they don't seem as naturally inclined to web- based development. They seem more inclined towards hardware based development.
So um >> yeah but when we talk about >> yeah but the thing is that when we talk about AI >> they wouldn't mind probably creating their own new language just to make it efficient because it's like running so many talk it makes sense to make it super efficient it's still kind of Python is like preferred libraries for training and stuff like that >> I guess I don't know maybe because the target market not not always like fullon software developers >> a lot of the data scientists get in kind of just start with programming they need to kind of start analyzing stuff a lot of kind people like us like in different niches, they just need to do some stuff, >> do little plugin, do some little program and they don't want to spend like hours figure out how to deploy like C like software or something like >> I [snorts] mean one thing that helps a lot with Python and I do miss it is being able to be more loose with typing. Um strong typing is like makes things very legible but there is some scenarios I get into where I'm like man I wish I could just say this thing's a variable object and it doesn't have a type and you figure it out. um that I used to be able to do in Python where something could be returned as like anything I wanted it to be basically out of a method. It could be a view, it could be a sheet, it could be an element, it could be anything in you have to be pretty literal in C unless you use generic >> generic functions which have their own challenges. So like it's like that can sometimes be a bit of a hurdle that I think makes an easier language to pick up.
You don't have to think about types and objects as much as you do in like C#. So like that that would definitely be a big motivator to working in Python to me still. like it's I do miss being a bit more loose like that. >> Um and saying, you know, can you know can you interpret that figure it out for me? I don't want I don't I don't want to care about the compilation just interpret.
>> Um I do miss that at times. Um but at the same time I like being more regimented in typing now as well where I'm like okay I know it's going to work like because it has to be this type of object and it's either this or it's null. There's no other other possibility. So it is nice to also sometimes have that rigidity built into your code. Yeah.
I noticed there are like literally like two camps because there are people like me who just don't want to deal with that. I I still do it in Python here and there when I think it's necessary and I see the value. The beginning I didn't see any value in that but I understand why I kind of I appreciate that it exists but I like that I don't it's not enforced on us. But then there are also people who hate Python because it's not enforced. They're like no I want to know my types.
I want to do this. So it's just like >> some people I think they like this kind of to be in certain rules that they have to follow it. There's like >> I don't know it just different people think differently. So the language also kind of supports one more than the other. So >> some people say oh C# is so much simpler to learn than Python.
And I'm like wow that's interesting take but okay. And I heard multiple times. >> In the beginning I thought like well that person is weird. But then I was like, "Oh, there's like many of you." Like I'm like, "Oh, okay." Probably just you approach it differently, like from a little bit different angle. Not like weird people, but for me it was like, "Huh, I didn't expect that." Because in my mind, I'm like, "Oh, Python is simple." >> You can definitely pick it up and run with it a lot faster.
I think I think the big thing with strong typing is when you start to build very large classes and libraries and applications where you need like almost a contract between your classes to say you must ensure this is this type of object, otherwise I'm going to throw it and I'm not going to work. um whereas in Python you know it would throw and you're like well why did it throw we have to go back and figure out through all the classes what's going on here and what type this should be >> is it that C# it's like I can only accept this >> as a part of my interface contract if it is this so like it does sometimes help you >> ensure when you're building like libraries for people to use that like they have to give it certain types of arguments otherwise it's you know it's going to throw when you write your code whereas sometimes in Python you get those you know silent failures the worst ones of course that like you know you'll get throws where it's like I didn't give it the right type. Whoops. Whereas in C#, it's like sorry, I'm not even going to write build your code because it's not the right type. So, it can, I think, help when you're building larger scale solutions, but um but like it definitely makes it harder as a beginner >> for sure um to get started.
>> Uh definitely it's also required for the debugging because the issue with like Python code like your ID doesn't always know what kind of what are the variable types and stuff like that. So, it cannot really debug it. So for power rait we don't really run any debugging except for kind of running the tool printing stuff and like oh not what I expected let's try again >> I mean also make it so much too like we have debug right line like we still print a console to figure out what's going on sometimes it's not um like people do laugh at the whole print debugging but I think everyone in every language does print debugging every now and then just to see what's happening. >> Yeah. >> Yeah.
Nobody goes far from this hello world statement. [laughter] Yeah, that's a good one there. >> All right. I I think we went we a little bit more technical in like languages and stuff. >> Yeah.
Yeah. Um I we can probably like pivot on to like either AI or the Dynamo logic. Maybe AI. Do you want to talk about >> Yeah, we can go to the AI just in general. See >> because we kind of started talking this before, but I think I'm going to I'm going to include our earlier conversation somewhere embedded here as well.
>> But in general, what do you think about the state of AI for specifically for like AC? not Ravit, not limited to Ravit, but AC, let's say. >> Um, I mean, I think it anyone at this point that says it's not going to be a transformative gamechanging technology for our world is probably probably wrong at this point. I would say I think even if we're still not at the final iteration, we're not seeing the final enterprise solution that's going to be adopted by the masses like the internet. Um, it it's going to happen at some point, I think.
Um, even if we burn the entire planet to do it. though [laughter] I'm a little bit socially opposed to AI. I still look at a lot of things it's doing or that it probably will do. I think it's a class divider. I think there's going to be a really big ownership class that owns data centers and the means of production and then there's going to be people that are need to pay for the means of production.
I look at subscription models that we're already paying for and I'm like this could be like Autodesk but way worse for our industry. Um, you know, we could be looking at a lot of cost if we're not careful, but >> it's hard to deny that it's going to be a thing like it or not at this point. Yeah. >> Yeah. Yeah.
I see. There's like a lot of talks right now that it's already getting really really good and people don't realize it, but we are getting it for so cheap right now. Even though people say Oppo's price is so expensive and this and that, everything is still subsidized because they still want us to get hooked even more to the point where we cannot really do anything without it. That's the end goal right now because and then there's this cool term is like in uh what was it intelligence as sub um I forget exactly is it intelligence as a service, intelligence as subscription, something like that. So it's about turning intelligence into like just kind of selling it.
You want you want to do something cool like build an app like you pay us money we give you intelligence you build it. Pretty much what it happens now but this is going to be more kind of I cannot put it in the words but I think people get what I mean that in the future when you for example come to work you're going to get maybe your some kind of allowances here and there and then like okay G for this year you also get like 5,000 in tokens spent like do whatever or something like that. It's definitely coming because it's already kind of here. Some companies do it more officially and not but it's definitely going to become part of everything how we work. >> I mean I worry I guess the phenomenon you might be talking about I often describe it as putting your brain in a black box and then paying for it.
Um you know you're paying for an brain that part does worry me um to some degree. I look at the younger generations and they're already such victims of technology and social media and algorithms and mental abuse through these services. I I do hope that the the AI companies are either forced to be socially conscious and moral. Doesn't seem to be looking like that at the moment. Um or that there's open source models that are so good that they keep the the corporate models in check because if they get too brave, they raise the prices too hard, everyone's going to go back to the open approach instead.
Sort of like pirate day >> for for you know the cost of access to streaming services. Like there's a fine balance between those two environments. Um, but I guess I I do I do hope that either governments or just society forces them to at least think with the social good in mind. Um, because otherwise, yes, we could be looking at >> new generations that don't actually have any innate intelligence available to them. They have to pay for skills.
And then at that point, what is the person doing, I guess, is the question. What is their purpose? Are they there to just think and think cognitively so that an AI can turn that into results or are they just pressing buttons because that's where you can pay someone less money and that's where you look at like universal basic income and all sorts of arguments that which in my opinion will just push the glass divide completely apart where you have the trillionaires and all their family and then you've got everyone at the bottom that just presses buttons to get like some food for the day. So it's um it could be various topic or it could be fantastic like if we get the right people in charge and you know like we said there's an open closed approach it could be [clears throat] amazing like we look at the internet people said the same thing about the internet when it first came out they said this is the destruction of society um everyone's going to be access everything's going to be dumb um I don't know if it made everyone less intelligent I think it made us more socially conscious um because now we're aware of what's happening in the world I think that was a big game changer Um people used >> the knowledge became so much more accessible before that well you couldn't get it. >> Yeah.
People like used to have no idea there were wars going on in the world because where would you find out the news had to tell you. Um now we can tell each other. So like there there are benefits to this but I just I try not to be too skeptical because like I think they're the people that get left behind. If you're only skeptical you're going to completely miss the bandwagon entirely and if the bandwagon takes off well >> that's you. Um, so I do try to use it where it makes sense in my career.
I try to at least encourage people to think critically about what it gives them. Um, stay, you know, as the human in the loop. Don't be the human out of the loop. Um, but yeah, it's it's it's a challenging technology and I think we're only really seeing probably I wouldn't say the early days anymore cuz some of them are about to go public. Um, like SpaceX went public a week ago and I'm pretty sure that means that like Grock is probably going to be in a public setting soon as well.
So, even though Grock is pretty terrible, um, but we know Open, it was just yesterday. >> Yeah. Well, we know Open AI is about to do the same thing. And but that makes me wonder, has the VC money ran out? Are they, you know, running dry now?
So, they need to go and actually make money. Um, cuz I mean, from a social perspective, most people don't understand this, but >> you know, everyone thinks that they're just going to get shares and that's how they make their money and people buy shares. Uh, all of our superanuation funds are going to go and invest in these companies. like there's a lot more sources of income that will just automatically go in their pocket because of this. So like it's going to be an interesting interesting change in in how these companies are ran and their motivations like will they chase customers, will they chase profit, will they chase both?
Um I think you you mentioned it before there's a bit of a war over users at the moment. It's still like getting as many users as possible before they lock you in and in Shify naturally. >> Um so we'll see. But it's it's a bit of a negative outlook, I guess, but but I try to I try to find the positives where I can in the day-to-day sort of uh use cases for it. Yeah.
How about yourself? >> Oh, man. I've been resisting AI for a long time. Even though I use it every day for different things, I I kind of resisted going kind of this more chinting, creating a lot of AI. I don't know why.
Some kind of ego, some kind of maybe fear of replacement, kind of pretending it's not here, it's not happening, like you know, all of that. But I don't know at certain point I was like okay it becoming too good especially from December 25 when the OPOS 4.6 6 dropped everything like changed especially in software development world cuz now it was way better more reliable and stuff like that plus started kind of coming out things like skills like different loops and stuff like that where you can also give a lot more context teach it you don't have to create this rack as we had to before like kind of upload it make this vector databases and like it was like really hard to get into that understand what's going on another thing is to build it like I spend a lot of time just figuring out like okay How do I build a rack? Okay, what is a what the hell is a database with these PG vectors? What it even means? Like I started to understand it.
So over the years I still picked up a lot of theory about how AI works like what of these stuff like that. And I kind of was staying on top of the news. I wasn't just using it to the max because I I don't know. It's hard to explain why subconsciously something something I had resistance to it. I was maybe hoping that it's going to die out.
It's just a hype. It's not because I know that there's like with AI everything is overhyped. >> It's like right now we have this new model mythos whatever it's pronounced >> this new fable 5 model. Yeah. Which is like so dangerous to release.
The public should be scared and stuff like that. They've been hyping for like a month and now like okay yeah fine have it. And it's happening all the time like and you don't know what to believe anymore. This is also like this we we discussed earlier as well about this AI fatigue. We're so tired of all this hype like all these AI apps coming out like this and that.
We just sometimes want just go back to Ravit and just click manual buttons like you know just just to get away pretend it's not there. >> Yeah. >> So yeah, but now I'm embracing it. I'm just I'm just seeing potential understand there's no way around it. The clo code I've been experimenting wildly with that thing.
I think I have like 20 different projects here and there. Not I have a good plan of how to kind of put it more in pyra development and stuff. For now, I'm just kind of pushing the limits. I'm trying to understand like how far can I push it. What are the workflows?
You can spin up this kind of lots of different sub agents. I think my record so far I had like 80 agents, but it burned through every target. I was like, "Oh, no, no, no. That's that's not what I meant. Like, go back and stop it." I mean, I just it did exactly what I asked.
I was like, "Spun out as many agents as you can to analyze my code like more modular." Decided say no more. It just like went on. I'm like, "Okay. I mean it did good some results. I think it just did a lot of things.
I'm like okay is it good? Is I don't know >> it's because you're you li I mean I guess you were trying to refine the context that each of them had to deal with and then help them break down their own thinking and then share it amongst you know themselves. >> Well well there are two things. First of all I'm just trying to see how to absolutely abuse AI to the point where it just goes nuts. The second point I just try to kind of analyze my repo with so every every agent gets a little bit different kind of modules and then analyze analyze it on its own so it doesn't like break the context but it takes a lot more tokens and stuff you burn through quick result you need to know when you need sub agents >> because the thing about like when you start going into the sub agent thing each agent has its own context and you have to kind of think yourself like is it good idea or bad idea cuz if you're working on the same let's say kind of code let's to simplify the same power tool going to spin out different agents for like UI for this for that for that you're going to lose a lot of context how everything works so one agent is much better but if you have like one agent working on your code >> and you want to create a research maybe go for rate API documentation examples and stuff like that that's great for sub agent because then you're not polluting your current context so there's this a lot of things about learning how to navigate the context and stuff like that there's a lot more to AI once you kind of try my goal was just I took like €200 this subscription.
My goal was okay, I need to learn how to max out every single token so I learn how to abuse it. Then later I can reverse back how to actually use it like more efficiently for different things. >> So that's the stage where I am I'm just trying to see how to abuse it to the max here and there just kind of >> sometimes I get a bit too lazy doing that >> because I'm like I I cannot be bothered like looking for the right file just to change this thing. I'm like hey change it. It's like I told you before, I use AI to just write the comments on all my classes there.
I just give it the code and say, "Slap the comments on, please." I might do the like three dashes to create the auto comment, but I say, "Please fill them in." Like, and it [laughter] knows what what it's looking at. It does a pretty good job with it. I give it like a bit of I give them a few examples saying, "This is like a welloc I often don't even do my own comments or think about them. I might read them over just to make sure cuz I'm really again just leaving that breadcrumb trail like I know what my code does. I need to make sure someone else looks at it and knows what it does and eventually that an AI can read this class and know what it does too like cuz it might prefer to just read the XML to get a vague idea and then not even think about the logic that sits under it.
So um yeah it's it's interesting to see like and I I do find myself getting a bit lazy in that in that regard. >> I know what you mean. >> About that I have a question. And do you kind of dive into like creating your own skills, teaching AI how to do certain things? >> Um you mean like trying to actually create like dedicated assistants or um >> not assistance.
So right now if you use something like cloud code and stuff like that, there's a lot of MD files you can provide. >> It's sort of like prompt embedding let's say but it it's a little bit smarter because it doesn't need everything at once. There's like cloud MD which is always read and then there's like a lot of skills which are kind of situational. For example, you ask it to debug, they're going to look, oh, how do I debug? Oh, here's the kind of skill for how given likes to debug.
>> So, sort of like like a like a I guess a shall rack knowledge base that it can draw upon. So, yeah, we do um we do I we use system instructions and generally I provide a few extra resources that the system instruction gets told about and says this is what this resource does. This is what it's for. If you need it, have a look at it. Um and it generally go knows what to do with that stuff pretty well.
Like I've got um separate MDs like you said in the in the the files that it has access to. I have just raw classes, things that it should look at and say, "This is how I put my classes together." Um, generally it picks the right resources very quickly. There is definitely like a some degree of work required to know how to get the best types of system instructions, but I think like some people obsess over them and they think about the system instruction way too long. Like in my opinion, no system instruction should be over like 8,000 characters past that point. It's just way too verbose and you're going to lose context in my experience.
But like that's my personal preference. I don't want it to be a huge instruction that has way too many things depending on how broad you want the scope of your AI system. >> But oh no, you're not wrong with that. Even like entropic in guidelines they say like keep it to I don't remember the exact count but pretty much they say do not bloat these files especially the main ones which are always loaded keep it minimal refine it and stuff like that but the thing is again it's all about refinement because slowly your p you have to kind of teach it again like okay example what I do and I find it really really well when I do a big task I just I have a command to wrap up and pretty much I say like look over our conversation and document kind of notice the patterns, document what worked, and also document what that didn't work cuz the next time it kind of understands like, oh, this thing works, this doesn't work. So, this is how we can approach it.
It kind of >> you just memorize into a markdown that it can throw up on. >> Yeah, pretty much. It's it's nothing fancy. It's just like one step you actually have to do. You can even make a hooks because there are like hooks kind of automatically going to do it for you after like certain like after 10 chats summarize of you know there there are different ways to do it.
But it's a step people have to do. >> Yeah. One thing I guess like I mean I took a little course where it was like a basics course to some degree. It was teaching you about just how LLM's actually work and what's going on behind the scenes. And I was shocked to find out that your whole chat becomes just appended to the next message each time.
So if you're the sort of person just typing in a few words at a time and tell me an answer, tell me an answer, you're basically just throwing the same chat at it every single time. So um I did I did learn that yeah it is important eventually like you can also just break off a chat through a summary into a new chat just to like reset your context to some degree and sort of not carry you know the last >> 500 messages through each time you type a new one. Um it was enlightening to just learn what LLM actually are doing behind the scenes how vectors work like what it's actually how it forms associations between words and some of it made you realize this is a pretty raw it's a pretty raw algorithm like in terms of what it does at its core. um you know it's it's basically guessing its way through it. Um like people think it's magic but it's like no it's just a very you know wellought out graph in principle like what it's dealing with.
So it's pretty interesting to learn about. >> Yeah vector. I mean >> it's still a black black box right it's like everyone says like you also mentioned like we take data put it in black box now it just spits out patterns and stuff like that which we humans cannot even kind of comprehend certain connection it does but sometimes it's just like wow no it's I don't know this AI thing it's terrifying when you start getting deeper and deeper and deeper you start to see so much more potential what it can do >> yeah I mean the scary part just what people will do with it, right? I mean, at the end of the day, it's just a technology. It's what people do with it that makes it do bad things.
So, you know, when you start to see the US military start to look at using it for drone targeting, you're like, bad. Like, you shouldn't be automating those sorts of things and delegating the decision-m process behind this very extreme and, you know, dangerous things to a computer. And that's where you start getting into the whole Skynet freak out sort of stuff where it's like, okay, shouldn't be automated, >> you know, but but it's very positive for some tasks. I mean, medical research, I'm sure there's like incredible applications there. Like, there's got to be some fields where it should just be used cuz it's going to do good things.
And I guess we're in a field in the middle where it's like, yes, you could like destroy your company's codebase overnight if you're not careful, if you're not responsible, but at the same time, you could make your company move so slow if you don't use it. So, it's that interesting middle ground in our industry. But the thing is that this kind of news where like database was destroyed by AI in 8 seconds or something like this. It's >> ridiculous. just such a stuff like what [laughter] >> cuz there was like recently there's one CEO he destroyed the whole database like he destroyed like not just database but the note where database lived on the server in like railways whatever it's called >> bad the physical server >> and he went on ranting wrote a huge blog it went viral blog is written with AI of course because you could see certain patterns there and then in the end of the day you just sit there like okay could you just provide your prompt cuz I'm everyone can agree it's just going to be shitty prompt just said like ah clean the database and it's like >> look at the level of access that AI must have had to systems I mean they set them up for failure if that was how much access they wanted to give that process so it's basically just along with the blog saying I am an idiot like it's like you've got to build safeguards and security into these things and limit the context limit the access to what you want it to be able to like what's your worst case scenario >> like git for example I mean we use git so that we always have backups we always have versions we always have commits we go back a version.
It's okay. So like it's like he probably had no idea how any of that logic works in principle work with code. >> So >> I mean I looked at this >> I looked up the story the conclusion I came it just that he just gave access not to the database not only to the database but to the platform where it's hosted. >> Wow. And based on description, what happened?
It's not just database deleted. It's just on the app. Pretty much he killed his app somehow. But they still had the backup. They restored it because there was like so much >> there was so much hype around the story which didn't make any sense.
I was like, why everyone talking about it? I looked at that. I'm like, okay, yeah, it just happens. But in reality, >> you couldn't even restore it. I'm like, yeah, I'm pretty sure you can restore that.
Like, so it's always funny when the news tells half the story, just the one that people want to see. [gasps] >> Yeah. That's the thing like they they make us scared like oh don't be afraid of AI and I mean I kind of at first I was like oh yeah it makes sense but then I realized like well it's probably bad prompting like you said no guard rails >> and yeah it's usually very rare that something like this happens. >> Some people had their whole inbox also cleared but yeah >> you've almost got to ignore the news these days. Like I mean I don't take much news seriously anymore.
Um, it's sort of one of the good things about AI is it sort of got me off LinkedIn to some degree. Like I don't really go through my feed very much anymore because it's mostly just people posting about AI. So I generally just make posts and interact with the people in the comments. That's my main >> means of going on LinkedIn these days. Occasionally responding to messages that that's it.
So it got me off the feed because the feed is just garbage now basically. I mean I have too many connections. I've got a lot of garbage connections as well unfortunately. So um >> yeah. >> Yeah.
big advice someone if you are going on LinkedIn don't accept all the connections because you're just going to get a garbage feed. >> Yeah, I second that. I mean my feed is very weird because I see a lot of people complaining about stuff but I never see it in my feed. My whole feed is people complaining that uh what is it this kind of post like ravit is not beam for some reason it's still kind of trending. I don't understand like nobody talking about except for the post complaining about it.
Then another post about like AI kind of pretty much half of my feed is people complaining about AI slopes >> instead of so it's either AI slopes or people complaining about AI slopes but in the between there's so little and I started fighting certain people they actually make better content but eventually like I also have so many connection my LinkedIn is a bit cursed >> but most people they don't have like 10,000 connections or something like that so it definitely probably helps. I think it's cursed either way. Once they added the someone's connections connection did something and here it is. That's when it became cursed cuz I'm like I'm not connected with that person. I don't need to see what they're talking about.
But because someone else interacted with them now I see it. So it's like you can't escape you can't escape the swap. Um you can only block all of LinkedIn basically. That's the only the only solution. >> But it was good.
So yeah, >> the thing is that LinkedIn was always the weirdest social network around and there my favorite post is like I just got driving license but then you go on LinkedIn and like I'm so honored and pleased. Thank you everybody. And then there's like this posted praises and I kind of get it like this is just kind of what was cultural of linked in this kind of space that everyone makes fun of LinkedIn always. >> It's a weird platform. >> Yeah.
>> I'm still surprised like this is this kind of the main platform probably for AC because back in the day probably it looked like logical. You create an account, mention where you work, put your all the experience and maybe even got a job later. I don't know if people get jobs for LinkedIn though. Well, occasionally I I've hired people through LinkedIn before, but only because they've approached me in a very professional or or particular way. So like um and don't just reach out to me now, anyone listening to get a job.
[laughter] >> For example, I had I had a graduate reach out to me a week ago and um she was talking about Dynamo mentoring. Um if she's watching, hi. Um and she was very professional, very interested in talking about it. And I looked up her CV and I could see she'd only been working somewhere for 6 months. And she'd hopped around a bit.
And I asked her, "How how's your career going?" She said, "I'm working casually at the moment, looking for full-time work." And I said, "Well, drop your CV." Like, you know, like you you've said the right things. You've presented the right way. Um, and I'd always love someone to work with me that knows Dynamo, too. So, like, um, sometimes it's just those random connections, but I don't think like >> inbox bombing people going, "Hi me, hi me, hi me, interested, interested, that stuff doesn't work." Like none of that works. Like it's just annoying.
Well, yeah, but also I kind of I I think last year I saw my email from like when I was like 17. I read how I wrote emails before and I'm like >> I get it now cuz back then I just wrote like whatever like ah wrote it, send it out. It was something related to university when I was like making application and stuff. In my mind I wrote something like >> decent professional. When I read it it's just garbage.
my LinkedIn messages like just quick messages now better than that email was and I'm like and that made me understand like oh I think many people just don't put too much attention to that they just drop what they just dump whatever and often times it's also through translation because their native language is not English so they just translate it and I see >> certain patterns when people like write me from like um from Arab countries they there's certain patterns they like to include sir and stuff like this and I'm like oh that's translation >> thing yeah Yeah. Yeah. I mean, a big part of it now is we're going to get AI messages, right, from a lot of people, especially from second language, um, English second language or third language because that's just easier than trying to translate something into coherent sentences. So, I I definitely recognize when someone is just sending me AI generated messages instead of talking to me. >> And I understand if English isn't your first language, I understand.
It's it's okay. I'm not coming at you. But it does definitely change the tone of engagement. like you're much less likely to convert into something meaningful if you're just sending a messages. Um yeah, >> also depends.
One thing is translation. You can see it's AI just but the other thing is just like it was a prompt like from scratch like just write me a nice email to something and you're like if someone writes more than like three paragraphs I'm like who does that? Like no one writes three paragraphs and then presses enter so they write like one or two tops and have a conversation. So >> yeah, >> I'm actually guilty of that. I have an issue sometimes.
I just ramble too much. I'm like, but then I sit down and I rewrite it and rewrite it and then I think like I I should have just used AI because like I spend so much time writing like a simple like message email sometimes. I'm like ah should I do it? >> Don't know if I know the person I'll write like a lot more. Like I mean Nicholas from Bimure reached out to me the other day on my thoughts of AI.
I think it said him about you know like 20 paragraphs or something like that um just of my thoughts. But um if I don't know the person it's usually like very informal just quick message here and there. But um yeah, it's interesting to see what that's done. Um I mean I guess um I was curious. So you've been using pirate MCP or how have you been finding that if you're using it?
>> I haven't really gone into that. I understand how it works. Looked at the code to see how the tools created. There's like a little weird kind of syntax. You have to use a synchronous coding a little bit because well apparent because you kind of call the sort of this u route kind of it's constantly kind of listening.
You send it out messages and so on. >> I don't No, I had mixed feeling in the beginning. I was like, well, there is some potential. Then I was like, ah, it's just hype and then now I'm in the middle. There is some it's important thing, but probably not how most people think about it cuz many people think about as AI assistant, and I don't think it's going to work this way for very far.
It's kind of cool thing, but mostly I think you've wrote it somewhere that sometimes just creating schedule manually is faster than asking AI or something like that. you made a post and I'm like yeah it's just such a good just straight like to the point like dude just just right click once and that's done but when you make like thousand and stuff yeah sure >> but because there are custom tools which again you can generate with AI and make sense because they are more stable you can verify and they are going to be predictable eventually >> and [snorts] MCPS it's kind of good maybe to give your boss to poke around the model ask some questions in like non-y way like okay what's what's going on with rooms what's going on here and there but you have to maintain create tools in a very specific way. So I don't know >> one thing where it's really really replaceable is connecting to AI directly creating this kind of bridge between your kind of LLMs and Ravit >> and that's pretty much how it works right I probably in the editing I'm going to drop the post how it looks >> but the thing is that once AI can connect to Ravit you still can kind of control what it can do by giving it tools but one of the things you can also let it execute its own code and I talked to Alexi I'm sorry Alex, I I don't remember how to kind of read your last name, but he shared that he also going to come to podcast to share it and he pretty much took the MCP connected to LLM disabled all the tools and now he uses it for AI to kind of figure out certain things. So AI writes the code, executes it if there's a mistake kind of rewrites it. So created this kind of loop.
This is what everyone talks about when you kind of create this identic workflows. This loop is the most important thing because you can let it run. You can just give it some task, kind of give it some conditions and >> work. Yeah. >> Yeah.
It just kind of keeps working like, oh, error. Okay, I'm going to try something different. Pretty much what we do normally, but we normally exe kind of get the code, put it to the script, execute it, copy the error, and there's this kind of manual loop of you sitting there doing very useless work. And this is the first work that should be automated, but it's not as fancy. Nobody, you know, like and often it's just something that we are like ignoring should be automated.
>> Yeah. I always find it funny watching the um the hype cycle, the words they follow, the trends they follow. Like I remember when tune was a big thing, for example, and now loop is the new thing. They're like, "Oh, I put it on loop and that's how programming works." >> And it's like, and all these people are like, "Loops. Oh my god, loops." And I'm like, "That's like programming day one." Like you got these people just getting they're almost revealing they have no idea how to code basically.
They're like, "Loops are so amazing. You need an exit condition and all this stuff." And it's like duh like like you know like [laughter] the most basic concept in programming. So people are almost exposing the fact that they have no idea how to code. They have no idea what programmatic concepts are because they're following these little trends. And the latest one I agree with what they're saying.
You you put it on a loop. You keep it going. Your exit condition is you worked or you did something. But I'm like that's that's pretty basic. I mean that's just how people work.
It's not like we need a word or something to describe that. And loop is a probably a bad choice of word because it has programmatic implications. And >> yeah, >> so it was funny to watch I guess just the the people reveal themselves when that came out and go wow loops are really important everyone. It's like yes yes they are. >> Yeah.
The thing is that the issue is that it's coming from the very very top because it's pretty much the create right now it's training the creator of clo code himself Boris whatever his last name is >> he has a way to kind of go and kind of hype up as well because well they need to hype it up and he says like oh I don't write any code I just loops loops and this is where it came from there are like a lot of these kind of quotes or something they go like use loops and they're just like loops [laughter] >> loops >> crazy I just it's such a hype circus but I mean that's like the LinkedIn joke too, right? It's like just touch grass, like go go go [snorts] out to reality and, you know, like don't take it so literally, but there definitely is like a hype circus around it. It's fun to watch it though and just sort of have a laugh sometimes and go, "Okay, wow." Like some people are so so abstract in how they understand all this stuff. Um, >> I mean, in AI it's still a big thing because before the issue was the context, the the AI harness improved a lot. This is also the thing like LM model is one thing and when chat GPD came out it was all about you have like the best model and you create your amazing prompts and stuff like that you write the details things but then it's evolving to we need less and less prompting because harness doing a lot of it for us >> because the way it works also because now with all the skills and stuff like that clo and chibt whatever you use probably most people use clo code right now all the skills you create all the information it give all the context It still feeds back to the kind of cloth >> and it kind of understands it and it kind of iterates on top of it and it kind of improves space.
So now millions of people creating amazing systems they inherently also teaching clo how to be better >> and with every release >> Yeah. >> Yeah. And with every release of the model for example somebody can create amazing skills hide it hide the whole AI stack with with the next kind of version of the cloth it might be somehow included in the training itself because well it needs to kind of learn from itself. >> So now it's at the point where because this kind of the idea of loops is that now it's not about prompting it's about goals. You just tell it what you need and why and you still provide certain context.
But now it's at the point where there are certain when we just say loops there's certain things happening in the background how it connects the context and so on that can achieve it. That's why it's a big thing. But yeah, it's again overhyped and using the loops I also didn't like it. I was like I mean like it is a loop. I get it.
It's just short. It's super trendy word as well. So I I understand why they chose it but I see your point as well why it's annoying. Yeah, >> it's funny cuz a lot of this really just is an abstraction of how you delegate things to people in real life. That's how a lot of this AI development seems to be moving.
I mean, we began with the idea of prompting and that's basically just like going up to someone saying do this and then walking away and that's it. That's all you do. You don't check if they got the right tools, if they got the right systems, if you know there's even something they can work with like and now they said, "Okay, you need context." And it's like, "Okay, so that's where you make sure they've got the tools they need. You've got enough context around what the instruction means. And now they're saying you need a harness.
Cool. We have systems. We have company standards like the you know things that tell it how to work and what framework they should be using and drawing upon. And then now it's like okay loops. It's like yes like people generally work iteratively.
It's like we're just sort of abstracting the process of real work I guess in principle. So it's like I don't know what the next step is after that. Probably I'm energetic having a team that where the agents are all aware of each other and they're working together as a team. Like it's like we're just >> it already exists. It already exists.
But I feel like we're going to get the next like, okay, this is the next agent. Now we have loops and we have nested loops or something. You know, there's going to be some sort of like some sort of like new term that they use, but really we're just breaking down delegation in principle. That seems to be the I guess the abstract framework that we're we're emulating in real life. Um, so it's funny to watch it have to everyone has to learn how to work all over again almost.
It's like >> it's like we always joke saying our principles they you know they give very bad instructions so we're safe because they can't tell an AI what to do. Um like that was sort of the joke that I think went around for the first week when AI became a thing. And so when they said oh our clients had to give a specific brief so we're safe cuz clients never give a specific brief. They just give a really fuzzy brief and walk away. Um, so it's like I think we always understood from the start that's what we were doing, but it's like we had to rediscover our own process we already did in real life like light programming.
We just had to abstract it into a system. So it's funny to watch us have to, you know, baby step our way through something that we already knew how to do in real life but just couldn't abstract it to a a coded solution, I guess. Yeah. So >> no, now it becomes more accessible. >> And you also ask what's the next thing recently?
I think like one or two months ago there was like a project on GitHub called auto research made by Andre Karpati I don't know how to pronounce last name but now it's about like giving it goals and let it train itself and I saw how it works. It's pretty good when but it's certain scenario where for example you can take a website and tell AI it should load faster >> right it can look okay it loads this and it's just going to go on this kind of loops and try try try and it's actually going to optimize itself >> it's also going to document everything so eventually it's better better to the point where it cannot make it any better. So that's a really cool thing, but it's certain use cases and you have to kind of set up like certain goals correctly and stuff, but it seems to be really really kind of good thing if implemented well. At least examples that I saw for the websites, I was like, "Oh, that's really cool." Not sure how to apply >> learning I guess. We already have these concepts that mix with AI.
>> Yeah. Yeah. They bring it back. So they just made it so AI pretty much does its own reinforced learning which is great. Super simple.
At least it looked like. All right. I just realized we've been rambling about this. So, yeah. >> Yeah.
I mean, I guess we spoke about a little bit as well, so we can always add that in as well where we spoke about the more philosophical underpinning. >> Yeah. Yeah. Definitely. >> I just now look at the time.
I was like, "Oh we're kind of coming to an end." And we haven't really dived deep into like the C# example, some like pirate versus C# stuff. >> I mean, if anyone wants to see the C# code, I do, it's on my GitHub, so um it's all there if you want to have a look at it. But um I mean happy to talk about the return to Dynamo briefly. I guess that's something people have been quite interested in lately in my journey. >> Yeah, let's go.
It's definitely something interesting thing I I I should have managed it better, but I just treat it like we're just talking and we just carried away. [laughter] >> But um yeah, so I guess for people that aren't aware of, I've sort of roundted myself back to Dynamo lately. Um that I sort of mentioned at the start, but it was an interesting sort of choice I made because I guess I realized that further up you go with coding, you sort of pull the ladder up a little bit as well. And eventually people have no idea what you're doing. They can't learn from you.
And I've always loved that Dynamo is a bit of a bridge into programming. So I said, well, I know C# now. I can go back and do zero- touch node packages which use C#. Um, and then it didn't take me long to realize that working in this way gives you way more access to the core application of Dynamo and let you do some pretty weird things that you can't do on the canvas with nodes typically if you're just using regular out of the box nodes even or Python because you can do things like catch Dynamo as it's loading as an application and hook things onto it and set up your own custom behaviors and data classes and that's um just been a really interesting sort of way to revisit and appreciate I guess the complexity of a program um that sort of taught me how to code >> and in turn I I sort of feel like I have an obligation to keep building on it and help other people find their way through otherwise they're just going to go on one shot stuff in cord and probably never learn how to actually code. So I'm sort of trying to keep that bridge alive um for people.
So, it's been a been an interesting journey just getting back into that >> to appreciate it and go, "Wow, this is actually a pretty sophisticated piece of software." Even though a lot of people say it's slow and clunky and >> Dynamo sucks, use Grasshopper, whatever. Like, you know, I've I've really come to appreciate that it's it's quite a beautiful piece of software under the hood that's running. It's all just an MVVM form, too. The whole thing's running off MVVM. It's pretty amazing model view, view model.
Um, so you have access to the Dynamo View model behind the scenes, and you can do all sorts of weird things with it. But I mean, you know, when you look at the ZAML for WPF, you're like, my god, I can't even imagine what Dynamos looks like. It's like it's pretty pretty complex. Um, >> yeah, it has this 3D previewer behind the canvas and stuff. So, it should be quite advanced.
>> But no, the thing is that most of us started with Dynamo. I still hear people like because I have like the challenge, the community, they still say like, oh, most of them start with Dynamo. Slowly they get to the point. Majority people mention the biggest issue was like deployment, package management, stuff like that. Even though now many also kind of um told like well now I think I know how to handle it at the time it was not the thing because there was an actual issue plus people were not as good as programming and stuff you know in Dynamo we start with like miss half of the concepts like loops because loops not exposed many when I switched to Python and I made very quick jump from Dynamo to this one I kind of missed existence of for loops somehow I only learned about while loops and then I was like well I guess I need to count myself so I was counting when I I was like, "Oh, no way." Jesus.
>> Which is funny because when you get to C, you mostly use what is basically a while loop anyway. So you use like a forerator and that's just add >> basically how you work. So you sort of almost worked in the C# way. Um cuz you can use the for each loop in C which is like the for loop in Python, but it's often easier if you're doing like a zip loop with multiple lists. You would use a for iterator and just iterate the the object.
But um it's funny that you know it seems silly but actually you were going to a more you know logical >> yeah I know >> cuz there is like all this for me I'm still amazed that people like in C++ they have to also manage memory one thing is like I used to complain about type heating in C and this and that putting the semicolons but when I heard about C++ memory management I'm like >> oh I was so stupid like this is this is like the bigger issue not issue but complexity, right? But that's how you get >> I learned C just like C with nothing after it for a while and Maloc and D alloc and pointers like memory and pointers. Oh my god, like it was like such an eye opener. Like a list behind the scenes, a list is doing so much work in in the computer like it's a list is basically a bunch of what we call strcts in C. I'll just go a little bit in depth here, but like and basically the strruct has a how you go back, how you go forward and what's in the thing and then it points to another place in the computer.
The computer finds out and dynamically allocates places to put things and they're not next to each other. They're all just at random spots where they fit. So arrays occur in a in a set. They're a fixed point in memory whereas lists are literally just linked together to point places in memory. Um, and like they forced you to build blink lists in the C course that I did.
And oh, every time I use a list now, I'm so appreciative for what's happening under the hood cuz I'm like, wow, okay, there's a lot of work going on here. >> Um, if you add an object to a list, like computationally, that that is quite a bit of work. >> Um, like you you learn about sorting methods, what's happening behind the scenes when you sort, how you index things, it has to go from the start of the list sometimes depending on the structure type. So you you you definitely pick up a lot of appreciation if you ever go down to these level languages cuz there's a lot of work under the hood that we're just benefiting from. >> You went really deep.
I didn't go that deep, but I can throw in a good analogy. If people going to think about their RAM memory sticks as a huge parking lot >> and cars parking as a kind of memory allocation, let's say like you say like each item in the list is a something located somewhere. So it's like it's parked somewhere in the parking lot >> and then your actual list is just kind of maybe let's say a paper saying like okay red car blue car and something like that but it points to the specific place on the parking place where this car is actually located. That's a good analogy for me to break down all this kind of memory management >> and then appreciating if you need to find out where the 20th car is, you got to go to the first 19 cars and get pointed around to find the 20th car. So >> yeah, obviously all this sorting it's a good analogy.
I don't know. It just randomly came up in one of tutorials because you know there's like when you print stuff in Revit API it gives you this kind of memory allocation hash >> which doesn't make any sense like I don't know why it's even printed >> but I know that beginners like look at that and like this must be important. I try to always tell like okay it's just a memory staff. I just once explained it and with a parking lot and it made so much more sense to me than probably to people who I was explaining it to and I was like oh I'm keeping that analogy it made sense to me finally. So I kind of explained it to myself.
>> Yeah. And I guess there is that that challenge that if you don't learn those really fundamental concepts, you often don't know how to communicate with the computer. So like when you get given a hex code, it's like unless you know what a hex code looks like, you don't know what what it's telling you. But actually that thing's just basically like a warning code that has like something you can go check somewhere else based on the hex. Um cuz the course I did it taught you you've got binary asy hex and then you finally get to like you know more friendly data type storage like pointers and things like that.
And um so sometimes when you get those weird like xxo664 or whatever sometimes they're pointing to like ASI references I think or something like that I forget it's been a while but they're basically like the most efficient way you can put this thing in a memory aspect. So like that's why it looks so weird sometimes because it's just a memory a memory address or something like that. >> Yeah it's pretty pretty abstract. Um I guess like yeah if you start too high up in the abstraction chain you sort of miss the opportunity to get to the more complex development pathways. I mean maybe AI is just going to write all the code in future but there's so much dependency underneath all this stuff and someone's probably going to need to know how to fix it at some point like assembly >> you know about assembly I assume or assembly is like the first programming language.
>> So assembly >> you mean about language? Okay. Yeah. I know. I thought >> bits how to turn themselves on and off and it's like just a guy moving around flicking switches basically with instructions and that's how like your compiled code gets broken down into instructions for the bits in the computer and it's like someone out there has to know how to do that because if this thing breaks one day like I don't think AI is going to know how to fix assembly.
Like that's a a pretty raw um you know literal language and like I don't know many people that can do assembly. Um, a lot of the old programmers did learn assembly back in the day, um, when C was still like more of an emerging sort of concept, but it's it's pretty amazing just how fast we move away from the core of what's happening at the bottom of the computer. And I do wonder how like how long AI can, you know, keep us abstracted away from it before we need to come back to it. Yeah. >> Yeah.
>> Bit of a deep conversation there. Sorry. >> Yeah. Yeah. We went a little bit deep.
Now I'm thinking that maybe I should have prepared a little better structure. I mean, I have a structure here, but we're just talking and it's nice. So, [laughter] I thought like, yeah, let it run. >> Enjoyable. Yeah.
I mean, I'm sure if anyone's still here in the chat, but hopefully you've enjoyed um enjoyed our viewings. >> Yeah. Uh unfortunately, we would have to wrap up. I would have to go soon. >> But it was so nice talking to you.
Like there is always so many different topics we can dive into there. I think we should have just fixed something because uh you sent me like a really kind of we can talk about one of those things like I also throw in and stuff and now I look at it. There are like MCPs, AI, there's like C power dynamo like what packages you manage, what kind of stuff I do with on my my end there's like so many topics and I realize now like I knew that we're not going to cover all of them but now I understand like maybe I should have made a bit >> structure. Probably in future I'd love to come on and um maybe show like a C# project for an addin and start to explain how you can break them down and probably the commonalities between how you build and how Revit and sort of talk about those. Yeah, that's what I kind of wanted for this episode.
>> It's just we never got there. I just very lately realized how little time and I already knew that there's not going to be enough time to dive into that. >> But now Yeah. Well, it is what it is, right? I I like to keep this podcast casual.
It was pretty much us just chatting whatever comes to our mind. That what happened. >> No, I really enjoyed it. Um it's it's it's important for people like us to keep talking to each other because the moment that we lock our thoughts away on our own is where we get really biased, right? Like it's important for us to ground ourselves and talk to each other and make sure that we all >> understand what's going on in the industry and have people that can challenge our opinions and go, "Oh, I don't know about that.
Maybe this is it." So like anyone out there like this is really important to do this sort of thing, especially in coding and development where you can code yourself into corners and all sorts of things like that. Yeah. >> Yeah. the great work you're doing too by the way like some of the work you're doing with like your websites and like the form builders like that's amazing like you're you're doing some really hardcore stuff there so like it's pretty impressive um yeah >> thank you appreciate it but you just described pretty much why I decided to kind of bring back this power rate podcast because once I start talking to different people like all the different experts for example had John who came in he said like well I learned rate API power this is how I use aentic now I talked to David was really like savvy pirate developer is like I'm not using AI as much to you as well. So it really helps me see so many perspectives because I can talk to one person then I'm like for example if I would only talk to you right now and this then I would just this would be like one of the kind of the only external opinions for me and it would also shape my own opinions but now when I start talking to multiple people from different like levels like including experts people who kind of kind of maybe not as kind of far down the journey it helps me understand and see different perspectives so now I'm doubling down on this life not live But well, we're kind of live.
But anyway, like talking to you and also to my audience as well, it helps me see so many perspectives that I start to appreciate. I'm like, "Oh, you actually at certain point I think like okay, AI is taking over." Then I talk to people and people they see the same complaints like people ship like with AI not robust tools. They don't understand code. They run too fast. Like they don't have time to really understand what's going on.
But then they kind of slow down take it kind of understand some things then it helps them use AI better and stuff like that. So, it really helps me, as you said, like stay in the loop, see what's going on. >> In the loop. There you go. Loop.
>> Loop. [laughter] Loop. >> We're looping. >> Yeah. No, it's good.
It keeps us grounded, right? It's It's like touching grass to some degree. Um, just >> Exactly. an Yeah. Yeah.
Yeah. >> No. Yeah. I definitely need to bring you back actually dive into C# code to see because my biggest plan was like take like a little pyate code turn it into C# live so people see all this compiling thing how to use the template that you mentioned this free point 3D point whatever it was >> yeah so that >> we probably build some structure around that could be quite a complex demo but um yeah we're happy to work with you and we can figure something out behind the scenes of how that might might play out >> oh we got a question there we go someone's here you good >> oh yeah almost surprised like so Yeah. Hello.
I think I can put it somehow on the screen. Well, it covers everything, but anyway. Hello, Erik and G. Nice podcast. I need some help please unveiling clash tool detector and pirate.
I want highlight the clash and linked elements and the active 3D view. Is there any way to override color of single linked element? Well, that's a very technical question out of nowhere. [laughter] Um, so yeah, can you override colors of linked elements? >> I forget if you can.
I don't know if the API exposes that capability. I think it was only for native elements last I checked. >> There's a lot of limitations with accessing linked elements like you can't cast a filtered element like over a link document. You have to access in more abstract ways. But >> I'm not sure if you can.
Um >> so in my mind to overwrite element you need element ID but element ID bound to projects and when we reference another elements from another project usually we use reference. So there's also linked ravit. >> No, actually there is a >> you can get element ids from linked elements but I think it's the override um the override method which is um there's a the view based method. So if it's view override element in view I think in the >> um I seem to recall that that one was limited. >> Um >> okay there is a class link element ID.
Maybe that might work. >> Yeah that's >> and it's created with a element ID. So yeah, you would have to dive in and see there. I haven't tried it myself. Logically, it should be possible.
>> Yeah, I've researched it and I think there were limitations. Um, as an absolute workound, it's not a great workound. You could run in the link document and um like add a filterable property and use the filter on the link. That's like a really long workound. Um, if you do need to see it, but you wouldn't be able to dynamically do it because you'd need the link document to be active to populate that property and then back in the host model with the link.
So, it's not really like a live workflow. Um, as an alternative, I guess you're saying you want to highlight the elements. You could also look at section boxing around the elements and then selecting them. I think you can select linked elements using the API. That might be one way to sort of draw focus to the object.
Um, and there's also a method for moving to the elements in the view as well. I think it's show objects on UI document. um that will focus you to the position of the element and then you can cast a section box after that because if you do a section box first it won't be able to find the element because the section box excludes it can't see it can't move to it. So the UI document show documents show objects um at least gets you to the position >> and then section box select might potentially work as an alternative UI UX >> but yeah that's a very kind of technical specific things you just need to go in and try different things. Yeah, I mean that's often the Revit API, right?
There's often something can't do it. Okay, what's the next best non crappy way of doing it? Like you have to find those workarounds. Like a really funny one, speaking of links that I know people have done in the past, um you can actually start exporting a link in IFC to get the elements visible in a view and figure out which linked elements are in a view instead of using a FilteredElementCollector that can't target linked elements. So like one developer I know started background exporting an IFC grabbed the ids from memory and said these are the element IDs and the link I can see and then put them back into Revit API and said get the elements with these IDs in these documents to do a linked element collector.
So sometimes you have to take really long workarounds around the API where it's got gaps. So this might be one of those cases maybe. Yeah, >> right now Mateo is just like [laughter] >> so. >> Anyway, unfortunately we have to wrap up here. I really we should plan even more.
I even specifically booked more time with you. We even started before we invited audience. >> Never never enough time. >> Anyway, it was real pleasure talking to you Gavin. Um if you want to throw in any links, well anyway, I'm going to leave whatever you want in description.
all the kind of projects you mentioned like C Dynamo zero touch notes and stuff I have links I'm going to drop it there as well >> if you want to just looking at it important clarification you will need to look at my whip branch so I did I used to work in main as we call it in GitHub and that's a bit of a sin like you're not meant to work in main you're meant to work in branches then commit to main um with pull requests um I've just started working in whip branches so you won't see the latest code on the main branch generally you'll see it in a whip branch um until I commit it as a version So I am actually using GitHub properly now. Um because I actually have a developer I can work with at work now. So I'm not working in main anymore. [laughter] >> Um so if you do go to those links you may not see the latest code on the main branch. That's the main clarification.
>> Just exposed a very bad habit of mine. I used to have too. So [laughter] >> I'm really sorry everybody. We have to wrap up. I didn't plan enough time for today.
>> But yeah, it was a real pleasure talking to you as always. There are just too many topics we can explore and it's always we we go always deeper than probably for the podcast than we should. But hey, >> we'll pick one and deep dive it next time I think will be the easy way. But um I really enjoyed having a broad discussion with you and finding out where you're at with all these things as well. >> We haven't spoken in a while.
So it was nice to dive in, see where we at. I think this podcast was most mostly for us to talk to each other than for the audience. But today we get to kind of ease drop, see what's happening. >> Thanks for watching everyone that did tune in as well. We appreciate you um taking the interest in what we're up to and um thanks to appreciate it.
>> Yeah, thank you everybody and as always if any questions or guest requests just comments below other than that happy coding as always. >> Before you've been just completely all white like like a t-shirt your face was like all the same. I was like okay when I mean I've got like a two two-tone tan. I've got like white and then tan cuz my arms are always on the desk in the sun. So, >> how's that possible?
I thought in Australia you all always walking around. >> Not the gamers and the nerds. Yeah, we still stay inside quite a lot. [laughter] >> Yeah. Yeah.
True. Like Sharp is not going to learn itself. >> Yeah, exactly. It's been It's been fun to start to sort of control software a little bit more and feel like I've sort of got a bit more agency and what I can make programs do. Um, that's why I sort of came back to Dynamo because I realized there was this huge underpinning core of Dynamo that you can basically muck around with.
Um, so I'm getting it to start to store like data into graphs directly so that you can like give a graph to someone that's already got like initialized drop downs built into it that you've sort of tailored on on the canvas and said these are like the list of things I want you to be able to pick from and yeah, it's very very you can do with it and you can store like anything in the graph basically. Um, I mean it's all >> Yeah, I I saw you started getting into like this like started like VPF form, storing data, stuff like that. So you you're about to break down >> VPF and all sorts of weird stuff. So um and there's just like a huge gap in the package um developer community right now because they've sort of lost a lot of their big developers over the years and John Pearson works with Autodesk now so I think that sort of slows down what he can do with rhythm. So there's definitely like a bit of an opening >> in the community to sort of create like the mega package that can sort of bring everyone back and you know get them to get more out of Dynamo.
So >> happy to be own the mega package in future. Yeah, >> I didn't see it coming. It's literally you made a full loop like Dynamo Pirates C and like you know what let's start let's go back to the beginning. Yeah, I guess I see it as a huge like it's a great entry point still for like people to just understand code cuz I'm really worried that like people want to we can definitely talk about this in more depth too um as we go. They're just missing that entry point to code where you sort of have to figure out why you want to do code.
>> Um you have to have that little moment where something works that you've built and you're like yeah it works but like now it's like oh AI gave me a thing and I hit run and it worked. It's like it's not the same discovery journey. Yeah. >> Yeah. I know.
Everything is so fast is like people start coding. I occasionally talk to people like I I don't understand how loops work but here's like 20 tools I made and I'm like I mean that works and I start doubting like questioning myself like should I even teach this thing like if people do that but then I have other site where people actually like to kind of get into this manual stuff and they actually >> say like they finally get what's going on and stuff like so give them clarity then it's completely different >> game because I guess I find myself wondering if I'm gatekeeping when I you know get in the way of AI based approaches. Maybe I'm being a gatekeeper to some degree. Like because I guess like I learned through visual programming and a lot of coders at the time would be like that's not real programming. You're skipping steps.
You're, you know, you don't learn how to debug properly. And I'm sort of saying the same thing now to AI developers. And it's like to some degree I have to sly check myself and make sure I'm not just being a gatekeeper. But I look at the way they're learning and I'm like I don't know at what point of that journey they will learn to debug for example. Like will they just never learn to debug [snorts] sometimes?
>> Yeah. Yeah. debugging is like this is why >> I start to feel like we already started the podcast before the audience came. They're going to come with you guys when we finished. [laughter] >> Yeah.
It's what I was going to say. We're getting too excited we're already jumping in. >> Yeah. Yeah. >> I mean, when we talk about Dynamo, I'd be keen to show very briefly like the level of um customization you get available to you.
Like you can literally like get the nodes and the wires and all the things in Dynamo like reflected back to you. And it's pretty insane just like the depth of what you can customize when you sort of learn like the ins and outs. Um I'm still only really just learning it, but I'm getting nodes to start telling me like their nicknames so that they can index like custom drop downs in the graph like the graphs themselves and do all sorts of wacky stuff like that. So >> trying to build likeable scalable sort of hacky infrastructure. Yeah.
>> Have you tried Grasshopper? Because their customization I think is insane. Yeah, Grasshopper's big. Um, the only problem with Grasshopper is like they're so focused on Grasshopper 2 now and it's unclear like how long that's going to take and I think everyone's a bit like worried that if they put too much work into Grasshopper now, it's like it's going to get undone when Grasshopper 2 becomes the official standard. So, it's in a bit of a funny little holding pattern at the moment.
Um, but it's a great piece of software. I use it like almost daily at work. Um, mainly for just computational analysis and um, sort of like advanced form finding. >> Yeah. >> Yeah.
It's >> Yeah, you're a everything. It's cool. >> Yeah. Yeah, I try to. Yeah.
I mean, pretty much anything in Rhino and Revit, like I've got my hands on at some point. Um, I've still got to get more into Blender. That's probably the next program I want to crack open because I've played around a little bit with like Spurs Shock and a bit of that stuff, but it's just it's very hacky. It's very, you know, I don't know if an average user is going to be able to use it, but yeah. >> Yeah.
I wanted to get in Blender for a long time, but then I was like, I know I can find time for anything. Like, there are so many things. I'm just like trying to my issue is like I need to learn how to focus cuz even right now I focus on like new training this training then documentation this build. >> Yeah. >> Sorry I have too many things going parallel and I'm like I need to I need to like step back.
Sometimes I almost wish I wasn't like in tech so I could just ignore all this stuff like everyone else gets to like like so many architects get to completely ignore tech entirely and just like their job doesn't change for like 20 years and it's like I don't know what that like to >> Yeah. I have friends who just discovered image generation. >> Yes. >> And I'm like oh so you're like two years behind. Well wait until you find out what we can do now.
>> Yeah. Another thing we can talk about too. I mean like so many people I talk to don't even really care about AI. Like I think it's really overexaggerated like how I guess like this is just going to change everyone's lives and I'm like I don't know like I think the average person I talk to just doesn't care and they're like I don't know they'll figure out how to send it to me later like the internet and then I'll care about it but until then you can just go muck around with it. It's a tech thing and you want >> yeah there is this fatigue like AI fatigue every week like the best model this that new application you never seen.
It's like and everyone's like, "Oh, come on. Just let me let me load my AutoCAD for fun." [laughter] You know, it gets ridiculous how like everything is overhyped. Now there's this new model Fable 5 and they did it before the IPO or something and like oh my god. And this one is crazy as well. >> Oh yeah.
I've been having a look at it. It's quite powerful. But um it uses like a lot of tokens compared to the old models. That's >> Yeah. Like you pay for it, that's for sure.
But um I guess it's the whole nuking the antill thing that I always keep hearing people say. It's like don't nuke the antill. So it's like Fable 5 shouldn't be used for like everyday basic stuff. It's like you really need an advanced agentic workflow that justifies like using such an intense model. But um >> yeah, I saw a really good meme.
There's like a guy took a gun, put his brush on it, and when you kind of click, you know, it's like kind of kickbacks. He was like brushing. He said and there was like caption like when you use Fable 5 for renaming files. It's like the perfect representation. >> Yeah.
I mean eventually they are going to have to figure out how to package this stuff up in a very simple way. That's the interesting part about AI. Like I think they've they've almost like got in this weird narrative where they assume like everyone's like a programmer and everyone thinks like a programmer and we're all like really great at reading the docs and doing all these things that programmers do. But it's like the the average person doesn't do any of that. Like they just say, "Give me a product.
It should just work off the shelf. Let's go." And I think like they've they've lost a bit of they've oversighted it, I think, in created such a myriad of models and complexities and APIs and the average person just wants Google. Like they're just going to want something really simple. I mean it it kind of I think it's oversimplified already because you can't tell tell it like oh make me a clone of this app or that app and it's like sure here we go. But some people still going to be trying to share local host to their friends and wonder why it doesn't work.
>> You're going to need to combat like a wide variety of skill sets and um right down to like your grandma all the way up to like you know the most complex you know programmers in the world. Like I just I mean I show like even like chat GBT to like my family cuz they barely use it like most of them aren't anywhere close to tech and they don't even realize you can attach files to it and things like that. It's like that the UI UX is going to be such a big challenge for them to navigate to make sure that this thing feels like anyone can use it. Like it's not too complex. It's not too techy.
Like even where I work, we have people that are just like AI is for the tech people and I'm like I don't know about that. Like you might want to rethink that. I think it's meant to be for like all of you. Um so like it's just perception of software versus like it's a something so ubiquitous like the internet that you should just all use it eventually. >> Yeah, >> I think the tech people they well they know what kind of to do that with that.
So they are the most excited but at the same time they are the most terrified right now because they understand what actually is happening. They're like oh it can do that now. This is it's great but at the same time it's terrifying. start I see here and there certain projects and I'm like if that's if that's now it looks a little bit shitty here and there but give it two years it's going to be perfect like pixel perfect and I'm like oh >> you you YouTube is going to have a big struggle in like the next couple of years >> just saw a video a guy just he has set up certain things he's like in full automations and stuff just like okay make me YouTube video pretty much that's it left to the gym came back there's like full video with his avatar his voice full-blown video animations based on what he's talking about. It's very very >> You can still see artifacts.
>> They're fairly clear, but still you see it's like 90% there. And I'm like, "Holy shit." >> But I think that's going to lead to like a revisitation of the type of concept, the type of content people accept. Like I think people are eventually going to realize like they're watching an AI format. Like if you're ever watching a video that changes every 4 to 5 seconds, that's AI because they can't hold like video context long enough to keep a scene going for over about 5 to 10 seconds before you start to notice weird things going on in my experience. So you'll notice they change scenes like very frequently.
Um or they never have a person on the screen that's talking because you'll realize the audio just is uncanny valley compared to the person talking that's like still quite obvious I find. So like there just like >> but that's what I'm talking about. There's like five minute full-blown video, the guy on the screen. There are like animations where he kind of becomes smaller and bigger, but it's close. It's We're almost there.
>> It'll get there. It'll definitely get there. >> But then I think we're going to see a bit of a resistance, especially from younger generations where they're actually going to seek out content that can be provably not AI generated. They're actually going to reject it to some degree. Like you might have seen the um university speech with Ronnie Chang.
Um I think it was a week or two ago and he just started it off by saying like FAI like screw it. like let's let's let's beat it. Like we don't need this. And like everyone in the audience was cheering and it was like a whole university of students that just don't they don't want it. And I was like there's gonna be a big resistance to this.
I think especially in the younger generations where there's no jobs anymore for them because of this. So >> it's like how do you sell it to like the next generation of consumers? >> Yeah. I mean I don't know. The thing is that I also resisted AI for so long.
But now I'm at the point where like I cannot resist it. like I actually need to show people how to use it because there's like so much you can do. >> You can't avoid it. But it's just like knowing I guess it's how you use it though. It's like are we being you know socially conscious?
Are we being um responsible in our professional obligations? That's that's more the bigger picture with AI use. I think it's like you can't be like reckless in how you use it, right? Like that's that's >> um and I think we use it but we're being careful with the ways we use it. Yeah.
>> Yeah. Yeah. Also, I think there is like this thing like, you know, we spend years learning this craft from like Stack Overflow, Google, the hard way. We learned it and now we kind of trying still hold on to the skills and kind of >> I don't know. I noticed that internally it's not it's something subconsciously like I I try to pretend like AI maybe not as good.
You still kind of need to get deeper into that and you still kind of have to understand like the basics and stuff so you can even take the full advantage of that to understand what's going on. But at some point I was like, am I resisting it because I'm kind of afraid of it that it's replacing what I learned so hard or is it just you, you know, there's some weird internal >> dialogue happening. I can't really explain it. Well, >> to some degree there is I think yeah, that that aspect of it's not quite denial. It's >> maybe just um I mean some of it's probably jealousy that we had to do all that those hard yard [snorts] like oh god.
>> It's like these lucky kids that don't have to do it. But then it's like in skipping that, do you miss out on that core, you know, um, mindset that helps you be a better programmer? It's like, is that possible to still have if you skip the steps and jump all the way to like writing a problem, get some stuff back, do you think like a programmer anymore? Can you take a business problem and convert it into a piece of software anymore mentally? Because for me, like I when I go through prototyping and briefing with like the the people in my company, there's still like a pretty intrinsic skill set that's mentally like built into how I think and approach it that I don't think I'd have if I hadn't went through all of that.
And I'll be curious to see what the younger developers look like in in our industry in particular, how they approach problems versus before they even code. Um, but you wouldn't begin with a prompt, you begin with a question to a person. like it's like that process is so important to building something that's useful in business. So I wonder if that's going to be intrinsically missing from from that generation until they sort of realize how to you know get born in the fire and the baptism of fire of you know learning those skills through failure at a business level. >> I see.
>> Yeah, it'll be interesting. But um I know what you mean. [clears throat] There is that >> that weird feeling of like you know am I am I the old guy now? Am I the you know >> Oh yeah. [laughter] Oh yeah.
Yeah. kids are going to come and take my job and no one cares about my addins anymore. It's it's it's a funny phenomenon, but um but we'll see. I guess I think some >> it also happens subconsciously. >> Yeah, >> cuz the thing is that it's not something like I really think like I'm not going to talk about it because I it's just like it kind of you just become biased.
That that that's it. I think >> I think we all carry our biases no matter what we do. It's hard to avoid. >> Yeah. Yeah.
Of course. So um yeah, >> but the thing about also intelligence and what you're talking about is that they are now starting kind of pivot to the point where prompting is not does not matter as much. For example, for Fable 5, they now like release that the less you give it the better actually because then it can figure out all the steps for you instead of you explaining make me all these steps and then it kind of have to follow even though it's super good at ignoring you. That's also something they focused a lot. They going to take your prompt.
they're going to ignore half of what you're asking. They still going to deliver kind of what you asked, but they're going to come to that kind of themselves because they realize like uh in the beginning there was like all the super prompters writing this kind of huge like 40 pages docs just to drop it in ChatGPT. Now AI does it kind of internally behind the scenes. You don't even need to worry about it. >> That's also quite scary because now some people just okay make me Minecraft.
Literally that's the prompt. It it does it >> and you look at it. It does it. works. >> But what if you say like maybe something no one's ever seen before.
It's like what would you get out? That's >> the That's the thing. >> It's like sure there's a million pictures of Minecraft. There's all these code repos people have written already. I'm sure it's got a lot to draw upon.
The interesting >> Yeah. There are probably on GitHub like hundred kind of replicas of Minecraft. So it knows like ah just going to copy this repo. Bada boom. >> Yeah.
And it just builds some crappy 3D Node.js thing that doesn't app instancing or multiplayer or anything. So, like it'll be interesting to see how it deals with the I guess the creative requirements that I think people are eventually going to want AI to have where it's like don't just make something derivative like make me something new, work with me and don't just go and pull on something that you fall back on um that exists already. And I think that'll be interesting. That's where I guess AI teaching AI that's going to sort of have to somehow figure itself out to >> get ahead of some degree and say, well, if you left someone in a room for 100 years, what would you get? Well, now we can put an AI in a box for a minute.
You know, that that might be the simulation. Um, so like I think that's the endgame for AI. How can we get it to be creatively so derivative but so creative that it creates basically new things out of derivation that the things that you wouldn't combine in such a way before that create new ideas. That's >> that to me is the end game and the really exciting point with AI. If it gets to that point, I think I'll be quite excited by like, okay, now it is literally just like creative.
Um, but right now it seems Yeah. very derivative. >> Yeah. >> Yeah. There are ways to kind of hack through, but still it's derivative even though you not just kind of copy copy pasting.
You're more like stealing like patterns like you take you can take a website and take the patterns like for example I'm doing this stress testing. I have like actually prepared we're going to go through this. I have like eight different examples in Star Wars, Harry Potter or Mario, Minecraft styles and they look very similar but >> just a bit more fun. >> Yeah. It it forces us to confront the fact that we as humans are we are creative but usually our c creativity has come from some combination of derivation of ideas like it's very hard to say this thing is entirely unique and it's never been done before and I didn't get influenced by any external forces to make this idea like subtly and subconsciously we probably built this creative thing out of things we already know or have seen or been influenced by um obviously someone at some point had to discover fire and those sorts of things where it's like accidental creativity, but like eventually you're playing with building blocks of things that exist.
So like I don't want to say that AI can't be creative derivatively cuz I think a lot of us are um naturally we just don't think about it that way. >> Um but yeah, just to the point where it's so creative that you you you don't even know where it's pulling stuff from. It's just creating something that seems so new to us that you know we would have eventually built it if we sat in a room long enough. But like that that will be I think the exciting point for me where I'm like okay this is going to [clears throat] take my job because >> it can be creative like yeah >> yeah I mean at times I feel like it's creative but then when you see it for the first time you're like oh this landing page is super creative but when you used it for like mom's doing this thing I'm like I start seeing the same patterns everywhere other people websites I'm like that's clo that's 100% cloth this is not even like Gemini it's like I know I know this Yeah. And that's about the change of like almost like model collapse to some degree.
It's not completely model collapse, but it's just like creativity collapse where they do start falling back on their own inherent patterns like we as people do. Like it's like is there a risk that eventually they do become like so strict as a personality of a model that it's like it just has a thing where it's like this is what I'm going to do. You know, I'm going to do it. It's what I'm going to do. And that's the point where it's like, has AI sort of lost its cell at that point because now you're just working with like an intern again and it's not really like you're working with a, you know, creative graphic designer, you're working with someone that just looks at someone else's thing and that's it.
It's done. Um, so it'll be interesting in version how they can get past those sort of natural learning patterns that they sort of pick up over time. >> Mhm. >> Very philosophical, but yeah. >> Yeah.
Yeah. There are like so many. You cannot predict anything. Uh listen, I'm going to interrupt you. Just need to send out an email and we need to figure out if anyone is here.
>> Hello. Okay, some people joining. Um okay guys, if there is people here, we're just going to continue talking. We might use the chat somewhere. In the end, we're definitely going to ask you if you have any questions.
For now, I guess we're just going to continue as we've been talking before because we're already kind of doing the podcast for the like 15 20 minutes. [laughter] We couldn't hold it. So, where do we begin now? Yeah, it just breaks the flow, isn't it? >> That's good.
Let's start fresh. Um, just recap um yeah, what we're here for and um sort of set the tone for the podcast and then we can go from there. >> Uh lately, I becoming like more and more lazy with these intros before I was like preparing, making some little script and less and less. Then I was like, "Okay guys, here's uh podcast number nine, something like this, and then we just roll in." I think it's just going to I'm just going to do some kind of intro afterwards. It's just going to be more natural >> cuz also it's always so weird make this intros.
I just look in the screen, pretend you're not there and I'm talking and you just sit there like, "Oh, he's done." >> Informal. Informal definitely to me as well. Yeah. [laughter] >> Yeah. So, whatever.
Like, I'm going to figure out I'm going to edit it anyway. Some people will see this. That's fine.
### A 20-Year Revit Veteran on Revit, pyRevit & AI | pyRevit Podcast #8
https://learnrevitapi.com/podcast/py-pod-08-revit-veteran/
Tay Otman, senior project architect in San Francisco with 20 years in Revit, on his path from Revit specialist to pyRevit, Revit API and AI. Podcast #8.
## Transcript
Today I have Tay Otman on the show and just gonna talk about many things related to parade raid API and his journey. So welcome on the pot t. How are you doing? >> Thanks for having me Erik. How are you?
>> I'm good. And you? >> Uh better than what I deserve. Uh >> they framey vibes. >> Yes.
>> Perfect. Uh all right. Hey, could you introduce yourself to my audience? What do you do and well what we should know about you? >> Yeah.
Um uh so I am um an architect, a senior project architect right now in uh working in San Francisco um California. Uh and I'm originally from Iraq. I moved to the United States in 2010. But actually I started with the Revit uh much earlier. So I graduated uh architecture degree over there and I moved to the United States 2010 again.
And then I because of Revit I think that time uh 2010 was the bottom uh the rock bottom of the financial crisis that you know hit the United States >> and when I moved actually to to California it was I couldn't see a single crane. There's like the construction industry for two years were were stagnant. >> Uh and um it was like if you go and search for job openings there's none for architects pretty much that time. Um so um stumbled on an opening for a Revit specialist. >> At that time it's actually when I moved to the United States 20 days later I got the uh Revit certified professional for Revit 2010.
>> Nice. >> And uh that helped me actually getting a job with a very big company uh probably a lot of architects know it's Gendler. And I worked there for 5 years and then I uh worked locally in a company for nine years after that called dees. And now I'm with Boulder Associates doing healthcare architecture, medical office buildings, uh, hospitals, clinics, imaging, um, surgery centers, all of that. And then active on the pyrovate community.
Now, from the background, you can tell me I'm u tell you that I'm actually relatively new to the Revit API world. Uh, I started with Dynamo maybe 10 years ago, but with BIM, I'm 20 plus years. I started with Revit in 25 2005. >> Oh, that's such a long journey but uh so much to unpack here. So, first of all, when you kind of got your job here uh not here but in United States.
Uh how good were you at Revit already? You mentioned you got certification but >> but you were already very solid at Revit, right? >> Yeah. Um I was really solid at Revit. My biggest challenge was switching from metric to imperial system.
That was the probably the hard part. Yeah. >> Um, >> oh, I can't imagine it. >> Um, I'm working with uh with my team member now and he has like a converter. He's from India and he has a converter between I told him like forget about it.
Just reframe your mind around imperial system. It's not perfect. It's probably a step backward for humanity but you know you need to keep going and you know the only good thing about um imperial system it matches the Revit internal uh unit. >> Yeah, probably it ends here, right? I always looked at the metric like I have no idea what's going on.
I kind of get it now because I saw it way too often, but I'm like I don't want to touch it. >> That's where um I'm actually so um I worked it's it's potentially vibe coded for WPF, but um I'm planning to have one uh calculator uh it's probably a part of the extension >> that's actually you can do uh metric and imperial uh calculations uh like mathematical operations at the same time. So you can have uh a 2 m wall plus 5/8 of an inch for the jipboard >> and it will give you the total and you can pick which unit you want the output in. >> Yeah, might might help some people for sure. >> To unify the world together.
>> Yeah, that's the goal of py in general I guess >> especially um I want to go talk about politics but uh we better you know the United States needs to be better you know to our European friends uh and it's not happening recently. So my goal is to fix it. >> I see. We start with calculator then politics. >> Anyway, um let's get jump back to Ravit.
So 2006 it was such early Ravit experience. Yeah, even five. Like what was Ravit back then? Cuz I joined way way later decade later. >> So uh I want to say Revit was such a great tool >> by then.
>> Yeah. The only difference is there is no ribbon. So I started with Revit 7 and uh it's called Revit 7. At that time it wasn't included. I think at that time Autodesk didn't unify uh the numbering of the versions and at that time there's like Revit building, Revit systems and Revit structure.
I think there's three versions of Revit. It's not like one one Revit. >> Oh like separate apps >> separate apps. And I think they modified it in like 20 2009. >> Uh, >> okay.
>> It was toolbars. So there's no ribbon toolbarss, but it's the same status bar, the same, you know, the scale in the bottom, same user interface, same project browser, and same as the properties panel. Um, so it used to be like that. Um, it was great. Um, I had my own complaints about it at that time because, you know, you can't do slanted walls.
Um and I started getting excited about it just because I came before before I was a student before getting into Revit. I was uh in uh AutoCAD it's called architectural desktop which is the AutoCAD architecture now has the AEC objects which um at that point you build in you know wall like like a Revit wall and generates a three dimensional of it. The my biggest concern at that time with with AutoCAD architecture and it's probably still valid that um you can't do um solid operations like booleans um subtract subtract on a between a object and a standard AutoCAD mass >> like standard solid. So >> when I saw Revit I the promise was and this is the the um super exciting moment for me. Two things really caught me is bridging the u gap between uh conceptualization and documentation.
And most of most of us at that time were doing things in 3D studio max get the concept and then start working in AutoCAD right >> uh in 2D and uh >> until now AutoCAD operations to convert a 3D object into 2D like flattening it's not it's not good. So it's actually you need to work in 2D. Okay, you can like work in 3D and slicing through objects. It's not it's not ideal. >> Um >> also um the other topic that really caught me is think the way you think.
So instead of thinking about massing and geometry, it thinks about walls, kernel walls, >> you know, doors like actual building elements. And probably the most important one which is really relevant to what we are talking about today is building as a database and thinking the BIM is the building as a database. You know you can have the manufacturers, the designers, fabricators, contractors, engineers all together dealing with building elements that have parameters and each parameter is an element itself. >> Um and uh that database really uh was fascinating fascinating to me. The only problem is Autodesk since then they didn't expose anything with that database.
I think they added something called Revit DB connection which I think ID8 took advantage of it and generate the uh BIM link and ID8 explorer >> and >> it's like a quick export to DB or something but I never saw it really took off. >> Yeah. 20 2008 I so I got into 2005 by 2007 I lost interest in Revit. I found like this thing is you know very limited. Then ID8 came with their tools and really got me excited again.
And then two years later um I got into uh 2013 I uh I got early preview autoesk at that time when I was with Gendler. They gave us an early preview about two products. One called uh uh project visari and the other one called project dynamo. And when I saw that sorry was >> was an Autodesk take on SketchUp >> within a Revit uh UI application. So it's it's Revit.
It's smaller but you only see is the conceptual massing model and uh I thought that's great and when I saw Dynamo this is Autodesk take on Grasshopper and said this is awesome there. Um at that time I remember all of the team were talking to Autodesk and we asked can we have fix the issue where we have a family document and a project document and we can't really transfer geometries in between and they said they're going to fix it and it's not fixed yet. Uh and no but by understanding how the Revit API is structured it's really hard job. It's not easy to to bridge you know to you know if you think of it you know docs are not exactly like between a family document and u like a Revit project. So >> yeah there's also it runs on so much legacy code so I don't think they are always in so much control unless there's like a lot of resources involved.
>> Yes. Yes. Totally. Um I actually decided to learn Revit API in 2009. So, and um 2009 >> that was before Dynamo or after Dynamo.
>> Before Dynamo >> before Dynamo. All right. >> And uh it was an AU workshop. I think it's three hours long and they said build your first plug-in for Revit. And I said I'm going to do it.
So before that I have so I I I'm before that I'm okay with coding. Um uh I think I have similar path to Hassan and Jean Mara uh when it comes we started with basic and started basic when elementary school so 10 but you know by age of 10 I was uh coding in in basic and >> um in um in in high school we started a language called Pascal I think it's already disappeared that language it's it's uh >> probably declare variables >> you need to declare your variables before you start your your script Basic is more like high level very similar to Python. >> Uh you declare you declare variables on assignment and it's it's just amazing >> and I feel like most people who start with basic actually really like the Python >> but um then basically >> I noticed there are two camps people think very different. I also used used to think that everyone was going to love Python. Some people actually hate Python prefer this kind of defining variables on top because they maybe like extra structure.
it it's definitely less beginner friendly to begin with but there are benefits I think >> I I'm I'm slightly okay with C um I feel C# is very similar to the Pascal which I didn't like in high school I was good at it >> um in college I switched only to max script and lisp and became like a scriptor so didn't really get into any of the development when I got into uh the Revit API uh >> 2009 >> um two things first it was an AU workshop online available and it's free and when you're you know when it's free you save it on your desktop I say I'll come back to it later and it's on my desktop for 10 years. Uh the second thing I started the video and it said well you can use uh Visual Basic or C at that point that we don't have a you know we didn't have the RevitPythonShell at that time. Um, >> so I said, "Well, cool. Um, I know GW Basic or QuickBasic. Um, Visual Basic is just the uh, you know, the .NET version of it.
It was like the object-oriented version of it. Um, but it was completely different. I wasn't expecting, you know, visual basic uh, was completely different from the basic I know. So that was a smoke screen. I said like ah maybe I need to come back to it." I didn't really take the first step and I regret that.
So >> So during this threeh hour presentation you actually didn't finish it as well or >> I think I still have it in my the day still to come. >> So every year I put like uh things to learn and put a folder and put a bunch of videos and by end of the year nothing is done so I move it to the next year. >> So I have it in my I think if I if I if I you know search for it probably I'll find it somewhere. It has the handouts, has a PowerPoint presentation, a bunch of videos, I think also project files. Um, but I think it's irrelevant right now.
Well, maybe not that much. Uh, but it is. So, >> okay. So, this was in 2009 when you kind of almost started but something pushed you away, >> right? >> And then you discovered Dynamo in a few years, right?
>> Yes. So, Dynamo, I started with it in 2014. Uh >> Mhm. First, I think it was it was pre-release 2015. I was in AU and it was only about Dynamo.
Everybody was talking about Dynamo. >> Dynamo is the big hot item. Um, which is unfortunately it's being pushed in the in the back background, but um uh so I got into Dynamo and at that point still like packages were limited and it was all you know version 1.1 and 1.2 too. So, you don't have that com, you know, compatibility issues that you're running into it right now. >> Um, and I decided I'm going to learn it.
And I spent I think the New Year's Eve 200 2004 2005 my friends were hanging out partying and I decided I'm going to stay here and I'm going to learn it. And I think in in few hours I you know it's just that first step you know breaking the smoke barrier and saying I'm going to do it and just get in there. It's the the big the most important aha moment and >> yeah your first win. Right. >> Right.
Otherwise if you just said I wanna I want to learn it one day that that day won't happen >> and that's the issue. >> Yeah. >> So um I started with with Dynamo and I this is where I got into uh the Python node pretty much. Um but it was very linear, no functions, no classes and it's pretty much automating getting a quick access to the you know like this creating like uh quering the sheet list or revisions on sheet and just you know reporting the sheets with this revision on it and getting a list >> um you know it was it was very basic implementation until I think 2018 2017 I wasn't in that AU do. And my coworker at that time, Jessica, she told me, "Have you heard about pyRevit?" And I said, "No, >> but is it like RevitPythonShell?" She said, "No, I think it's better." I said, "Does it mean it's I can write do an a full toolbar with it?" She said, "Yes." >> But also, I didn't look carefully.
My misconception was um part of it is like interpreter on top of a visual studio where you can actually write in Python and compile a an addin like a DLL >> and that was uh something that I should have looked looked earlier into it because um I could have won I could have been probably three four five years earlier in that journey. Uh then so I downloaded pyro uh pyrovate. I like the tools and also >> I kept it waiting and at that point I was like grasshopper doing more like computation design ladybug environmental things. >> Mhm. >> Until 2021 2022 end of 20220 2022 and I was looking at the extensions and I think I start I was looking at your extensions actually.
I think you have you have one in 2022 I think the first installment. Um, and I discovered this uh tool that really changed my life. It's by Jean Makufa and it's called Pyabbit Bundle Creator. >> Mhm. >> And when I got it and it's probably um nobody thought about it.
Uh in five minutes I have a toolbar because it's really create the the buttons for you. And that toolbar that I created, it's all URL buttons. But hey, it it is it is um I got now I I I now I understand what is pyRevit >> and looking at the folder structure of the py the the anatomy of the pyRevit extension >> and then it's like I get it. This thing is super cool. And I think once I started maybe 6 months later Chad GPT showed up and it's just like >> perfect timing where you know you start getting into exploring with the the API >> ambiguity.
You get lucky with that one. >> And I think I started seeing your first initial videos, the videos without beard, like the whole initial, >> right? >> But um I think uh the first tool actually I wrote I had to go to uh Revit Revit API docs. It's the um you click and it will take the hub ID and the project ID and generate a URL where you can go to the uh uh ACC form. And now it's called forma the BIM 360 >> Mhm.
>> link of your project. So sometimes you publish a model and you need to do create a package instead of going to the browser and navigate to your project you click once into in your Revit it will take you to that page directly. >> So um and it's funny that uh like last year somebody from H emailed me and he wants to do the same with desktop connector. You click on it, it will open the folder structure of the desktop connect like auto desktop connector of your project that the active Revit document and uh I think we did it. Um fortunately um Revit has the uh desktop connect.
Jean Makuan called me the ADC expert in this. So that's my niche. >> Yeah, >> that's your niche. Good. I'm the opposite.
I haven't really used this all this former B360 and so on. It's uh it's I think every time you do things you fix you know you p push a PR update next day autodesk will push an update it will break your work you need to be >> I see >> all right so let's just kind of wrap uh >> unwrap it a little bit so while moving from Dynamo to pyit was what what was the main reason for this kind of kind of shift first of all for you >> uh yeah so um my approach to Dynamo every every you know even when I'm in Python I always always treat it as a freelance tool. You're like one lone wolf in your firm and if somebody want to do >> um a specific task uh they reach out to you open your project and do the task for them and build their projects and they will say thank you. That's not an enterprise product and the same I would say the same is actually applies to Grasshopper like it's not these tools are designed with uh freelancer in mind. It's just one person >> um power user as well >> within the company.
Yeah, there's a tool by um Mustafa called um Orchestra that's actually you deploy it it's cloud-based. So you put your your uh companies Dynamo scripts alongside their packages and let their uh users double click on it and it will load Dynamo in the background and and run run the tool and it will you know bring the packages. So it fixed the compatibility. The issue with Dynamo is it's slow. It's, you know, it's a wrapper after a wrapper after a rapper.
So, you know, you need to wait for Dynamo to run in the background to execute things. Um, >> the only advantage I would say for Dynamo is it has its own geometric engine. >> So, you can do like intersections um uh cutting geometries. >> But I think also with with Parvit is just a plug-andplay. It's a enterprise product.
the CLI is amazing and you can deploy it to whole company and uh uh you know it's and um also I want to say you work on the script hit save and click on it and and you don't need to compile anything. Um >> Mhm. >> Uh I got into the I did some fixes on the new uh C loader >> which made me appreciate the the the Pyrovit engine itself because really you need to close Revit, close your project. >> Um do the edits, compile the DLS, put them in the release folder uh and then restart your rev your Revit and then uh it's it's it's a lot of work. So >> also about that I keep hearing there is this hot reload or something like this the feature so you kind of don't have to restart Ravit but people say of often times you still do have you tried using it >> um even the rocket mode >> no not in py ravit when you create the dls for kind of ravit addins there's like a feature like hot hot reload or something like >> oh I don't know because when I try to push the DL it will tell me um I can't like the visual studio doesn't doesn't tell me maybe there is a tool that maybe I need to put in the debug folder and but the problem is the DLS that I need to replace especially for the loader are actually in use so I can't replace these DLS once once they >> but that's probably only applies to the C# loader if you want to do >> a different >> um >> yeah just a question I thought that maybe you tried it because I keep getting this argument like oh you can't use C# without reloading Ravit But at the same time, some people say, "Yeah, but it doesn't always work.
I thought maybe you know about it." >> Actually, you can run C# in pyit in a button. >> So for people who want to prototype something for a bigger plug-in, they can still use pyit for it. >> Mhm. Mhm. >> Yeah.
>> Not many know. I haven't heard anyone really use that, but I know it's an option. >> I I know somebody in the forums actually was talking about it and we he said, "I use it. I use I I only know C#. I don't need to learn Python.
And I'm using pirate now for for you know >> for prototyping >> here for prototyping actually that's a sound idea. >> Yeah. >> Interesting. >> All right. And once you discovered pyra start moving into what was your first tool that me gave you this aha moment about pyrait.
>> Um I think it was so it was the uh it was that uh you know quick link you know open web browser. So it's just I import the web browser and I get the from the doc I get the gith the yeah so um since then I started doing smallers you know and this is what the beauty of pyRevit you don't need to write a major code um it's a 10-minut snippet code snippets that actually can can work for you um >> like quickly creating an Exxon for a room I think we're working on a project and I immediately did or um I had one tool that's actually you just select a bunch of wall. Click on it to give you the total length. Uh this is great if you want to if if you quickly want instead of creating a schedule, you need to know how much linear footage um or or distance of specific wall selected and you get quick area quick volume. Um >> it's it's totally a great tool.
Uh I think the best one is also apply quickly applying view filters to um view templates. Uh that's one of the one of the early tools that uh created. Um but everything was I was all only working low-key and something I discovered when I started searching for you know API questions that there is uh the pyrovate forum start becoming active. I think it was started around covid. Um before that the only sources of Revit API were the building coder or the dynamo forum.
Um, and now we have the pirate forum and you started getting some cool ideas over there. >> U, so I started becoming a little bit more active on the forum >> but without major contributions and things changed until things changed in 2024 when they announced the hackathon. I don't know if you remember that one. M >> so they announced the hackathon and only three of us joined >> but I think um it was for the pre-flight check um >> yeah yeah yeah I remember I think that that was the bottleneck because many people didn't understand it fully what it how to make it for that >> so I did the 10 mile radar on it and a bunch of people like one did the CAD audit which is also I think it's really cool and uh so like three three of them they got it and the the I think what's brilliant about that hackathon is only although three of us it gave us the level of comfort that hey you're welcome here so uh every participant needs to do a PR against >> uh you know the develop branch >> and I think it was the develop develop four because I think they're still working on develop five which is the pyavit 5 I think we oh the pre-flight check was against pyit 4 >> um And this is my first uh not just PR but also uh Jean Mark and u uh the cousins Andrea and uh forgot what's his name BJV um >> they really shredded us um and because I I was coming from a Dynamo all my all my imports were CRL >> and you know import all this revit db >> um are also using the um OS O uh OS.path utilities and instead of path lab which is I think it's probably a little bit more structured within pyrait. Um >> yeah it has >> I had no python um enhancement protocol you know pep 8 uh it was just every every conditional statement uh was like you know 160 lines of yeah or like a row of line uh of characters.
So it was very undisiplined but they started giving me reviews and started doing comments to update and maybe after going back and forth for for a month I start feeling I'm very comfortable dealing with those g with those people. >> So uh and I felt I felt that I'm really welcomed in that group uh which is uh that encouraged me. now return back to the office and every day somebody complained about oh this tool like I think that one one of them is the oh there's one broken it's the um I think it was the inspect oh find tag all untagged or find the untagged objects it was it was throwing an exception so it was I think it was just a syntax error maybe I think it was the >> the migration to the new net one of them like the the way it's handled Revit element that was like a single line of fix and I went and pushed another PR and Jean immediately replied like hey keep this going. >> So in that point I started like doing uh every time something is doesn't look okay I just go and uh participate in that community and uh >> Oh that's great. >> Uh the rest is history.
>> No no that's really good. They also need like more people to kind of chime in and like help with this PR. So because there are lots of this little issues like you know there's like new API comes in like one property instead for example recently they introduced this uh change to element ids now we cannot provide number it has to be integer 64 super annoying change it's it's just kind of adding like three letters and parenthesis >> right >> but it's just so annoying that we have to do it and yeah this really helps what I see >> yes >> I wanted to dive into pirate like to help with the code a little bit here and there for so long but I never found time. I decided you know what I'm going to keep doing my YouTube videos just direct people to parit and that's going to be my thing. I'm not really >> um No, I think what what you're doing is what you're doing is we don't have any voice for this community.
I you know the people I I I was look I looked into this maybe u a year ago. The amount of people who actually contributed code to the pyro repo is only 85 people. >> You know this a solid number. Yeah, it's it's a solid number, but it's 85. It's less than 100.
And I would I would say uh still I think most of the code came from Hassan. Um but I think now I think we got the new um uh uh uh Roman Gov. I think he's doing the uh C# loader. Uh I think >> huge huge shout out to him for that one. >> Yes, he did.
He did. Also, we in in the middle of nowhere, we started getting people I don't know their names. I can't even spell their names. They don't have pictures. they don't have faces and they started doing all these amazing PRs.
Uh it's just like this this uh this community is about about to >> be a different level. Uh it's yeah uh I mean uh I think Jean Mark um told us like hey there there are issues like 91 can we push them a little bit to be lower so if you find things that are fixable and um uh I think we managed to get it down to 60 now I think they're back to 71 we need I need to to jump in back but um >> uh it's it's a it's definitely an amazing community and it's a small And if you think about it, >> um the money raised for uh for part of it is minimal. Uh I think it's still I mean I only few people who contributed well thanks to them. I think my my firm contributed last year. I'm planning to contribute this year.
>> Um every firm should be should be contributing but it's also we don't have a voice. That's for example you you are probably the doing the PR um for >> for the Revit API. We don't have once I think Jeremy Tamik retired I don't think we have anybody is actually actively on the internet preaching the idea of like Revit API >> and >> I mean G before Crown but now Gavin Nichols now he's also doing he shifted to C >> but he also like has the war has the >> family and stuff so he also kind of comes to you and goes over but and I totally understand I do the same like I show up I disappeared and come back but now I try to get it more serious. >> Totally. Totally.
>> No, no, no. But but I know what you mean. Like before I started it was so hard to find information on Ravit API P Ravit. But today many more people come out. I start finding like kind of new creators.
I see new tutorials. I'm like ah who is that? Then also AI super breaking all the barriers of entry. >> Yes. Yes.
>> Yeah. Community definitely grows very nice. The only thing I personally hate is how Autodesk pretends par doesn't exist. Yeah. >> And I thought so many times that for them it would be such a great kind of community move.
Just give py one developer. That's it. Like for them it's not big money. It's going to the par the par community going to be so happy because John Mark mentioned many times that sometimes we just need like C# developer to kind of go in in the engine this kind of higher level code you know like because not everyone want to go into like touching the parate engine. It also takes time to understand.
I never looked at it. So in kind and code wise I have no idea what's going on. I kind of get some ideas here and there but I think if autoes could just give us one developer like here just do whatever they need help with. So like even just kind of rogue one just do yourself what you want >> do proono do proono do have like a community project. >> Yeah.
Yeah. Exact exactly but pirate just pushed aside because I think they don't want to like deal with Python Python engines even though they built Python engine for Dynamo. So they have even that because now they have this IronPython 3.6. 6.6 or whatever the latest version and I think there was some talks to share it with kind of pirate community somehow. I'm not sure exactly how it's working, but I >> think 2027 they switched to Pythonet uh at least when I because I did the uh dev tools for the um for the pirate dev tools.
I did a bunch of uh testing the bundles and I think 2027 they switched away from an IronPython. Um but I think it's a bless it's a blessing that Autodesk doesn't want to intervene in pyRevit and let us do the work or let everybody do the work. Um, Dynamo was supposed to be an open source project, but it's also pushed to the sides. Uh, just because it's probably not a revenue generator. It's probably a community project more and more.
>> I mean, yeah, they have completely different view on this whole Ravit and model. They care about shareholders. They're they're like, you know, like the corporation level, enterprise level. This completely different. But I think Dynamo is still they don't understand that if there wouldn't be Dynamo, if there wouldn't be a Ravit API, Ravbit would fall so long ago because it misses so many basic features.
>> I was so surprised when I started. I remember >> many people going to relate when you select one type in Ravit and you want to select all instances of that, you know, the SS, >> it works. >> You select two types, you couldn't do it for years, >> right? >> I was thinking like it got to be super complicated. There has to be a lot of code involved.
Then I decided to do it. I was still kind of beginner. I was just kind of getting kind of into this whole thing. It took I don't know like 20 lines of code. It started working and I was like what?
Why? >> Yes. And this feature was requested for ages like people like why we can do it. It's so because sometimes you want to take two types of walls or two types of doors whatever in select. Super simple feature.
I wrote it right away and I'm like this works. I just published to the whole company I worked at. Here's how we do it. I pushed it I pushed him in code somewhere on the forum. next year it got implemented.
I was like, "Huh, finally." But it's just like this is the issue with Revit there because it's not they're missing a lot of features everybody needs and they often focus on features that nobody needs. They they try to create a lot of hype always and stuff like that, but we just need like fix the issues we already have before adding all these like AI assistant. Cool. Can we fix something from like 5 years ago first? I think that's what's kind of why py raid getting so popular why Dynamo why C# plugins getting more popular because it gets more accessible plus we finally get to fix this little issues cuz they probably like I don't know they just going to it's too little not even going to care about it.
Uh, I used to go every year and vote for the OGI wish list, the Autodesk user group institute and online like they pick the 15 top 15 wish list and every year nothing gets implemented. So I decided I I'm going to give up I'm going to give up on that one. >> Even the top feature didn't implement. >> Uh, a lot of features did not is not are not implemented. Um I can't remember but it's uh there's a lot of uh maybe a lot of them became you know part of the pyrovate tools um so the firm I work for the they discourage people from using keynotes because they don't want to deal with the text file like this is this is from Brevit 1.0 they didn't really change pretty much the the keynotes >> the keynotes you mean?
>> Mhm. >> Yeah. Um, but also we have a lot of gimmicks being introduced. Like look at the Revit now. It's the accelerated graphics tech preview.
I can tell you this will be a tool that it's the same and it will won't leave the tech preview. Um, generate generative design for Revit. That was a gimmick and I like the time I saw it. It's it's just um I by the way I don't get that one. Generative design was a thing before they touched it.
Before it kind of they created their own version. people did cruel things with Grasshopper Dynamo >> once they touched it and make it their new feature of whatever release that was it just died. >> I I was so confused because before it was actual kind of for facade designs and stuff people were sharing cool stuff once they touched it everybody was like me. >> So actually when we saw that so um I was an attendee I wasn't an active member of it uh but I was like regular attendee um in San Francisco we had uh San Francisco uh Dynamo user group and I think it was also started 2015 2016 >> and we do like monthly meeting um and it's you know meeting with dinner and we have like a guest speaker >> I think son was one of them to introduce Rhino inside Revit uh 2020 2020 right before the co >> um but uh we we get a lot of people who are really into the Dynamo world uh joining us and I think the group of like 2019 they found like this Dynamo going nowhere where Autodesk is not also supporting and it's also that that group Autodesk wasn't actually sponsor stopped sponsoring uh the Dynamo group. So decided I think that point they rebranded to San Francisco computational design group >> because we thought probably let's let's make it you know expand the perspective and have a bigger community than just >> yeah broader reach as well.
Yeah, but I think to your point, I think Autodesk not intervening in Pyrovit is actually good for pyrovate and honestly I think moving to the future and you saw probably you had a hint of 2027 new features. I think this is going to have be the same pace for the next 10 years. Revit will be a stagnant product just because it's not it's saturated market for them. Most of architecture firms are already using it. >> Yeah.
It's so hard to move away. >> Yes. Right. And I I I was thinking because um I was offered a manager position uh 10 years ago by you know I told my boss I don't think Revit is a future. I was wrong.
Revit wasn't Revit's still there. And he said what do you mean? He said I don't see Autodesk is actually taking this product seriously. Um and um he said then what what is the Revit killer? I said I don't know.
And I I think he's he asked me a really good question. Right now there's no Revit killer. But the pro problem is Revit is not progressing. And you know when when things stagnate, it's not going to be good for the industry. Uh >> yeah.
um what I what I feel like 2027 the new features um are clearly uh it's not their main primary u revenue generator. I think their growth perspective is more aligned with forma, ACC, big data and even the AI thing is uh I would I would you know I think MCP server is although I think MCP server is a band-aid mcp server is probably better than having an autodisk AI because really you you're not you're not clawed or open AI we're actually >> versed in LLM and doing a small LLM you're you're getting a quality of, you know, GPT 3.1 probably at at best and you try to run it on that one. >> I think they still made the MCP server for their this AI system because they now released that you can connect cloud somehow and stuff like that. >> I think the issue I just had recent podcast haven't released it yet with um Jonathan Jagabson. Hope I I hope I remember it right.
>> Waiting for it. and he actually had a very solid point that instead of making this whole AI assistant and stuff, they should just give us in infrastructure like with Revit API. We don't need them to make all the features that once they got gave us Revit API, we just started making our own plugins and everybody can customize it. >> And same with this AI thing. It would be so much better if they would just give us proper it's going to MCP connection server how we can modify it how we add more tools like you know the infrastructure so we can take it and build our own stuff on top but instead they kind of make this halfbaked AI assistant nobody knows what kind of model it runs it's not performing well very limited we cannot really expand it at least not yet and as you mentioned it's in preview state so everybody is like yeah yeah just wait with the next update it's going to be >> pre forever >> yeah people already like >> probably it's going to be preview forever Now they have an issue.
How what did they do across the version because it's not supported before it's supported after and we already can make MCP servers even with Pyrait for all the versions. So it's already kind of eh so it's weird and >> but yeah definitely agree with that one. >> I think MCP is also a temporary solution. Uh I think LLMs are working I think the big players are working in native um 3D geometry uh generation instead of executing code through the API to generate an object for example um >> because right now is the if you think about LLMs are good at text images and now videos and I think soon very soon Yeah, text images and some some videos. >> Um, and probably I think coming soon I think sound will be I'm I'm pretty sure that OpenAI is doing training on Spotify like database and >> it's already pretty solid at sound.
It can generate sound and can talk and stuff. So it pretty much >> I think it will be generating music like >> it already does not not directly from them but I saw some some really cool just write a prompt random one it makes music. I just played around even made some par jingles for fun. >> I was thinking maybe add something. >> I see a lot of YouTubers doing that.
Yes. But um also I think what's missing and there is limited data is uh training on a 3D objects. >> Uh I know uh uh uh OpenAI has the point E I remember which is training like a point cloud. >> So it's actually text to point cloud files. Now point cloud I think meshy also used that or maybe a related product to generate points to me like a prompt to mesh.
So uh and I have I have one uh script that I was playing with. You generate a mesh um you get a WPF panel. You generate a mesh. You get a preview and you click on it and it will use Rhino to convert it to an herbs and then you bring it as a direct shape and Revit as a family. like one way of doing like >> prompt point clouds mesh and then at nerbs and there are a family like six steps in one script >> there are so many steps >> right but I think um tools like probably like Rhino I think it's it has the uh the tool like you can say hey create me um a mobius shape and it will create you a moious shape not instructing code for uh Rhino to create a mobius shape so it will generate this this file based on that.
Uh and the problem with Revit is not AI ready. >> Yeah, I think it was never meant for AI. It's for example uh I I you should do um a pyravitate um uh or maybe like you should do a pirate award for somebody who can actually use um MCP server to create a staircase because it's not exposed by the AI uh by the API. It's there's no uh autodesk revit db.stair 3D or you know class. It's not there.
So if people saying >> it's actually there >> is there stair 3D. Do you do you create a stair? Is it possible? >> Uh let me just have a look. I just remember in architect DB.archchitecture there is like stair class.
>> Is there I don't know. Maybe there is one but without a create class. >> I never looked at that one. I hope people get around that by creating their own families which is more superb to native anyway. At least that's what we did because we can control all these notches, perfect connections for the concrete which the native one fails at.
>> Yeah, direct shape maybe. But that's the problem is like you there's no single tool in in the whole Revit ecosystem that's actually created stairs, ramps or railing because they're not exposed by the API. And the best feature Autodesk can actually create for the community is actually exposing these API for the people like we don't need the new features. >> For me, the annoying one is the groups. It's so li we cannot do anything with groups pretty much.
There are some crazy workarounds which are super risky on our large projects because uh we just have to have like something like with context manager just go into the group like edit mode move things around and it apply like manually open the group >> do something close the group >> cannot do this with the API and this drives me crazy because I had so many workflows in mind that then I had to sit in there and think okay what's the workaround how do I go around this and sometimes it means like >> kind of letting groups a little bit go or making something like you know you to kind of find this weird workaround sometimes. But that's part of the Ravit workarounds in Revit. They always you're looking for solution, there's no solution, but there's a workaround. Hear me out. >> Yes, always.
Um, >> always. >> But again, I think it's I think the only the only thing that's needed and the problem is now a lot of the Revit API elements are being migrated to the platform services like with Forge ID and you know, Forge types. Uh yeah. >> So actually this is how I got into the um desktop connector. It's through uh the EF tools.
>> So uh our favorite tool is our set of tools is the DWG where you can open and reload or like save. >> Oh and I thought like this is a great tool. Uh I'm going to use it more. First click didn't work because again our files are on ACC. We don't you we don't store files locally even like even before covid and now it's like mandatory practice here in the United States most most firms you're not allowed to save any file or any link locally it's just peace of mind in case >> it makes sense >> in case a doomsday scenario everybody can take laptops to their home and without the need to worry about VPN or network infrastructure you just go um auto got lucky with that one like that co was >> was like a godsend gift to to Autodesk.
Um >> yeah. >> So at that point I realized uh um external reference uh external references versus external resources and these are two different um API classes and I decided okay I'm going to take your tools >> and I'm going to just create another one. It's like use try except if this is accessible um as external reference let's proceed if it's not that means it's an external resource if it's not there that means it's not available the link is not not available >> um but then I decided I discovered that step by step and then at the end your code is completely different like the you know I pretty much replaced your code >> just to get into the uh external resources because at that point you're dealing with forge type ID instead of like element ids and uh became a bigger problem with that. Um so at that point I decided okay I know how to deal with Autodesk uh desktop connector and then um I think they switched between 16 and version 17 and the way it handles u syncing and locking so um I think asan did it or maybe it's actually started by Asan. the ADC library and and and Pyrovit you it enables you to uh sync download lock open and save and get paths look get local paths of spec specific um uh like a element on a a file on a desktop connector because it's >> hold on a second what is this library you mentioned >> um it's if you go to pyrovate uh pyate lib inter interprobe and it's called ADC Um that one is actually um what you need to do if you want to handle files within desktop connector.
>> Mhm. Mhm. >> And the problem with desktop connector it's if you think about it it's like Google Drive. It's or like a Dropbox. It will give you a a um uh what was called like a f or like a pseudo path.
It says accord your company and for slash um yeah that one. >> Um and then um this um great because you want to transfer it when if you want to do operation open the file you want to transfer this to a local file. So in it should be like C uh users EF tools and then you go to like uh the you know the the hub name and the project number. >> Mhm. So, uh that um that became my obsession for a while and then we started getting a PR or like actually issue um Autodesk switched uh desktop connector to net 10 without telling anybody.
Uh and that update when it showed up it started crashing uh keynote manager on on Rev 2024 and earlier which is which are the uh net frame net framework 4.8 8. Um, so I had to go there and see what's going on. And this is where the keynote manager people started complaining, oh, can you change the interface? Okay, it became like adding AC uh desktop connector functionality and then ch changing the interface and then people started requesting more and more functions until I reach a level that I can't edit it. This becomes so complex.
30% Revit API, 70% WPF and um external handlers because we want we we change it to a modless so you can work on the keyynotes without actually only when you place it it will generate a transaction. So it's pretty much a floating window outside the um the Revit API. I know somebody asked like last week, can I do double click to insert a so people have started being really picky about their uh user requests and uh >> this is my recent obsession with pirate now trying to get the key manager to be >> better shape the thing is that I think also in par what's cool is that from autodesk side I feel like sometimes developers they don't fully understand how ravit is used because we also don't use it just straightforward or sometimes we have our workarounds >> and with parit we often get people who are really know for example like you mentioned you've worked with keynote you understand it and you can speak on the behalf of community how the tool should work because sometimes we get tools which are made by developers not by users and there's this disconnect and they think like oh that's actually a cool button here and users like yeah we never use this feature or oh we don't need it just you know there's like some very basic request like I mentioned like select all types also all users needed it developers probably didn't even know that this issue exists. I don't know. >> Right.
Um one one one one thing that I found like for example McNeel like Rhino um the group is actually very active on the forum is actually they let the developers engage directly with the customers. There is no customer service and marketing and they don't have >> modern teams do that. It's very very efficient >> and I think this is what we you know we have with with the pirate group is we are only you know maybe eight people active at the same time and people start you know uh requesting features. Some features are really unrealistic to implement and others are and a lot of people came with actually a feature that they want to put it as a part of the pyro like they want to donate their tool to be part of the private tool >> and we we we welcomed few I mean few people did some really phenomenal tools I think I I can't pronounce his name I don't think it's his name I don't know it starts with W but he added the measure 3D it's improvement over the Autodesk Measure 3D. >> It's way it's way better and it's more um it gives you the deltas in X, Y, and Z and um it uses the direct context 3D.
So, it's actually it's it's it's really it's really nice interface to use. And I think he did the uh crop um section box uh navigator. It's like a floating window. when you can have a section box assigned to a uh a floor plan, it keeps going back and forth, left and right. That was that was amazing tool.
>> That was amazing. This is like previews of how high it goes, where the cut, where's the B that Yeah. Yeah. Yeah. I saw some LinkedIn post.
I was instantly like that's so good. This is something that this is the thing that >> Autodesk just autoes developers don't always know our issues. Just think, oh, probably everything works. We like when we use this stupid like cut levels every day for a couple for a certain period, we start to hate it so much and then this kind of tools come from py power users who like okay enough I'm just going to do something about it. That's what I love about this whole community because it's it's communitydriven not like this uh kind of >> kind of users driven not like fully developer who don't use the product.
>> Totally. And um I think this is going to continue to be the case. I think if imagine if like for 10 years there's no major features being added to to Revit, how the AEC industry respond. Uh we don't have a product to replace it and all the new uh nextg products are either take you know treating with tackling niche products like parking generator uh >> facade generator uh space planning. we don't get one that's actually do a major uh project documentation and coordination like like you know like what we have with Revit and that vacuum is ready to be filled by the private community.
I think that's why I feel like parrot is going to be the biggest winner >> in the next 10 years for the especially with AI because now even if you're not fully well-rounded developer you can get away in writing a script that is actually if you know what you're doing uh understand the basics of the API I think you can you know create u a solution you know solves your problem and I I think this is going going to be the case >> now a lot of people are slowly gets there. I see more and more people get interested. Also, this AI, >> it's amazing how fast people can get into that without even understanding what they're doing. But also, they don't realize when they hit the limit because AI just gives you a lot of things, but sometimes you still need basics. Maybe not exactly as much syntax, but just understanding kind of Ravit API logic, just Ravit logic in general, so you can at least command what to do correctly.
>> So, I want to say I want to give also some cheat sheets to to the audience here. Um so I use AI a lot. Um I used AI mostly it's the GitHub copilot. Um but I have you know because uh my work they gave me the max account for cloud and I got also >> um and I think the best use of u AI and it's actually I utilize it a lot in the copy paste. So I added the functionality of control ctrl +v for the output window which which was under the wish list for like you know 5 years.
Um we all couldn't we couldn't resolve it initially because it was um it's an HTML in a WPF window and it's there's no way to register like C controlV events uh from the so you need to go right right click and copy the output of that. Uh so what I what I so what I what I added with the uh I added the trace logger >> so it will log my um events into a log file and >> it does >> and then I take it and put it into Gemini and it will tell me where this control C is actually being triggered. So we at the end the conclusion was actually let's do it on the system level. It's like in the operating system level, not on the WPF level, not on the HTML. >> No, not on pretty much.
>> Yeah. >> Okay, perfect. >> Um, same. >> I heard I heard this change. It was so annoying.
I always you select the error message, >> Ctrl C, go back. You paste something previous and you're like what? What? Go back, right click. >> So with 6.4 is actually you can control C control V from the open window.
Um >> but the same thing is actually so WPF it's you know there is a level like creating the interface and you know adding triggers that's cool getting into like external handlers that's becomes like you know this is where the memory leaks happen this is where you know the issues start going like the net crashes and I found like AI is really great if something crash you can just go and take the crash report instead of reporting to autodisk take it and put it in cloud and it will tell you likely what's the cause. >> That's actually a really good use for somebody who really get into the AP like the API development. So I want I don't think the Revit API can actually and this is for example the um the block AI that I worked on is actually help helping me because there's a lot of when when I was trying to run it I tried to figure out the command uh like the post command ID or the command post ID um from the journal and actually AI is actually instead of scrolling down you can just take the journal and >> put in a cloud said hey can you tell me what what command ID is being triggered So it's just it saves you a lot of time. Um >> Yeah. Yeah.
Yeah. >> And uh yeah, logging. Uh definitely it's probably being able to developing a skill around, you know, understanding that things will keep breaking. So let's let's fix it. Uh >> how much do you use do you use clot code or you just kind of rely on the autopilot itself?
The >> native I don't use cloud code just because I I tried it. Um it's just because you don't have enough control. It's just this it will keep coding in the backgrounds in the background for you. Uh cool if you're not really want to control it. But for me I prefer to have a chat session so I understand what is going on like getting it's more a conversation instead of like cloud code just doing your files your extensions in the background and just putting putting it right you know over there.
>> Uh you can do you can do both ways. >> You can do it. Yeah. But I I prefer to to just use the maybe co-work a little bit more but um I prefer just just the chat. >> But uh >> there is chat feature as well for the cloud code as well.
There's like native interfacing ids, VS Code and stuff like that. >> Yeah. Yeah. >> That's that's why I'm asking. >> But most of the work actually I do it within VS Code.
So it's not like I only take it to cloud code if I need to troubleshoot something. >> Oh no, I mean like you can integrate it inside natively in VS Code. you have a separate window like your copilot. There's exact same window for the clo code. >> Yeah, I don't think I have I haven't reached this level of you know in my development environment.
Um >> okay yeah I I suggest you give it a try because from my like full research I'm now diving deep. Um, clot code seems to be like the best one at big multi-step tasks, >> right? >> Because uh it's not just the Oppus level because you can also use this oppus module in your copilot, but their agent also works. It seems to do much better work at the moment and it's really good for this big task where you need to brainstorm, you can plan ahead and so on. So I like really I'm now using that as my main kind of driver especially for all the test with AI I do.
At least that's the conclusion I came up to that now also the Codex catching up with uh CL Oppo. So there's also like OpenAI users and both entropy can do that. But yeah, they they seem to integrate quite nicely now with all IDs. >> I need to take a look at it because I think I have I have the subscription right now. But um it's funny that I still use 4.1 GPT uh for Copilot just because it's fast.
like I want to fix the syntax of something and just you know control I and just say fix it it will just nearly instant >> and because it's probably it's a single step it's definitely I won't rely on this one writing a full function for me >> um it hallucinate a lot and start switching to Python uh like at 3.12 >> and start adding these uh formatting uh like the f like the formatting for >> yeah the f string >> string at to debug. So, uh it's >> every rule file contains forget if string exists. Just use the method. >> Yeah. So, um I I Gemini is good at constructing a function.
I think Gemini is probably better the best in reading the API docs maybe. >> I think so. Okay. >> Uh but I agree for multi-step process. It's probably uh cloud.
So, >> because for me, I default to Oppus 4.7. I do everything even little changes. decides just give Opus to do everything. It's fast enough for me. I like it cuz I just want to see how far I can push it.
I don't want to make sure that the factor of the model is kind of slowing down things. Plus, sometimes I would rather have one prompt and the best model figure out the rest cuz smaller ones they sometimes need a few tries. You're like, "No, you did it a bit wrong." Hope still fails here and there, but I'm still kind of testing everything. One question I have since you are on GitHub copilot, can you also set up like rules files like agent files, skills files? Is it something part of the copilot?
>> I don't think so. >> Yeah, it's not like it's not like uh the markdown that you do with with >> Claude. Yeah, exactly. Okay. So, >> I don't think so, but maybe So, so Claude is uh is managed by my uh company's um IT director.
Mhm. >> So maybe he can do it on a enterprise level of enterprise account. But for me what I'm getting is just I log in with with um >> so kind of an credentials. >> Yeah. >> Okay.
Yeah. >> Um >> because um because now because I teach others and I want to teach more about AI really conscious about what I use because by now I use PyCharm which failing so badly at AI game. So I have to leave it. That's what I'm doing. And the conclusion I come to is that it's right now like the best again if you listen a couple months in the future it might change >> but in general the VS Code and cursor they seem to be like the leaders of the ID there are like cursor else there's anti-gravity so they similar to cursor but these two kind of the main ones especially for their kind of agentic workflows and cursor it also has this kind of cursor rules folders all this kind of bunch of MD files and also clo and in VS Code I kind of solved it for now That's what I use because I use clo code.
I can create this cloud files and I start to notice that it can be much better. >> And the biggest tip I can also maybe you can try it out. When you talk with go uh like coco cop pilot without these files it's always kind of kind of blank state maybe it has some memory about you but not as detailed and so on. With these files you can configure certain things and teach it over time because for example you talk about new topic like how to do I don't know coordinates in ravit API quite tricky topic but once you nail it it's easy >> and it's new chats it's always have to figure it out from the scratch it goes time tokens like output sometimes wrong but once you do it once you can just say like okay you know what now go through all the code conversation we just did create me a skill file add it there and for future reference and it will make a kind of AI tutorial for itself not like a tutorial, but all the important pieces. Here's how coordinates work.
Here's version differences. Here's code sample that actually worked. Next time it just like, oh, let me just reference something. It knows exactly what to do. So, this is the future about AI.
I also noticed that you kind of vanilla AI is great, but once you start training it, it's going to be it start compounding skill because it's going to get more aware about ravit API and specifically to your workflows, your tools and stuff like that. That's why I just keep the co-pilot completely, at least for me. >> So, it's actually I did return back to skills. Um, I have a couple of skills that's actually um I used it more for troubleshooting. Um >> Mhm.
>> Uh I asked Opus 4.6 at that time to go and clone the pirate repo and find all the differences between the legacy um loader and the new C# loader. And the reason why uh we got a lot of functions that work completely the opposite. It's a true false, right? Things >> by by default. Um and that that really developed and then I developed this as a skill file.
Uh that became as actually if if if a bug is there, I can just consult like um like what is going on and it will tell me. But really I didn't go into like fully structured development environment with uh with uh with Claude but I think this is something I need to take a look at it uh very soon. Um I think um >> also what is interesting here is you can build skills on sister libraries for example I I find like pyrovit has the future to expand beyond what's you know the Revit API let's say like other third party uh libraries like topologic pi or like shapely >> like where you can actually doing some graph analysis like geometric analysis instead like just like private API and you know dealing with elements. Um and I think because you can clone the repo of these tools and build a skill on it, Claude will be better in integrating these tools into your pyavit work uh pyate workflow. >> So >> yeah, you're not just going deeper but it's actually going you know wider and making associations.
Yeah, it becomes more context aware which is really great cuz that's it's it's like before we had to to get better outputs in the beginning. We had to actually copy a bunch of codes, paste it in the chat, kind of analyze, get ready for the next question and then we kind of got a little bit out of it more. But this now all these files I I think it's really important not to ignore it. All this MD files, all the uh cloud rules, this cursor rules, all of this, it's really worth setting it up. I'm now I resisted AI for so long.
I don't know why I kind of I cannot really explain it but I just resisted maybe because I like kind of coding and I thought it's going to stay more in manual control. Now it seems to move more into aentic workflows. You still need kind of understand what you're doing but now you can save a lot of time. >> So now I decided it's time to embrace it. >> Um although I think a it's a fun story.
I had um I was working on a a um IO updator uh like a hook uh for um for for the company which will trigger trigger a specific event when you try to do uh some work >> uh and uh Claude told me uh because I I was stuck in an idea of like this is if I cancel it I got unexpected behavior and I told like how you to unsubscribe from this event in this condition. I'm trying to unsubscribe but I couldn't and AI suggested using idling like a timer in the background just running and uh I said like no I don't want this he said well that's this it's just a solution I don't want to go into that rabbit hole and I said no no I want to go into that rabbit hole >> um so sometimes uh it's like you know uh like flow of water sometimes a also prefer to shortcuts >> um which probably not very often not ideal for uh uh quality uh >> when I tested AI assistant, I had really good example where take shortcuts. >> Yes, >> it was very simple example. I just told it something like okay there are like maybe 100 walls or something like that. Go through all of them and modify and expose the ID, right?
Just write the comments comment ID and the number of each element, >> right? MCP took ages and it started okay executing one by one as separate tool okay changing door number one door >> you get like >> it took ages >> uh I mean in MCP didn't expose it as a separate transaction but it looked like okay making the batch of 10 1 2 3 4 5 okay the next batch of 10 1 2 3 4 and so on and eventually it reached like 47 or something and it just gave up there's like okay I did good job what do you think can you continue or something like this right it just kind of stopped working and that then asked me for more or something like This and this is the thing like sometimes AI when you give it way too much work it can pause. >> Aentic workflows seem to get better at that as long as you're talking limits are fine they can keep going but they still try to pause for a second. You still there all good? >> Yeah >> something keep in mind.
Yeah >> I I tested the MCP like over over a year ago the pirate MCP and it really ate my uh Claude because I was on a free account. I think it's it's like after moving a couple of walls, I think I'm out of credits. Um >> Oh, yeah. Yeah. $20 now don't get you far.
>> No. Uh that's that's the issue. Um but for the AI block, I think what what really excites me and I think planning to do it for MCP um at least for for firms if they want to implement it is actually you blocking instead of blocking the assistant you're blocking the transactions. So um right now it's like um for example it will um >> got it >> it will do uh an like an event and then the event will do a failure processing and that failure processing will trigger um a a um like a forms. Like forms alert tells you uh you can't do it without actually contact your uh BIM administrator.
Uh this is what I implemented in the AI block. Um, still I think it's a lot of um a lot of work needs to be done, but I'm planning to expose this into uh or extend this into the MCP. I just need to figure out the post command ID. I haven't >> I haven't used the Autodesk MCP. I only use the uh the parabet one.
>> So, >> yeah, I think that was the right choice. And I looked at your extension. Pretty good thing that you're doing. I think the only thing is that it covers so much ground. you actually have to go like new people like even I when I went there I had to figure out what's going on because you have some controls config files and so on >> and I was like okay so it takes time to figure out how it works >> so I think maybe you also need to maybe make some light version >> to get people in >> cuz right now it's like okay where's I I went in I was like okay what's the password because somewhere it ask you for the password you found it in your GitHub >> password read me >> yeah yeah that one is fine and I was like okay where are the config files oh there are config files how does it work locally So I had to kind of go a little bit there to figure out how it works.
In the end, I just kind of took the base and kind of show like, okay, here's how to do the bare minimum just to block it. But yeah, it's a good thing that you're doing. It's just I think that for people who just open it, it's going to be a bit like whoa many things. It's a good thing, but it it there's like >> how to say it they need there there's like a learning steep curve to start actually using it really well. >> That's what I just wanted to mention.
But really good that you started it. It also made it so much easier to share with others how to block it. it will it will be just you know put it publicly people can can develop their flavors of it um but I still think because I stuck it to to our IT and I think they're you know deleting the island is probably the simplest process but you know um autoesk um they will push things with access >> I think also it told us they can block this addin by name so even if the even future versions of their release they are just blocked like by by uh >> uh by the company's pol security policy. Um >> Mhm. >> Um I I'm a bit concerned.
Well, not for Pyrevate. Pyrovate is ready for it, but um they're migrating existing Revit versions to .NET 10. >> Oh yeah, the Revit 25 and 26 I think. >> Yes. Which >> I'm right during the middle of release.
It gets so many people confused. But I think it's becausen net is running out. Maybe not every plug-in uh developer is ready. >> Yeah. Yeah.
Uh I saw that many people reported it's not as bad. Maybe there are some little issues here and there, but in the beginning, everyone a little bit freaked out. I'm like, does it mean how do we notice changes? How do we know which one to run and stuff? But >> I think now as people start to test it and see how it works, it's maybe not big of an issue.
I hope it won't be, but yeah, it was like very unexpected. But also they just use the latest available version with support because it's the net 8 which is expiring support or something in the end of the year >> and they just don't want a liability probably >> right. So no I think I think also the pirate people did great when they migrate to net core uh couple years ago. I think it's just a huge investment the path forward. >> Yeah.
Yeah. This is also where some people because parit was a bit late with the release for the ravit which was it 26 26 I think >> 25 >> I mean I 25 yeah and many people took it as a sign like we actually depend on developers and many people start looking more into C route and they I don't know I think many people still understood it many companies did their own fix in the first weeks and they could run it internally themselves because well there are ways to fix it but I also noted that Even given uh Nicholls he also switched to C# after that he saw that okay parade might because they didn't like the idea that they kind of have to sit and wait for kind of parade table but now parade kind of is more organized and I see like changes coming much sooner for new versions and stuff because I think they also noticed that this was a big kind of not big but it was kind of hit on community but now it's like more important like okay we have to make sure it's compatible >> 2026 in 2027 I think were released 24 hours later. Uh but they they're ready. So .NET 10 were uh implemented in uh I think November of last year and I think for um for part of it 5 and and Revit 2025 it's actually a working version was there around July. So 3 months after the release actually the people were were but it was >> so not everything was completely figured out but um um it it was a a moving target but I think now I think it's reached the reached a level of stability >> and even with the new loader um 2027 uh I think 4.6 is a very solid build that >> you know >> yep >> ready for the future and this is actually what we did for our company.
So uh couple years ago we are we are fragmented with we have our own tools built in C built by a third um third party um u company that we keep paying them every year to um to pretty much updates based on the new Revit API changes. Um >> and then we also have um a collection of Dynamo scripts that we run um to automate few tasks and uh we decided to to switch all into pyrovit because first we take the burden of having our scripts up to date within latest you know net build and it will be handled by by pyit >> granted you know I'll be participating into that but it's actually we don't have to worry about this technical debt. I think technical debt is the Gavin Nicole's um idea. It's like you if you build a tool uh you're responsible for maintaining it. >> And that's why we we modified our internal company tools and now they're all pirate based >> and uh speed difference is minimal.
It's unperceivable. Uh >> you mean between C# and private or what? >> Yeah. Uh it's it's not that different. I mean for the >> you know Revit it can be as fast as it can I mean it's the bottleneck is Revit itself >> right?
Yeah, >> it's not >> also I wonder since probably you had a discussion in a company why have you decided to double down on pirate instead of C# because many companies they usually start with parade but eventually they when people get more better better with code they get more access and more start to take it seriously some consider switch to C# so wonder what kind of conclusion you came came to >> um because we don't have a full-time software developer >> and the time if you go C# you need like full-time dedicated people Um, again, I'm I'm a project architect right now and I I probably dedicate four hours per week to do all, you know, any of the coding work. >> If I'm slow, if I have like 10 hours some week, I have 20 hours extra for slow, my project is, you know, pending or it's in permits. >> Uh, this is where I get into doing more heavy stuff. Uh but um my my my rule of thumb here, if you automate something, if you automate a task that takes 12 hours and you spend 12 hours to automate it, that's a win because actually you're you're solving a problem differently, but also you're generating a reusable product that you can solve the pro another problem with no time. >> Plus, you also learn on top of that.
>> Plus, yeah, it's learning. Um, so that's that's the formula one to one. Now, if it's if if you take if it takes you 20 hours to solve a 10-hour task, this becomes a little bit hard to sell. Uh, although it's maybe it's still valid win, you know, it's it's a it's a learning, you know, as you said, and also it's probably going to be reusable, but it's also you need to to justify that to the project managers like, hey, >> I spend a little bit more time on this, so I can use it. Um, and a lot of project managers, they really care about their project.
they don't want to be you know bothered about somebody investing in the future of other projects. Um. >> Mhm. >> But um so that's my formula one to one. If you spend in many cases um if I know this task will take me like two hours I really feel encouraged like hey let me set up a Python file.
Let me put a you know a push button here and there and I have I'm comfortable to solve it into ours. Um that's perfect. So um >> that's the reason why we got into power because we try to make it collect collective so people can write their own >> um and I think today I saw somebody is doing some form of like space planning tool and it's clearly a cloud project. So I haven't take took a look on it but I saw a a folder said extension. So somebody's actually know what they're doing.
>> Okay, that's cool. But it says beta and that person's initial. So it's probably they're still working on it. But that person is also not a software developer. But I mean getting into this now being API development becomes more accessible.
>> You don't need to worry about compiling about DLS about setting an addon file and >> it's just a folder structure. I think it's just >> yeah that's the point. >> Yeah. Yeah. I also have a parade starter kit which literally you just download it rename two folders you can even leave it as if you don't want just need to provide the path where you placed it that's it you have extension then alt click modify anything remove add it just so fast to learn this one many people don't realize what they realized no way it's so simp I was like I got to be hard then I start looking I'm like oh my god it's so simple why how what >> get you sucked in there yeah >> I find it now it's much easier than dynam itself >> especially with AI.
>> Yeah, >> what you mentioned about the formula this one to1 ratio like time spent time saved. I had the same thing when I started and this was like one of the biggest levers how what helped me learn but I was a bit more generous with the time I was okay to spend twice as much time on save time because I knew that first of all I'm learning second of all I use it second time I'm already even third time I save time sometimes even more like I could justify spending more time but I had no AI now with AI this one to1 ratio it's actually you can achieve way more >> because AI also do a lot of heavy lifting for you. A lot of thinking, a lot of debugging which I had to do manually. So 2:1 actually sounds like now more kind of a little bit how to say it not optimistic optimistic I would say because with AI it just speeds speeds you up literally 10 times. I'm not kidding about that one.
>> So yeah it's definitely something people need to just think about like just give it a try. See if you can take your 10our task and do it even in 10 hours with code. Sure, in the worst case, you would have to pause it and go do it manually. But sometimes it's really worth giving this little risk if there if time of the project obviously allows and deadlines because next time you're going to save less time, you're also going to get more confident, you're going to learn, each tool going to motivate you to do something more and yeah, it's really good kind of framework to adjust uh to implement. >> Um I think I think so I I had this this thought.
So you mentioned the pyro starter kit but um also my favorite product that you did is actually the FilteredElementCollector handbook. That thing is that thing is uh is probably the best tool that actually explains FilteredElementCollector and >> and the the especially the quick filters because I think for a lot of people sometimes >> achieving quick filters is um you know it it just speeds up your your product and I think it's probably you can take it and build a cloud skill based on that so it becomes like >> because I think in many cases I saw AI really prefers the slow filters just because it's just, you know, it's easier to go just filter element and FilteredElementCollector is probably used in every script. >> So, it's probably the most important uh API >> part of it. Um, but I think quick filters identifying what you know preferring quick filters is definitely a better >> in uh filtering objects. >> Mhm.
But the thing is it's a bit more technical. Maybe not exact for the port, but if people wonder about quick and slow filters, it's not really slow as as it sounds. It just means that it needs more memory of the elements. Cuz quick element, for example, you have a wall. For the quick element, it just looks at the basics.
The ID category, some other things which can be kind of accessed without opening the element. Slow filter, you just have to open the element in the memory. That's why it's called slow. Even though time wise, you won't notice a difference. Sometimes it's like 0000 0 1 second.
Even though they do different things as well because they kind of focus on different information. I just want to throw it out there because people always think slow filters is something bad. It just means that it focuses on more information, right? Therefore, it needs more to get more out of the >> um well Andrea from the you know the private cousin is is really big on on on this like every CPU cycle matters. So um when when review of code it's just like if you >> if you have a duplicate u you know functions needs to be a small and precise >> structure of it but also because he does that you know every day so he's very efficient and uh >> yeah it's in the it's the soft software developers who are like more and more into software >> they they have so many lessons on the um how to structure your code this notations how to understand the scale of the code and so on and they sometimes I heard stories when people spend a lot of time fixing something that changes maybe zero one second and on large like SAS companies like Facebook like met all of this it makes sense we have like billions of users but for the office with 10 people it doesn't matter like we can wait 5 seconds it's okay >> um yeah I think so for >> it's like yeah you're waiting so people doesn't complain about it but uh pirate is actually sometimes load it's around 1 minute if you go to the >> the apps Um, it's we're trying to slow uh to make it faster with a new loader.
We're also trying to um uh this is also probably to your audience. If if you're putting metadata in your um inside your script, we're planning to duplicate that one. So um >> no >> but we're providing we're we're discussing this um because it's actually takes a few loading time for sec a few seconds loading time and you take it to switch to like all bundle dot you know all the bundle uh files. >> I see. >> But we're providing a script for people is actually you run it on your extension.
It will generate the bundle files and transfer the metadata to >> Yeah. Yeah. It shouldn't be hard. I'm just so used to I'm thinking things Mark mentioned before that I should switch to bundle and stuff and I'm like no I'm going to hold to my code >> because I I just don't like having extra file just for this basics. I I don't mind having like title and all of that.
>> I don't know. I didn't know you were like the team trying to depreciate this feature. uh it's um it will be pirate 7.1 maybe it's like maybe air down the line but the idea is so we switched to C# for two reasons first it's becoming more um you know future proof or like upto-date um and I think that's that's a really uh good vision from Jean Mark >> and also um I think um speed although I really got excited first when when the first alpha showed Uh it was like 60% faster and I thought like oh so C# is actually way faster. >> You mean by extension, right? >> Yes.
>> Then I I didn't realize that it's actually faster because it's it's skipping most of the things. It's not loading any of the critical things. Doesn't reload icons properly. So it was it wasn't faster because it's faster. It's faster because it's not fully functional yet.
Once we start adding functionality and make it on par with the um with the legacy loader, it became same speed and in many cases there's a bug with the uh with telemetry server that can push that to telemetry server um entry in the >> pirate config. It will push it by another um like a I think I had private config.ini ini 40 megabytes and that really put my private loading time to like 3 minutes and they discovered there's a bug there's a PR on uh going on you know >> how how did you make it 40 megabytes that's a lot of text >> uh if you go if if you go to par part of it um config.ini INI and try to read you'll see some double spacing like JSON double spacing on the telemetry server entries. That's a bug that's you know we are fixing. >> Mhm. >> So I think I think some people need to test it and then we can um so it it keeps inflating inflating inflating until it becomes really big and it it slows down.
Um there also few few bugs that we solved and I think I think now C# loader is like 10 time 10% faster than the legacy. >> Okay, >> which makes sense but it's not going to be like instant like you know guardian like 1 second. It it will be like you know 20 30 seconds to load but if you compare this to Revit loading and you know opening a project will take you 20 minutes it's probably nothing that's being uh noticeable. >> Yeah. Yeah, it's fine.
Some people complain like how it takes 40 seconds to open it, but yeah, it saves hours later. >> Um, depends on how many how much toolbarss do you have also. >> Of course. Yeah. >> Yeah.
Yeah. There are some. >> I I used to download every extension, but then I decided maybe I I'll keep it to two. >> Yeah. I see.
No, it's interesting to hear from you as well about development, all this kind of behind the scenes what's going on. I want to get developers as well like Roman Go, some others. Um, >> you should get >> Yeah, I'm slowly getting into this podcast. I I don't even know how I find my guest now. I'm just like, who?
I just saw saw you popping up on LinkedIn. I'm like, I should get you on the podcast. >> I'm I'm not very active. I'm slightly I think I'm more active in this is what you I mean, I'm slight you can tell, you know, with 20 years of driving, I'm getting older. My social media is becoming the pretty much the GitHub.
Um, and you're slowly moving from one community to another. And I'm I'm really happy that my community is only like 85 people. >> Um, >> but with LinkedIn sometimes you need to do uh announcements related to to the works being done and uh >> to keep others in the loop. >> Yeah, for me I'm just trying to get a lot of parade developers to share their tools, share how they use it because well pretty much parade podcast that's what I do for now. He's just kind of randomly casually.
I'm going to get Jeremy Tamic on the show. He already agreed. >> Oh, nice. >> Gavin is coming again to talk about his C switch because I think it's going to be interesting to hear >> because he's like making like full first he's like super like Dynamo user then he's like super py and then now he's switching to C#. I see him getting more into software developer kind of mode.
Goes in much deeper this finicky topics like >> right. >> So it'll be interesting. Um once once I get into uh pyit I have every video from Gavin Nicole's the C uh journey. I'm gonna put it in my um in my in my watch list. >> I know that presentation we started with.
Right. >> I think it I think the I I see the benefits of C#. You don't have to deal with lists. Uh but it's I I'll take a look at it. Uh maybe I don't know.
Um I think both both languages are I just I feel like Python is more home for me. >> Yeah, exactly. I think that's the thing about C# and Python. Many people think that it's either one it's kind of one is better than the other. But I think there are just two camps.
>> I for example not planning to go to C#. I understand the syntax I can make like in a week and start making tools and give me a month I'm going to be pretty decent at that. Totally of >> of course there are different things I would have to relearn but I understand opt syntax because I just translated so much C# into Python manually that I just learned C# as a result of that but I just I don't know I don't know it's just it's just not my cup of tea Python I'm just only in Python I even remade the whole rate API documentation website using Python Django it's amazing >> people say Django slow I don't care it's fast for me actually you want me to quickly show you because I'm making a huge update. Maybe I share on the port and with you >> and you can roast it a little or maybe just let me see if Yeah, I think it's running. >> Uh I just need to share.
I think it's going to be cool. Can you see it? >> It's loading. Uh yeah, let me just make the screen slightly larger. >> I don't know.
>> Okay, sounds good. >> Oh, this is local host. Okay. >> Yeah. Yeah, it's local host is haven't pushed.
I can push it quickly, but I'm not finished. So, this is the what people see at ravit.com right now. This is the next one. >> This is what I this is my this is my go-to. Um I switched, you know, from uh Revit API docs to uh to your uh website.
This one I find it's better better search more visually appealing. So, >> yeah, >> I see. Yeah, >> the difference is I'm just going to go this is from Nonica Creator. uh cuz most of them they take the original kind of the layout of these HTMLs. This is what we get and this is all accessible.
>> I kind of hated it. It's fine. We got used to that. But I the thing is here I kind of I parsed all of it, got all the information out and rebuilt HTML. And this was the kind of first iteration worked pretty good.
>> Yeah. >> But now I'm on the second one here. So because now I finally pushed it not in like kind of cold files, it's all in database. Now I have full control of everything. It's going to be similar but I'm adding more and more features.
For example, now >> oh yes >> it's also I can look and say okay what each method is going to return and stuff like that. I can also mark here for example that one is native. You can see no inherited all the graved ones they inherited from somewhere. I'm also decide finally make a community snippets. So now I'm gonna get to that.
Yeah, people were asking for that one. So the comments also for some reason here it broke. I need to look into that. >> So now I'm kind of joining two. So first of all, it's going to be better.
Also, you can open multiple pages. I just went all in. Like since cloth code, I decided let's see how far I can push this. And I I could push it really far. >> The search here super snappy.
>> I can even show you things that's not possible by default. So it's just kind of good to run down what's coming. So I can see for example what is obsolete in that version. These are all obsolete items. Okay.
I can go through I can get better understanding what changed. Later I might do the full page breakdowns between the versions because now I already have this for example uh something changed here. Obsolete status something changed here like and it's missing here. So now I'm going all in into that like I want to make a really good place. I can even search let's say view I'm going to search for inheritance and there are like a lot more things but now it just looks at this box here and says is there like view for example if I go to I don't know view 3D obviously it's based on the view I'm going to go to I don't know I think render note yeah you see there's like view node so it's not you can also make it I think precise but the thing that I'm really really proud of now because I decided can I add gamification and I actually managed to pull this off so Now we we I'm making profiles.
I'm making like all this like I decided steal from G this feature like for activity, shared snippets, shared comments, everything. So I think it's going to be also like achievements. It's so fun to play around with that one. So I don't know how far I'm going to push it, but now I'm going to make a little bit social place for RA API developers, but 100% overkill for documentation, but I think it's fun. >> Um >> and also place to share snippets.
I think that one would be awesome >> because I heard it so many times. >> And another thing is that once you share for example uh can share here, you can write some description if you want to. You can comment on that. But what I really really wanted to do is link to pages because often times when you explore documentation, I heard it so many times people want to leave their own stuff in the docs and now we will be able to do that because this will be just community snippets whatever you want, right? because this syntax yeah is this in this case it's useless but now we will be able to kind of add more into that so your code snippets your thoughts and stuff I don't know how far I'm going to push it but I'm pushing it already beyond what we what anyone asked for this is really helpful especially if for people using AI um because now even AI if hallucinate you have a a a code snippet that is done by somebody and you can use it to >> pretty much provide rails to that AI too.
>> Yeah, that's true. >> Oh, that's that's a huge that's a huge uh step forward for for the API. >> Um >> yeah. Yeah, I think it's going to be fun. I don't know how people going to react to that in terms of do they really need it, but I think there are certain few who will just absolutely love this thing.
So, I hope it's not going to break as much, but I will just fix here and there things overall. also the leaderboards because I think if we make it like more communitydriven, people are more motivated to share. They're going to like, oh, if I share, I'm going to level up. I can also like others and stuff. So, yeah, I'm still kind of playing around, see how far and I can push it and so on.
But so far, I love the idea that maybe also it can turn into marketplace because people sometimes look for rate API developers. I can add here page something people can put themselves out. >> Yep. >> Yeah. If you have any suggestions of what you've been missing from docs in general, would love to hear that.
>> There actually I I don't I don't miss anything. Uh I see the the examples you already implemented. Although I didn't use them that much. The um I think the there's the API docs.co the other the older uh website had some examples, but I didn't really bother with them a lot. >> Oh yeah, you scrape the GitHub.
It's not always perfect, but overall, yeah, it was also good to it's often great to grab some examples. I think later I'm going to just scrape GitHub and try to just kind of either take examples or just full working tools relate to some places. So, you know, we have a lot of reference. So, while Ravit API is mostly C oriented, I think this doc is going to be Python oriented most. >> I have a lot of plans for that.
>> Yeah. So, that's just something I want to share. I thought it was going to be a nice thing to share on the pod as well to show people what's coming. >> Yeah. Yeah.
Uh, of course, that's uh another another since since Revit, I think I'm my excitement is consistent with uh with uh with Revit now. It's always, you know, you get excited a year and then you you you lose it to the next year. But I think this one is, you know, community projects is >> Yeah. Uh, pyRevit also made me so so much more excited about Revit in general >> cuz I started getting once you get to certain point where you get really good at Revit, you start to encounter so many things that needs fixing, needs solution. There are always workarounds.
At certain point, you just get tired of all of that. You're like, come on again. You already know when you have a problem, it's going to be a workaround, not a solution, >> right? And um, I don't know if you so there's a few things coming to Pyrovit as well when it comes to the UI. Um I see that the um so the split button is is being implemented but I think there is the combox button and I think there is a checkbox button and it's it reflects the new ribbon updates in in the latest Revit versions.
I think there's one on the forum. Uh somebody did the combox button. Um >> Oh yeah yeah I know what you mean. I saw it somewhere. Not here.
Where was it? Maybe an issues. >> I think it's probably in this. Yeah. 6.4.
I think it's probably being added. Um. Oops. >> Yeah. >> UI.
UI. Is there like UI? >> If you scroll down a little bit, I think it's uh >> I saw somewhere. So, local. Yeah, I saw some changes also.
I think I need we need to document that. I'm thinking that maybe in the future just go through all of that and kind of show step by step what's going on. But I just need to also myself track what's happening because I was on like five versions behind because when I do tutorials I like to stay a little bit I had times I don't know pirate never gave me issues updating but I just have the habit to not update while everything works and it comes mostly from video editing software. Every time I update, I have to spend like a few weekends fixing some stuff and stuff like that. So, I'm always afraid to update stuff because of recordings.
>> But yeah, I think I need to get back into that because there are many things that I've never heard of. I just hear from people here and there just like what you can change the background now. Oh, just Oh, interesting. >> And stuff like that. So, I miss a lot of updates.
I think there's this is pretty much the best place to get it. Just go straight to GitHub, go through and read it. But it's also well everything is text. It's not always easy to go and read. >> Yeah.
Um, another thing that I'm planning to do is actually uh looking forward is um I still think there is I mean AI can write fancy WPF but for I think for a quick prototype most of my tools actually use a flex form. Uh >> and what I'm missing with the flex form is uh radio button. I saw somebody added on a sample script that they actually >> instead of adding it to the to the uh flex form, they added a >> WPF um radio button to it. But I'm planning to add a slider >> and if you want to like it just like a like an integer a number with a slider. >> I think uh >> I think I had it somewhere.
>> It should it shouldn't be that hard and I know where to steal the code from. Um I think the um Dynamo data shapes it's the similar to flex form it's the WPF tools for building >> Dynamo right >> yeah so I think I can um I I think I remember I saw a slider there I just go there and take the function >> there is an element some kind of slider in VPF it's not hard to just have to kind of set the updater I I get it somewhere I definitely have a tool with some kind of slider just for fun, >> right? >> Uh but I don't think my >> WPF is very easy. Yeah. I just need to to put it put it there.
>> No, it's still not easy. But >> it's a it's a unique thing this BPF. >> Yeah. >> Yeah. Um we are almost two hours in.
I think we need to wrap it up. So I later don't regret editing. Was amazing having you on the show. Just one thing I like to ask in the end kind of all guests also their kind of number one advice to beginners >> right >> so somebody who is just getting into pirate maybe just heard about pirate what would you say >> I think they just need to do it first thing and also don't do my mistakes that uh I I I encourage people to join your um your uh part of a challenge just because um first you get intense focus and actually learning by doing instead of actually waiting and binge watching because I still have the you started this episode I had the uh the Revit API workshop from AU 2009 and it's still there not being implemented. Um so maybe if I paid money for it I probably I should have attended and learned it.
Um, you know, free lunch is not always good lunch. Um, so, um, I think they just need to to lean in and just be get into there and >> Yeah, just make the first step, right? >> Yeah. >> Just a good one. >> Just jump just jump into it.
And I think it's just like if if again it just took one one you just create one button maybe would you know start with the starting kit and I think um the rest will be history. >> Mhm. >> Yeah. >> Yeah definitely. Also the every next tools get so much better and easier to do >> and some people told me that what if you know what what if I learn this and Autodesk decide to pull the plug on Revit.
Mhm. If Autodisk pull the plug in Revit, your problem will be much better much worse than your problem will be much worse than actually learning Revit API or not. At that point probably firms will lose their entire archive you know of their project. uh also I think it's uh it's not going to happen uh because they need to provide product out and uh also I I was thinking yesterday if autodisk do AI does it mean that if the AI needs to go and upgrade every model to the latest Revit version which will take you know hours of compute time. Um, >> I feel like it's going to be a rough moment, but I think it's just the people who are willing to learn are going to be the winners here.
>> Mhm. >> That sounds >> a lot of uncertaintities, but definitely and uh for people who said forma will replace Revit in people 2003, 2023. So 3 years ago people told me in 5 years there will be no Autodesk uh desktop applications because everybody is going to switch to forma. Uh good luck. I don't think it's it's going to happen.
>> I think it's their dream but I don't know going there because once they make the switch people start considering options as well. >> Yeah. I don't know. I also don't believe Ravit is going to disappear. As much as everyone wants Ravit killer and Ravit to just die out.
It's it's a big money maker. It just holds the title of most used beam software. It's it's here to stay for a long time. I don't know what's going to happen with it. Yeah.
>> Also, the reason why the only reason why I think ACC like a former uh like a document management holds advantage over the other competitors is just because it natively works with with Revit. >> Yeah. Compatibility. Um otherwise people will jump to Procore Box you know Dropbox easily if they because I know for sure we tried to utilize um like a Dropbox initially for u syncing central Revit files that was like 2017 and uh that didn't work. It's not doesn't have the native >> um >> like the unified database that Autodesk offers with with ACC.
So um if you lose rabbit I think you'll lose your uh the cloud game as well. >> Yeah they kind of forced it on users as well. There are not not many many alternatives and if there are well you're losing something here or there. >> Yeah. Well the good point is like Python skill here to stay I don't know like I love Python is definitely not moving anywhere.
It's just going forward especially with AI. what I learned from Python. Yeah, what I learned through, you know, from Python through uh Dynamo and um Grasshopper is actually easily transferable to pyrovate and also easily transferable to other applications. >> Yeah. Yeah, definitely.
Funny enough that people still hate Python being inefficient, slow and stuff in comparison to other languages, but funny enough, the whole AI frameworks, the most popular frameworks, they all built on Python. Yeah, I think >> cloud runs Python code when when executing, right? >> Uh I think I don't I don't know. >> I know that all these kind of main kind of frameworks for AI they are in Python which is uh I was always kind of surprised about that but I think they still certain parts still going to be rewritten in C++ where efficiency matters in this kind of stuff but for AI like training and stuff Python seems to be the king which I really really love to hear. It is it is definitely a growing language.
It's actually my first interaction with uh Python was with Maya in 2008 when they released Maya had u like a scripting language called me Maya embedded language and suddenly they added Python and everybody was excited. I didn't really get it that time, but it's actually when you start doing like for loops, while loops, conditional statements and you start doing like you know functions. This is definitely uh a step forward from being just a random scripting language and your expression to actually >> Yeah. Yeah. >> Yeah.
Once you move out of software, the skill is kind of gone. But Python, it it just stays like you can do anything. I even edited videos with Python when I was just like playing around see what I can do. I saw that um I saw your videos about uh the dark theme colors with uh with Python. >> Yeah, that was that was cool video.
>> There's a lot of people who are really um because I think the dark theme was introduced in 2024. Uh before that >> before that if you have a toolbar before that you probably need to recreate your icons and having you know that script that's actually >> generate the the dark theme icons. Now I decided I just gonna take colored icons from default. So they both work in light and dark theme because that that one worked but it becomes I don't know a little bit too flat you know just single color maybe two colors. It's just my initial icons were this kind of just black and white.
Now I like to like in like par challenge for example I have this like colored one for fun and I don't care if it changes like it's red and white and dark same red. I saw somebody's toolbar on LinkedIn where it's actually animated GIF animated GIF. >> Yeah. Yeah. So Nonica has this thing as well.
The thing at least that's where I first saw I'm like oh you can put GIFs there somehow. >> Exposed by the pirate API but um >> not yet. >> Not yet. I think we have bigger problems than animated GIFs. >> I have bigger problems to to solve.
>> Yeah, it's probably low. It adds to the load time as well. So not the best thing to focus on. Yeah. But um I think you just wrap it up here.
So thank you coming on the show, Tai. So it was really good talk. You shared a lot about pirate and just your thoughts in general where it's moving. Really appreciate you joining here. >> Uh could you share your social links where people can find you which if you want people if you want people to contact you anything like so just do your own plug please.
Uh LinkedIn is probably the easiest way to find my name. Um >> and I I talk to everybody. >> Yes. Um anything related to Parvit just go uh you'll find me on the GitHub. You can mention me and into any issue if you have or any questions.
Now issues is not you don't need to go to GitHub to only complain about an issue. You can also go and suggest new features and also you can offer help if you want like anybody can just go and uh go there and uh be part of it. Um yeah um LinkedIn and I I had I had a website I I don't maintain it. I just used it for old design competitions that I stopped doing it. I think you know uh I used to have a lot of time uh before the kids.
So I uh I I I don't do it now. And uh I think it's uh yeah and if you're in San Francisco just you know text me and you know we'll meet over there. >> Very nice. I'm going to leave all the links below. You can send me on LinkedIn or somewhere.
I'm just going to paste all the links you want to like website, GitHub and stuff so people can actually find you and chat with you if you they want to. And also a quick question to the audience. I hope that you enjoyed this episode and just let me know in the comments who else I should bring on the podcast. Maybe you have some expert in mind or maybe even topic, right? If you don't know the person, just let me know what we should explore next.
Maybe some MEP parate users, maybe structure, I don't know. Just let me know. I'm going to find somebody to come in and talk about this. And as usually, thank you for joining and happy coding.
### Fully Agentic AI Development for pyRevit with Jonatan Jacobsson | pyRevitPodcast #7
https://learnrevitapi.com/podcast/py-pod-07-jonatan-jacobsson/
Jonatan Jacobsson from a Swedish construction management firm on fully agentic AI development for pyRevit and the AI workflows he uses. pyRevit Podcast #7.
## Transcript
Hi everybody, welcome to Power Rated podcast number seven and today we're going to have a very interesting topic definitely something that many of you wonder about and it's going to be mostly about probably AI workflows for working with Pyrait and I brought a really good guest for that because he was experimenting for quite a long time with that. So welcome on the show Jonathan how are you? >> Thanks Erik for having me on. >> Yeah I'm good. My >> pleasure.
Yeah. >> So Jonathan uh for people who don't know you could you just introduce yourself who you work as? What is your experience? So just kind of quick kind of background. >> Uh yeah, the name is I work at a small firm in Sweden called Big Steing.
Uh we do construction management. Um helping the building owner from like the first idea for a plot to a hand over to whoever going to hand going to own the building after we're finished. Um so we helped them through all the uh earlier phase design. Um but our core uh strength is on uh construction management onsite using um what we would like to call total beam practices using open um like open um open beam. >> Oh so you practice open beam as well very much in your company.
>> Yeah as much as we can on the construction site. Yeah, that's also interesting topic because well many people treat open beam very differently at least in my experience even though like there are some standards there's like I see the schemas and so on but usually people break break it to their own ways. >> Yeah. Yeah. >> Yeah.
I think we can dive into that later as well but also let's just go a little bit back in your background because I want to find a little bit more about how you discovered Ravit >> uh and then we're going to go from there. I started uh my first uni tour, university tour was uh was in web development. Um but uh yeah, I dropped out at work worked uh as a web developer doing intra nets and stuff um back in like 2011 12. >> Uh and then uh started um my journey as a construction engineer. >> Mhm.
went three years to uni and then worked as on an in an architectural company uh until like 204 um a few years uh where I quickly became the Revit uh guy or nerd to talk to >> uh for all issues regarding Revit and like it stuff around that and I could keep the programming uh like skill alive during that time um both the web part and uh like I I mean I once I started opening Revit like the first year maybe I just like use native Revit and whatever tools I could get my hands on. Uh but like eventually I popped the hood and like used the Dynamo and eventually got into pyRevit a lot. >> So you you already had kind of programming background from this web development. Yeah. I don't mean like HTML CSS but you knew JavaScript probably.
And what what languages did you know? >> I mean at that part like all uh we did a lot of WordPress and PHP and >> like uh like ASP files over I'm just getting PSD just uh trying to talk about it but yeah uh we did a lot of like front and back end stuff. >> Mhm. I see. Um what I'm trying to understand is like when you started with Dynamo so you you already had programming background which is definitely going to be helpful because many people don't do that don't have that when they start with Dynamo.
Uh did you know any Python when you started with Dynamo? No, no, Python uh I started like using Python. Yeah. Within uh within Dynamo first and then I mean once I got into uh >> realized that I mean all the depart deployment issues that we had with Dynamo back in the day and like when I started this uh started that big streaming we went all in I went all into private. >> I see the I see this pattern over and over.
The main reason people jump from Dynamo to pirate is like probably this phrase like well it works on my machine like >> yeah everybody had to say it at least once otherwise you're not real Dynamo developer at least not back in the day now it's better I think >> hey it probably is better uh I have colleagues that use it to do like small off uh but they still use Python inside I know web due to >> all of it >> especially today with AI it's going to be so much easier to like create a Python node drop There's some code test test until it works because AI I don't know if there are workflow to find the real node drop it on the canvas with AI. So not sure if there is something like this. >> Yeah, I've completely dropped Dynamo from my toolbox that I use. So maybe it's good now but uh >> yeah yeah same. So >> you'll have to convince me.
>> Oh no, I'm not going to convince you. Like stay where you are. It sounds good. >> All right, so let's just jump back a little bit to Dynamo. I just want to see for how long did you use it?
What kind of problems you tried to solve it when you started? >> Yeah, so I started uh with Dynamo when we worked at a big uh big hospital here in uh my county. >> And then um yeah, some of the problems could have like reading and setting parameters, grouping stuff. Uh so to begin with it it was more like uh throwing data around. >> Mhm.
>> Uh for for setting door parameters and figuring out what door handle you need etc etc. >> I'm having flashback as well as you name all these. Uh so that's where I started um and like doing uh like door numbering schemas within uh Dynamo due to all of these whatever 50 parameters that we had. >> Mhm. Uh but uh we did uh some geometric processing as well like uh we have we had the fire engineer in AutoCAD at the time.
Uh and then they drew all of these fire uh requirements as lines in the DVG and then we we had some Dynamo scripts to like import those and write that parameter uh based on the layer of the line or like the property of the line. And then you could set some fire requirements on the walls. Something like some geometric processing like that as well. >> Uh I mean we I mean I think I had like 50 in the end of that project. We have like 50 uh >> Dynamo files from that project.
So it it was definitely like a learning uh tool. And >> Mhm. >> So I learned a lot of stupid I did a lot of stupid stuff with Dynamo and a lot of like some of them like ped up to other project. >> Sometimes it's fun when you work with geometry especially when you make a mistake and you just randomly get some weird shapes. You're like, "Oh, that kind of looks nice but not what I need." No, no, no, no.
And uh were you like alone or did anyone else understood dynamo? Like did you have anyone >> firm at the time I was alone? Uh >> okay. Yeah, that's very common. Hard to explain what you do, right?
People just know like, okay, just give him a problem. Don't touch him. Something happens, >> right? >> Yeah, that was Yeah, that was my job a lot of the times. >> Yeah, that's a cool position to be in >> and you learn a lot of you learn a lot like jumping between projects and uh solving problems.
I mean I I I love it to you up with projects and uh I I like to describe myself as like a BIM torpedo like torpedo. So like to uh I I like to to uh from scratch find a find a new problem and solve it. So that's >> I noticed that also people who start with dynamo programming in general sometimes we try to like automate everything. Not everything needs to be automated, just to be clear. But some, but that doesn't matter.
Sometimes you're like, I'm going to do it with code. >> Yeah. Yeah. I have to I have to like constantly read the the XD CD comic about uh remind myself to not automate everything that I uh do because it's so >> it can be rewarding, but it's >> time wise for a lot of things. >> Okay, let's make a quick test.
Have you ever automated something that already exists in Ravit natively? Did you make any of the tools that already exist? >> I I've probably I probably have uh a lot of the times. Yeah, I mean sometimes because you don't really like some features maybe like too um yeah, you haven't touched them like if you for example for like one case could be >> where I've mostly worked at an architectural office while I worked at that firm uh at Aphrey but uh like in my current job we I work as uh I support all of the disciplines in our projects So I I can have their models open all of them at the same time >> and like jump between and help help out in the models. Um so in that sense there's a lot of parts that I haven't touched in Revit uh like MVP stuff and structural engineering stuff.
So there's definitely some tools uh that I created along the way that already exist. Uh yeah, for sure. M it's it's kind of funny. I also had a few few of those. Usually they don't take much time but you make something and then you find like oh it actually exists in Revit.
I didn't know that. Then then it's like awkward. You're like do I delete it or do I pretend it's normal? Okay. I see.
So you started with Dynamo. You started automating this common issues especially with parameter geometry and so on. And can you share how far did you push Dynamo before you started looking for kind of better way with to kind of switch to Pyavit right you mentioned that you had some deployment issues can you just share on that one how far did you push Dynamo before the switch >> yeah I mean I didn't uh we didn't have like a yeah for that deployment issue because that was that was kind of the main theme like it it was so hard to to move past working on someone's machine or like promoting into someone's machine and fixing it to the work. Um, we didn't go like full into that to actually try to deploy like using the tools that were available then like network shares stuff. But eventually some to be able to make it user friendly you need it you need buttons on a tab.
>> Mhm. And that's where like uh the journey for pyrovate began like just simple really simple shortcuts within projects to to get some to to get to where we have the families or >> uh some project internets and stuff. Yeah, that's where it's >> how how did you discover paravit? >> I mean I guess it was through all the online forums and YouTube but uh >> Okay. So just one Google search.
Huh? Yeah. >> Solution. >> I mean in when I worked with Dynamo, Parvit eventually dropped like like um popped up. >> Mhm.
>> Uh and I started using like Yeah, this is was now we're talking about like the development for pyRevit, but I used pyRevit as soon as I got it. Uh just to like and I >> while working as an architecture engineer. >> Okay. So you had this tab in. I had it open, but I Yeah, I had it open, but I I I just didn't realize that how how easy it was to to create new buttons and stuff.
Uh but um so like when I worked as like architecture engineer, like I used the like memory feature for selections a ton. uh this like you where you append or write or read the selections >> to effectively jump uh between stuff in Revit. So that was kind of the main features I used as an architecture engineer to start with. >> I see. >> And have you considered C when you're moving from Dynamo?
Like there's usually Py to C. For me, I uh I always like um I when I started out, I compared Python to JavaScript so much because it was so easily like the syntax were kind of um were kind of clear or kind of similar in a way and you could um so I never really got into uh C that >> okay. So you wanted to stay in your like comfort comfort zone with Python and stuff. it. Yeah, it it felt more natural to be to begin with having learned like native JavaScript.
It was it was Python was easily read readable for me. Um >> Mhm. >> and like the way you the way parit works um structuring the Python files is kind of similar and how you could do it with JavaScript. Uh Mhm. >> So it's like C f it feels it still feels like uh I mean I now I can do it with AI but I I can't like start a C# project from scratch never >> that feels uh too hard for me that >> I mean I think if you would want to you would also wanted to make the switch but I remember talking to Ashen the part that >> and he shared something that resonated so much that usually well there are lots of languages and different people kind of root for different ones.
>> Mhm. >> But also uh once you find a language that makes sense most to you and how you think usually you kind of drop out all the other ones. This is like the one for you and I feel like for you this is also Python because for me I understand C. I could also get into that but I don't want to like it's not my kind of I don't enjoy watching C code but I like to see clean Python code especially when it's very readable structured nicely. This is nice.
>> I agree. >> All right. So, and how was the switch to Power Ravit? Was it like easy? Cuz this was still before the AI, right?
Do you remember approximately the year when it happened? >> I mean, it's definitely like before and after AI. >> Mhm. >> Um, but I guess we we did our like first custom uh pyRevit uh things that maybe 2020 or 2021 or something. Yeah, somewhere around that.
I'm just guessing I I don't have this uh in my head but I guess >> so after this co this whole thing started somewhere you start >> somewhere around that we started like using private more in the firm uh >> Mhm. And how was the transition from Dynamo to parave it? Was it like straightforward like >> Yeah, it was easier to deploy uh because it you point you you point the user to do like two things. Install pirate and then link some network share with >> yeah the private extension and then off they go. >> Yeah, deployment definitely.
I was more meaning like creating tools because in Dynamo you still have nodes. Some people have very strong habits to using nodes. But this one, >> yeah, it feel for me it it as a programmer, it felt natural to to okay code. >> Oh, makes sense. >> So that switch wasn't too hard since I had the programmer.
I could read code. I mean, I can read C#, but I don't I can't write it. I can I mean I can read the code and like once you have like familiarity with like Revit API and stuff it's yeah you can review uh like what the code what the some function or something but maybe you don't know like the ins and out of like memory management on all yeah all of the niche stuff. >> Yeah it's also extensive documentation you can't really know everything. I'm still learning things here and there.
What are like your most favorite tools that you created since you like kind of moved in? Like what are the like the highlights of your extension? Let's say because you have also I'm going to butcher it but it's called pi booking something. Yeah. Prefix by pi as the theme goes for py.
>> I'm going to I'm going to leave a link in description guys. You can read it on your own. >> But yeah. So what is your highlight tools? Do you >> I think what I personally uh use the most myself is the color elements feature that I use that extensively like while reviewing models and jumping in and fixing stuff.
That's maybe that's one that I use the most myself at the moment. And then I mean that's also where like the code base has grown has grown like maybe a bit too expensive for a single Python script. you mentioned like you you want like clean understandable code maybe you would puke reviewing this it's like 3,000 rows Python at the moment I really need to refactor it >> to make it more like m level but at current that's why I will use the most >> 3,000 lines is because of the UI or >> yeah I mean uh the combination with >> uh UI >> once you start using UI code just like triples or quadruples really quick because now I have to define all the buttons. What happens when you click and so on and >> yeah I also noticed like once I introduce UI my codes look and then like at first I'm like what did I do then I'm like oh it's just like this is for this button and then like yeah but yeah so 3,000 makes sense because if you didn't have UI I would I would be wondering what's going on there. >> Yeah.
Yeah. Yeah, I mean when I start developing some script, I always try to use just just to get the ball running uh correctly uh I usually go with like pyravit UI forms and stuff that already exists >> just to see like does the interactive work? Can I quickly iterate? Uh that's usually where I start from when I have things from scratch. >> Uh but eventually I I have a pattern that I reuse.
Yeah, the native pirate forms. For people who don't know, you can type just py rait effective input and you'll see a page. I'm going to probably show it on the screen as well >> where you have a bunch of code snippets which are usually like one two lines of code and you have a form right away. This is what Dynamo users often see and they're like no way because well UI in Dynamo was a this kind of touchy topic. >> But in par once we got that that was so kind of liberating because you can create like select from list, select views, sheets.
It was very quick especially for development. I still use it to this day as well all the time. Sometimes I even leave it and like a the tool works. I can fix it some other day. >> All right.
So let's maybe move to closer to the main topic. So you're working on your pirate extension and then AI drops, right? It was chat GBT was like free. No, it was before free. I remember it was in November I think 21.
So did you start using it right away or how was your introduction to par uh to AI just in general? >> Yeah, I w I my journey was uh SH GP like 3 something 3.5 or something that's maybe where I like the first night that I spent like awake totally couldn't fall asleep. Um yeah. So like the uh it started with like the realization of that now I can create like uh small prototypes for like JavaScript and HTML uh at what I then thought could be like incredibly fast. I could iterate a lot faster um than me writing the code uh myself.
like I'm not a like 10x engineer by any means writing code. >> Um but uh yeah, but that's when I realized like maybe this this is definitely the future. Maybe I have to re uh rethink what I I actually do or how I do things. So that's uh but and at that point just uh you there was no like integrations to anything really. So I mean it was copy paste >> between shipdity and whatever ID you used.
>> Oh, it was still amazing. >> And it was still good. I mean >> now we're getting lazy. We're like no integration not interested. >> I mean it was still good and it was priced reasonably which good also >> very cheap considering what you get.
Now we again get super picky. were like 20 euro a month for this even though it's like life-changing like thing. >> Interesting. >> Yeah. So that's when I started and then you eventually use I started with like dumping in ideas for pyRevit scripts dumping in like templates some of your templates like or some feature like functions uh or scripts for from pyRevit like dumping in that uh dropping in on the day and dropping in like drop copying pasting in some Python files and then see how it attempt >> to solve and then uh like dumping logs between it until it worked.
>> Yeah. >> Mhm. >> But some some parts of that still remain but they are all tool calls now like reading scripts, reviewing them, updating them, running them, debugging them. Maybe this loop is the same. Yeah.
For >> you mean like you mean like you made the skills or what do you mean? >> Yeah. some use these are either implemented in the ids the programming ids or or like custom tooling u which is something we can talk about later on here. Yeah, I think we can slowly start diving into the main topic because you said that you want to share this kind of agentic workflow using cursor operated development. >> I think nowadays you said you don't write as much code.
You mostly kind of torture AI to make it for you, right? >> Yeah, that's Yeah, that's definitely my way of working at the moment. Uh I've gotten too lazy, I'm afraid, to like write it myself or researching every feature myself. I usually have try to have as uh as many agents running in parallel as I can. >> How far can you push it this way when you start kind of like do you do you give it like multi kind of step task right away?
You slowly build it up? How do you >> My usually uh approach is to uh like um thinking out the idea and and like dumping in every idea that I have to begin with referencing like uh scripts that I already have up um or like uh to other tools that are on GitHub or something referencing dumping in uh URLs and stuff for it to research and then having um cursor do a plan mode. They have different modes um where it it doesn't really create anything yet. It just creates a plan based on what you prompted >> and then >> yeah like totally straight >> and then you iterate on that plan until it's like when you you review the plan. This is kind of what I'm uh after and then you switch your model to something that's not expensive and then you fire it off and then once it's done you start debugging until it works.
Uh basically >> and that loop can take I mean it's for simple stuff it could take like one shot the entire script but most of the time we're not doing like simple yeah select walls uh or something but it's usually like a combination of things or like the UI uh needs some debugging and stuff until it works >> or maybe the assumption that they did well while planning was wrong and Yeah, you have to fix the underlying assumption. This is all like programming in a nutshell basically. Yeah, you start you have one >> you have like a hinge of what you're what you're looking for, >> but you you need to to iterate on that feedback loop as fast as possible. Um my bottleneck at the moment is is um like I usually want to have a Revit open and then cursor open and having an agent working through my script, >> but I the uh like bottleneck for me at the moment is testing that script in Revit. Mhm.
>> I at some point at some point I need to have some >> like MCP thingy clicking the buttons for me in uh in in par like reloading re reloading um Revit hello pyRevit u and the clicking the script you need to test. Yeah >> that's my bottleneck at the moment. Maybe someone has solved that but I haven't got it >> because that's what I wanted to ask if you because Herser usually does does its thing and then either ask you to test it or test it itself and I know people definitely have this workflows where it can execute in Revit itself get the output and kind of keep working. I saw this workflows I think before MCPS as well. So people but they kind of rewrote parit a bit.
So it was a bit they went really deep into that. But now with MCPS maybe it's simpler because now we can just connect it send it and get the output. >> Yeah. And you can have like rules in uh like u like a within the plan for cursor. I guess you could have like uh when it starts to uh write the code it always writes like u like extensive debug logging and then when it's once it runs it's uh double checks how it's working.
But for me, I usually um plan in a in the like more expensive models and then write the code in a more um like a cheaper model and then debug a few times maybe like 10 rounds or something. That's usually where I you need >> what you need to create a feature or something or add something. >> Do you find it more efficient this way? because I came to conclusion that oftent times it's just worth to pay extra for like Opus or like this Deep Seek V3 or whatever is their latest one to kind of try to oneshot it because the dumb model sometimes you spend a lot of time back and forth a lot of time and like you still save on tokens but sometimes it takes you like extra hour maybe to get there or at least >> yeah I haven't really like benched my like I have trial and error And this is what I do now like full-time basically. I sit I I think I use cursor more now than I use Revit.
Um so um but we do a lot of web development and stuff as well. So >> like for the dashboards for the analytics and stuff, >> we have the like uh small like hub project hubs um custom hubs or we work a lot a lot of it like in self-hosted environments uh because some of the projects we can't work in the cloud. So then you have to do >> uh you have to yeah you have to have stuff in self-hosted environments. So all of a sudden like PowerBI isn't suited as a dashboard or like uh all of a sudden you can't use u to uh yeah for all of the things you want ACC for >> or like format sorry. Um >> no they keep changing the name.
>> Uh so then we do a lot of like programming inside those project environments that are like secure by default. Then >> Mhm. Yeah. But the AI is crazy good with web development nowadays. >> I mean my bottleneck in web development is my imagination.
That's what I think at the moment. Like it if I run like Opus for like a large task for the things we do, it it gets gets us pretty far. Uh >> but uh >> we're not serving like 1 million customers. We're s will we're serving in projects maybe a few hundreds. So it's the uh it doesn't have to be like super super efficient or like uh >> Mhm.
>> for the things we do. It has to be secure. That's what it has to be. >> Secure. Yeah.
>> But it's also good at that nowadays. I don't know. I love how far you can push it. >> But yeah. >> Uh I think well web development is really exciting to Yeah, I like this topic.
I just try to hold myself not to go too deep into that because most people came here for like Power Ravit and this AI workflow. So, I think just going to move back a bit. >> Yep. >> Uh do you want to dive straight into the topic because you you share that you don't mind showing us a demo of your kind of workflow and I think it's going to make a lot more sense. >> Yeah.
Um and also I think maybe a good question to begin with. You mentioned you're using cursor for this hygieneic workflows. Can you also share why cursor and not like cloudcode or copilot or one of these other thousand tools that coming out every week? And you're also not sharing your screen by the way. >> Yeah, I'm I Yeah.
So, uh this is my extension. It's it's uh we want this to be used in our projects uh and be able to have like a starting uh a point like get us gets us to a we want to use this as a um a tool that we can iterate on when like native features and everything doesn't do what we want. Maybe we have to automate something in our project. Um that's where we we really want to like have a some way of like adding tools to our project that we can uh define ourselves. So that's the starting origin for this uh tool set.
>> Mhm. >> Um let's see here. So the it has grown a bit from the um image on GitHub but when people install it they through pyit and extensions this is what they get. >> Um >> and this is just like a normal um template model from Autodesk. Um, I mean we talked about deployment.
Um, we since we I mean I have users calling me like maybe once or twice a week to fix something or something's broken or something. Yeah, this it it needs to take this use case into account or stuff like that. Um the only thing that they have to do on their machine is just clicking reload here and then they'll get the latest from GitHub uh which is our repository for the entire um tool set. And I just recently added a feature for like branching um >> Oh yeah, >> due to the like the forum or like on your discord forum, Erik. >> Mhm.
Yeah, I remember you shared screenshot. This is pretty good one. So this allows us to like um test things uh in like I like more on isolation. So some some of these features uh can be developed and like deployed um >> Mhm. >> separately to test things out.
So this is a feature that we added yesterday from a project and I have a user testing that today. they can just uh click this button and then >> I'll direct them to switch to the feature and then they'll switch and reload and then >> um they'll get that button or that part version of the button >> and then I'll merge it to the master then later on when it's uh completed. >> No, that's a good workflow. Also for people who are not familiar with GitHub just going to quickly explain that branching is like parallel state of the project. Think of like a folder then you copy paste it to have second folder and it can work in parallel and then there is a way to bring it back and merge back.
That's pretty much the branching like in a nutshell. Yeah. No, that's a cool feature. When you share the screenshot how it works, I was like, "Oh, that's actually very nice, very clean workflow." >> And maybe we'll dive into that having other version of branching since get has a lot of uh other tools we could use as well. Yeah.
>> Mhm. >> Um I don't know where do we start? I mean should we I don't know if it's any point of like diving into u like the code base for the extension. Maybe that doesn't make any sense. >> If you want to explain certain things like show the branching explain how it works that's fine.
If you have tools you really want to explain in depth that's fine. But we can also dive straight kind of into cursor. >> Mhm. >> That that's fine by me. Whatever you feel is kind of more natural flowing to you.
>> Yeah. My I can explain how I can briefly explain how cursor works and how I usually use it. >> Yeah. So first we can also start why cursor and not like copile cloud code and all of these. I uh I did some testing earlier on and I guess cursor was uh it fitted it fit.
Uh I from my end uh viewpoint I came from like VS Code uh and since cursor at the beginning was a like a VS Code fork or like a copy basically of uh VS Code >> um it felt more natural. Uh I have I am not like a a programmer that only uses the terminal like I'm I'm not a terminal ninja h at that point as I see people who use cloud code are um more like familiar with using like tools like Vim or when they do everything in um for me cursor at the beginning felt more natural to use. Um and uh yeah and I still my mental model of the code is still like a this like a directory of files um that I like can interactively click on and stuff. So it it's it uh for me it hits a sweet spot where I can still like use agents to do like all of the coding but I can still review the code uh as my like mental model. um is suited or like uh or I'm how I'm myself programmed to you called so it's it kind of fits my mental model uh of my like ideal programming environment better.
>> Okay, that's fine. >> They have just recently released they call it like an agent window. That's why I'm usually now sitting because I like I' I I've switched to like like the VS Code way of looking at um my code and just just using this agent uh window at feels more natural for me at the end. But I still used back to like Claude, I still use uh uh like I love the cloud models. They fit me perfectly um >> Mhm.
for my like how I solve problems. Um um if you use like aentic uh programming a lot, it it's kind of like how you how you get used to uh like an ID and how the IDE treats your codebase and how you jump between stuff and edit stuff. Uh at some point you you start to get a feel for the model as well. Like you can sort of like I can sort of know how >> uh how it will plan out features. Uh, and if I like u use maybe some of the like Google um uh like yeah open AI or Google models uh I don't get the same results that I expect uh as I do with like cloud models.
So um like model wise I would it doesn't really matter I guess using cloud code or cursor for the most part. Uh I just started using cursor uh because at the time it it fit my mental model better. Um I think at some point this year I will try cloud code. >> Um >> you can also integrate it in VS Code and stuff like that. >> Uh I think the cursor came out as a leader because they were I think one of the first AI ids.
they also captured most of the market and I think they're still one of the innovators even though recently they were getting some heat for uh they're moving away from this kind of view that you have where you can see the code exposed and so on and they want to kind of hide it behind agents and stuff like that's what I understood I haven't used cursor in a while but I saw some people complaining especially developers that they kind of hide the code a bit they want you just to chat >> and don't look at the code so >> yeah I Yeah, there it's it and it's also it's it's you you also you you mean eventually you you often have to review the code but I mean if you you run the expensive models they will throw the problem for you so >> um eventually just a matter how many tokens you throw at it >> and how the tool set and the hard like the >> what the tools they have available and how like scoped they are >> they do it's um >> I see. Could you explain us the cursor setup you have because there are all these kind of extra MD files we can plug in to make it smarter or better understand certain things. >> Yeah. So the this uh this part here is like the uh directory for the extension and then in the cursor file folder this uh part of the repo is used um for cursor to like review before it starts to plan it. It it reads the it reads the um um what tools they have available, what what rules are could apply to this if there are like explicitly mentioned um what skills do we have and stuff like that.
>> Um the the uh maybe the most like used rule I have when I start a new tool is this one called Revit dev.mdc. This is what I use like all like always if I start a new project like a new script. Um >> Mhm. this um has like all the like some of the lessons I've used uh like learned uh during some of like the code um lessons hardearned lessons that I've had during the years are like explained uh in this rules file. I mean this I have a couple of hundred rows and there are there are more as well.
Um, and for people who are just going to get started into this kind of workflows, where should they focus on creating these kind of rules? Should they just start from scratch? Should they just kind of create it with AI, take existing ones? Yeah, for me I I um I realized like when I started using private and doing like AI workflows to create them that copying between like uh some chat window and into somewhere doesn't really you're not using the agents to their full extent. Uh so I started off really like uh researching uh like best practices um like analyzing tools that like how they usually go go around creating buttons uh how they usually structure the code here.
um your course material was used to begin with to like create help me set up like uh some of the pitfalls that you usually have and like I can't remember how many times I referenced this one uh for for um >> no f strings that's a common one >> this I mean when the models are trained on like the massive Python stuff uh it it can sometimes uh try to do like what people other stuff other Python libraries or software pieces use >> but for pyRevit they I mean you have to scope it down to what pyavvit can handle and use >> so that we running IronPython older versions and most of the python is python free >> yeah so >> so then some of these things have been some of the lessons that I've used uh to to not be like the first error that appears when I click a button is after strings. So, uh this has been used extensively yeah to like scope the um agent better. So then some of this could be like yeah I mean to begin with if you create a button you it I mean it has to follow like pyRevit's way of creating like tabs and panels um >> Mhm. >> and then you go into buttons or if you have stacks um how how it handles stacks like bundles some of that can be explained in these rule sets. So if you just uh have it uh create a new push button, it will read the rules, read some like uh code that you already have and then it will replicate that.
>> So then you won't have to debug if the folder structures are right. Right. >> I see. >> So yeah, this kind of uh also the same kind of setup goes not just for the cursor thing. They they all implemented similar in cloud code.
You also can create skills, add all these extra things. >> Mhm. >> Which are which is quite nice. But I think curs was it cursor who was the first >> maybe >> maybe I don't know I I'm not I I didn't have this in parallel when I worked I completely ran into cursor >> the way they do. Um >> okay.
So these are pretty much just kind of files with the rules on how to behave with IronPython how your code prefers to do and stuff like that. Plus you train it on the learn rate API material. So >> for me what I noticed the most is like when you give a working example it's so much better because now it understand the context especially for example for UI forms if you ask it right away it often fails but when you give like simple example look this works now make that it's now it's just such a difference. Yeah. >> So I think that's what it does.
>> Pretty good. >> This is one another thing that I it it often does like if if if we do >> if you have like in parate if you have >> like tools that you you've um that you have your scripts that you have ref you have reference to some like a common um uh code stack where you reference file from them. in py rev you have to reload >> entirely to to use these like function calls that you use in your scripts. >> Mhm. >> So this is just a reminder that um it remind me about if I add stuff in the library uh it will um I won't have access to it.
So whenever I have li scripts that I reference here it it will notify me to read. >> Mhm. This one, by the way, I think it was updated. That was the case. And I spent >> like two days trying to fix something and I couldn't understand why my code is I haven't noticed it for a long time.
>> Maybe changes in the new. >> Yeah, this this reminder would save me hours. But then I noticed that when I start teaching it in tutorials, I try to prove the point and it actually worked without reloading. And I'm like, >> okay, that didn't go as planned. So I guess there were changes maybe or maybe I don't know but I would still recommend to reload your par extension like it says right there that whenever you make changes in library not a bad practice trust me I >> I I do this like maybe maybe you're right maybe allowed to to to add a new maybe >> I would leave it I'm not sure like maybe it was just for me like some engine setting changed in private or I would take it six version.
>> Um, yeah. So, this is like the you you in in cursor you you have your your normal repo and then you have a folder that where you can reference things from. Well, so if if we need to create a new button, we can like explain it here. >> Uh, and then >> I could reference rules to and or like just instruct it to read the rules before it's uh when it starts to plan. Um what's your opinion between rules and skills?
Because in the end it's also both like MD files with a bunch of kind of uh explanations how to work. >> Yeah, I mean this is the part of for like my my pyavit uh development journey needs to improve a lot. Uh because I mean skills uh if the agent feels that it needs to reload to be able to test it, one skill could be to actually like trigger some MCP run or something to reload that. >> Um so I mean this um for me I know that this part has to improve. I use skills a lot in other repos uh and that works uh really good >> to like skills and stuff.
>> MC this is not MCP tool. This is like rules and skill for the >> AI to do. >> Mhm. >> But I mean one skill could be to to trigger an MCP uh or like this uh >> so it's more like SOPs like this instructions on how to do certain tasks, right? >> Yeah.
And it could be there are a lot of other cursor functionality or agent functionality like as well apart from skills and rules. There's also a concept called hooks like so if >> the moment you let's say you have a kind of have a hook to >> whenever uh you create a file a python file like a push button file you would have um that hook would trigger and then you you could explain what to like check or validate or run or debug when that new file is created. >> Mhm. >> That's also like a more like a event driven uh thing than skills. Skills can be things that you reference as well.
So like use this skill when developing this or >> um I haven't used it a lot in par context but I use it a lot for like web development stuff uh to uh maybe like analyze uh >> uh like maybe if I have a a database running in my local de developer environment I could have a skill to how it should uh like authenticate or test things in that database. Okay, got it. Um and if I reference in the rules that like before um getting back to me it has to check the skills. I mean yeah I mean it will >> uh if you use the better models. >> Mhm.
>> I see. Got it. All right. So the setup makes sense. So what feature will we build now?
Or is there anything else you want to mention before we kind of dive more into the demo from challenge please? Maybe I can we can do a we can do um um Yeah, maybe we'll do I have an idea now. This uh >> Yeah, >> but since you mentioned clashes uh Okay, so we're we're looking for a feature that can um have me select different Revit categories to clash between. Um and then once it can generate the clashes uh it will group them using our current method for uh family elevations but not using elevations using isolated 3D views instead. So we have we would get a grid um like a one to one or like a end to end grid of all the clashes in the model on a sheet.
based on like this uh category clashes. So like the first uh first grid element would be like if I like the walls towards doors category and those who clashes between those on in an isolated view and like the next grid element would be uh doors uh against columns or something. And then uh this would be a sheet with uh end to end uh uh isolated 3D views for these categories. So this is usually how I uh start like just talking out >> the AI and then so now we have like a a small uh part of that. Mhm.
>> Uh and now I can reference I can start by reference rules that we have. Um just to scope it down a bit. I can use like clash detection method like I I have done clash detection beforehand um for our zone detection part. Uh and I can also like drag in part that I like usually I can reference >> folder. >> This is like a tutorial for AI on how actually it works the clash detection in Revit API.
>> Yeah. So this I have like one uh after some hard learnings I uh I ended up creating like a small docs for me to use uh again. >> Uh so this yeah I mean these are examples. Uh so from now I like I can um I know that I mean it can use it can read this it finds examples. So clash detection is for me is already solved uh in this sense but it hasn't already it hasn't uh done the uh like sheets part and creating that part.
>> But we have that in um >> uh in another called family elevations. Now that I look at that, I should turn my newsletters into skills because I often take a subject like that and just send a newsletter on that. I mean I mean yeah so this is how I you usually go about it. um and then uh have it in plan mode just to see and I usually go for like a harder uh like a smarter model to begin with um in planning. Um yeah so yeah we'll jump uh like straight into this uh and we'll I'll try to explain what it does in the beginning.
>> Yeah. So in in um in cursor they u it can create like sub agents. So we have one like major major agents or like the normal agent and they have we have sub agents that like dump like go through the code. Uh so for like the zone uh clashing it's it's uh uh the we're into that sub agent here and this is the prompt that is uh he initiated the sub agent with. So now it it explores the codebase that we have reads a few of the files and then it it lists the files that are available and what they do and yeah summarize them and they have meth methods here that they use.
Um so and I mean the sub agent is just uh it it uh it scans this a sub agent scans um and then reports back to like the main agent. So now we have two sub agents who have like uh scouted the code base for this um and then it starts reading like other code that we have. So I can I can like see the tool calls here >> that agent uh runs. It it thinks it reads it like searches for references that for like functions and stuff. >> Mhm.
>> It uh sees how we it search for like bundles. It it thinks I can read some of the patterns like how it thinks. Um, I can see what it's it's it's reading parts of this code base here for fan motivations. >> Mhm. >> Creating also reference your current tools from the extension.
>> Yeah. >> A lot. >> Yeah. I mean, yes. Yeah.
Yeah, I mean I do have a extension like this, but I mean if you're starting out there are like a lot of pyRevit extensions that you can do >> uh use this kind of workflow to like um reference add that to like a reference uh part of your codebase to have let a research uh patterns that you have selected that you need will want. >> Mhm. Uh so now it it has like a it it says it has a good picture of what I what I need but it needs a further questions before we create a plan. So I I mentioned like pick and categories. Um so then I'll have to options here like how how I want to like uh scope the plan.
>> Um so let's just pick that you select unique. You just select you get a list of selected categories and it will create par. >> So kind of hard code what we do. >> Yeah. But you just you get the user to select what categories to like clash and then uh what's a single grid one per category?
Yeah, let's go by category otherwise it will be obvious. Uh should clash detection include elements from linked uh host model only >> and then it will continue and then this answer is part of the like next phase of the planning and in this phase it also like it can also start to read parts of the codebase as well um or uh yeah for extra clarifications u based on what they've responded here. Um, that's it's it's thinking about like this creating a new clash module in the library here. Creating views and then we'll get to decide where this push button should live. Uh, let's say elements.
Yeah, that's that's Yeah. Or a new panel. Yeah. Yeah. Let's go find this is this gets you into the architectural um software architecture like how do you want to clash how precise do you want it to be?
>> Uh I'm going to go for the first one. >> Yeah. And at any point here I can like if I if I see that it's going in the wrong direction or I have to like this is the right path like uh it's uh trying to do something that I know isn't possible or something that or I know isn't efficient >> uh you could like always uh go into this and just say that it needs to do something else. >> Mhm. Mhm.
>> Um but this is already quite like the feature will be quite big like it will use um some UI features um create an icon or yeah or create a ribbon management and here we see like it's it planning out how it should work. Um like it will open a window and you have to use iter to select something and then you generate like clashes pair them some like filtering and then eventually you create a view uh with a section box and then place them a view in the grid. >> So this is our code that's going to be used. >> Yeah. So this is like just a plan but you can also you can always save the plan.
Let's see. But because in some ways uh this or this is all I do in in some cases because I know I have a feature planned. I just don't have time to write it or complete it. But I can always complete it later. I just save the plan enough in that uh folder or something.
>> Uh >> Mhm. >> So now we have a a plan how it would uh uh discover categories. the code behind the project for the UI part um heat and grid placement we already have we have direct references to that as well uh in the codebase. So the next agent who reads this will yeah can read that code. Um how it creates views >> and at any like at any point I can ask it to review the plan against like Revit API or some web page or the root set add rules again or um >> Mhm.
>> So you mentioned that nowadays you spend more time in cursor than Revit. So pretty much that's what you do, right? You're just chatting and waiting for it's more more questions. You chat back and probably have it in parallel. Yeah.
With other tools as well. >> Another project. Yes. So, and then like I review the plan and sometimes I have uh like multiple like windows and I like try to monitor them as I would have like monitor some AI colleague or or like a colleague coding or >> uh sitting there with a weep you now. >> Yeah.
I mean, so you can I mean, there's something to be said about uh that let's just fire this stuff. Uh and yeah, I mean, now that we I mean, for this demo, it doesn't feel right to choose a a cheaper model. So, yes, just uh let's go with a faster model. >> Uh since this is recording, so why not? Let's >> uh >> by the way, when you use OPOS 4.7, uh how is your target work?
You normally you pay subscription for the cursor. Do you pay for extra API calls? Do you connect cloud subscription? >> Yeah. So in how does it work right now?
>> Yeah. You have a you have a subscription and in that subscript subscription you have a fair amount of like API tokens that you can use. subscription still 20 a month or >> so I'm at the more the uh I'm using the like expensive plan from cursor because I use this a lot and I really enjoy >> uh uh let's see if how this so this is my um I'm not saying that I'm using this the most efficient way but this is my plan uh and in that plan it's included like $400 $100 for like API usage, but this usually ends up being consumed quite early in the month. So I now I have nine months until my plan resets. >> But up until this month, I have we've used some tokens already.
>> Oh, so you also pay on extra. Yes. On top of the plan. >> Yeah. I mean, yes, it does it does uh >> it it can be if you're not careful as I am, >> it can be quite expensive.
But I I'm at a plan that I we I mean we >> for me for us this doesn't uh it's still worth it if it's a good idea. So I mean >> but your company pays for that, right? Yes. It's not coming. >> Yeah.
My pocket. >> Also for them it's less than one employee especially in Sweden. I mean they want me to be efficient and this is what it takes. >> Yeah, >> for me that's this is what it takes. But >> on this note, have you heard about caveman skill for AI?
>> I read it uh like a week ago and I I think that maybe I should try this because this is also like how I write how I write the prompts. I don't write them like super extensively. Yeah. >> So, for people who don't know and watching this and wonder what the hell is caveman, somebody made a skill for AI. Yeah, if you could open it, that would be great.
So, uh pretty much it's going to dump down the answers from not really dumb down. It's going to make sure it doesn't talk what it shouldn't. It's going to cut all the punctuation, all the useless words, all the okay, I'm going to summarize now. It cuts all this fluff away. Just tells that just speak what I need as short as possible.
And some people you can see they're cutting 70% of output tokens. So you can chat more with your AI models getting pretty much the same results. And you can see there like before and after if you're going to scroll through I just scroll down there. How would normally cl talk to you and how it talks in the cave mode. You can see there's like the usual blah blah blah blah blah or it just tells you exactly what happened.
Okay. New object rendered inline object prop. It also shortens everything. So it saves you money by still giving you the information. And >> I mean the Uh this feels uh quite uh good.
So I'll I'll try this after this recording just uh because I do see that it has already pre pre skills for this. >> Yeah. Yeah. Yeah. It has the skills for all the AI to use like it pretty much it's just a set of rules and you can see in rules drop articles like a and the then short synonyms patterns not.
There are also modes on how hard you want to go. It's literally it can even shorten the real words. So it's kind of look like a word but you kind of guess it but there if you scroll through you will see there switch level caveman professional ultra uh on top >> in the middle. >> Oh okay. >> Okay.
So there was somewhere um line 15 >> you can choose between these modes >> and then it's kind of how >> how compressed your messages output should be because it can use like really hardcode mode where >> you will eventually learn how to speak it properly. >> This sounds fun. >> So yeah that's a good tip for anyone who is spending a lot of tokens like Jonathan here. >> Interesting. Yeah, I'll try this out.
This uh it's it's it would probably save us money in the long run. >> Yeah, >> I would also love to hear once you play around with it the quality of outputs because from what I saw, people don't really say that it becomes dumber. It just kind of saves on tokens. But >> yeah, but we can try this. I can try this in a branch, the same fe the same uh feature and then we'll see.
We can explain, we can check later on like the caveman caveman branch versus uh this one. >> Yeah, could be interesting. >> Also, how long does it normally take for you? Because now it's going to because the script we chose is not the simplest one. You gave it a lot of different steps, UI, and so on.
So, I wonder >> it's going to take a few good minutes, right? >> Yeah. So at this point is it it has gone through parts of the task list uh creating the tab creating the basic UI creating uh 800 rows of like the Python scripts. >> Mhm. >> So now it's it's it began like diving into that code and like cleaning up things and stuff.
Um, so I mean usually I mean this could take um I mean now that we're using a more expensive model it it it will think uh more than if I just set this to auto and and or like some of the faster models. >> Mhm. >> But the output is going to be closer to final results though. >> Yeah, it will. So I mean I I don't expect this to work the on first click but um maybe like five prompts in this will this will work uh or if in five like maybe 10 it's it not it's not going to be like three weeks of working to get this working that >> Mhm.
>> Yeah. >> That's how that's confident I feel after working with this after >> also I noticed that you're going to go you go completely yolo. you just give it the full steps everything right away. >> In my work, I usually prefer to start with like MVP. So start small and then slowly introduce feature by feature so I can track the bugs and so on.
Uh have you tried kind of also going step by step yourself or you just always give it the full prompt and let it cook? I >> mean for this example you Yeah, I mean we gave it quite I mean we gave it the more like the harder route uh to do this. This is already a hard task. Um, but I mean if we were to to drill down this into parts, some could be like just creating a push button script that with like no icon, no nothing that just would clash categories like clash doors and walls or something stupid. >> Uh, or like walls and columns.
Uh and then you like iterate on that logging like see that it that that part works and then moving forward. >> That's what I mean. >> Yeah. So that I you you could drill down that task uh uh create like the uh like an MVP but for me I I usually um it's so good at creating boilerplate code for me at least. But it's it's um the I mean this for me this makes more sense in and then will iterate on the code and then eventually it will go to the phase where it clashes and uh creates the views and stuff.
So it um this just means that I get more boiler plate. But I mean this is all uh due to the fact that I I know I have rules that uh work uh I know I >> and examples it. I know I have we have read the plan and we see that it's kind of taking the correct approach like overall overall. Um yeah. So now we're uh we're at the point where this gets interesting.
>> Mhm. >> Uh we'll see we'll see how humbled I get after this. >> So I think it's finishing now. >> Yeah. So it's it's created a few files uh in a new panel for us.
Uh and it it suggest a way to test this. Um this is where my MTP thing gets >> uh be approved later on to also allow it to automatically like read all the test stuff. >> Mhm. Mhm. So now we'll go into like the next part of the uh where we debug the code and see that it worked or not.
>> The most important part. >> So now we see that we we did get the new panel. >> We did get the button. >> It's I mean it does have some some level of review. >> That's solid.
So this is also very similar to what I gave it earlier. So this is what I gave it earlier and let's look at that one. So you see what it already had in its context. >> Uh so it like use this one as a base for your UI. >> Yeah.
And it also it so it has the pattern already for how it should plan this out. >> So now we we do we can select like view scale for maybe this isn't doesn't uh really apply. view scale for a 3D view maybe uh you can select a view template here that's let's set one and then it will prefix the sheet or clash for the view and crop one view per group let's see about that and then we'll try something like uh floors and cols to begin I should have I should have added like coloring color uh the first group like green and next one red or thing. >> And so now it's created the view. So then opening this sheet and we'll see how this turns out.
This will be a lot of 3D use. So okay. So we're it at least it created the views but doesn't uh >> Mhm. >> really pans them out. >> I can find.
So, this created let's see if I go into this and then see what's it does only have columns and floors in this view but it >> and stairs. No, >> and stairs and like it has uh it included legs. So, that was kind of >> Okay, got it. I got it. Yeah, but this is view visibility probably issue.
So just uh so maybe we'll add this into um add this into the next part to always hide uh Revit links, >> but it I mean it it's it's not really far away. It's it's more like >> we get the results. we do get results and we can see where it's uh it's from one shot we get uh views with isolated categories. So it it would be the next part for me would be like uh having this in I mean uh sizing them to the same size maybe the viewports >> and having adding them into a group. Um, and then like maybe coloring these in different colors so the user can like quickly jump into a view and like drag around and say, "Oh, these are clashing." >> Mhm.
And here we got the clashes of floors and columns per level, right? Just to remind the task. >> Mhm. Mhm. >> So each of these views is a separate level where we can find clashes, right?
>> Yeah. Parking. You see clash columns from I mean so I mean you could imagine this still being quite useful for a oneshot prompt for like adding for like diagnosing clashes. >> Yeah, definitely. Again, we can make more views and stuff if we would want to, but >> Mhm.
No, pretty good. >> Uh so okay, so let's see if if uh no nothing seems broken. So that's kind of weird. What do we debug? But we can like add the next part could be like adding colors to elements or like group having having a better grid or >> so you can see what it takes us and also check how many tokens it used just for this run.
>> Should be somewhere usually. So 172,000 of tokens. >> Yeah, that's in the context window. So >> I also like stuff. >> Yeah.
Yeah. I I I don't actually know how see how we could see. We could see we could see the token usage. Uh we were at 2625. >> Mhm.
>> $3 up. >> Okay. Yeah. >> I mean, >> not bad. >> I would consider this uh this is still like a marginal success.
Uh but uh this is all due to uh if we get to the beginning if we would have started with like only this part it would still it would have to be figure out the clash detection and figure out the UI and figure out a lot of things. >> Yeah. Yeah. You gave it a lot of supplementary information which made it also more efficient which is I think should be the end goalie. >> Mhm.
because uh what I like to see is that you use a lot of rules and skills and stuff like that. And well, I'm I kind of resisted this AI change for a long time. Now I'm embracing it more. So I think I just need to follow what you showed like I like that you showed the file of clash detections that you take individual topics and make like this manuals probably still with AI but still it's very useful when you kind of give what you understand ask it to complete it and then you have like this working file it can reference. I think this is a big killer feature.
>> Mhm. This is what made or break it for for me like like cop because you you need to it needs to have some some uh examples to follow. Um and for me it it's uh I mean we started out creating >> uh some some smaller features and then one the more the the codebase grows the more patterns emerge that it can it can reuse. Mhm. Yeah.
You can also ask it like look at my extension make me like a skill for creating this kind of tools. Right. It will understand your patterns, your structures. Uh what do we use? Uh can you read what you're doing?
>> Yeah. Yeah. So then uh now that we know that the functional it works, we can start improving on it. So like in classic classic clash detections um part we color them differently. Um uh I could have referenced my colorizer as well and this but um uh and also make the views in the sheet the same size.
Uh now they're stacked. But then we'll it's we see that it's trying to >> fix some view size and if it doesn't have a like a uh it doesn't know how to like read views port sizes or set them or yeah it will probably look at some form like like searching Revit. I see it when it has no context. It I see it uh like searching Revit API forms a lot. >> Um does the dirty job too.
Yeah, we have we have add we haven't added a research step here as well but but one uh uh one pattern that I also all sometimes use is I plan like multiple steps like I from the first plan we we created I I uh we could have uh uh asked another model to review the plan or like uh thrown another model to Google searches and review the planet again. Uh >> Mhm. Mhm. >> This is all like locally reviewed uh that I've researched, but uh you could always like have it go into GitHub and search for other patterns as well. Uh and also do you often hit the limit with a context because normally AI have a context what it's aware all the information it kind of feeds itself.
when it hits the limit, uh, usually it kind of stops working or kind of breaks halfway through. At least that's was my experience. >> Uh, how do you deal with that? And do you often hit it? I know there's also one 1 million token model of OPOS.
I don't know if it's available in the cursor. >> Yeah, you can do there's a max setting here where we it gives more context, >> but do you often hit the ceiling? Does it break your workflow? >> Yeah, I mean, we're hitting the ceiling at the moment. So yeah, usually you hit you hit them you hit this >> u uh it usually starts with uh when I do if I know that this is a like a soup a very large task I would go u in max if I have uh now that I have the caveman I won't maybe I won't reach it but that's at um when I I usually have one like large context agent um and then uh for this colorizing part we I we wouldn't have needed to use to have this feature in this agent.
We could have start another one like this and then reference that old that chat cuz the chat itself isn't the entire context most of the time. >> So it's like compressed version of it. It just picks and chooses what it needs and then continues. And I could like pick a smaller model that if I have a small task uh let's say if I want to rename the views a bit differently or I don't want the views to clash or yeah something like that I could use this a smaller a restart an agent with some context of what it's working on >> and then fixing it uh separately or parallel >> but we reached the max token at uh already so it's at some point here it it summarized the chat context and this can be quite dangerous >> because >> because it loses information, right? >> Yeah, it will lose stuff.
Uh but uh yeah, we're we're we're doing it live, so we're already in the dangerous zone. >> So why not? >> Now, it's good to see that it didn't fail because sometimes just refuses to continue. It just stops midway, which I hate the most because the moment you restart, it decides, oh, probably since I didn't finish, I'm going to delete this hours of research. I'm like, "God damn it." >> Okay, so now we have a new version.
>> Yeah. >> Uh we can I mean we had uh we can just uh either now we have re I forgot to re remove the hide the links but yeah. >> Oh that's okay. We can limit features as well. >> Uh so now let's go for another uh let's say case work and let's see if the search work.
see that there are more selected there and where we can add say something more here. So now we have we add a bit more we group we skip group by level and let's see where it takes us. Let's skip a view template and see where that goes. Mhm. So now there's few fewer views but it should still group them differently.
>> Okay. So now we have we have them more apart from the last one. >> Mhm. >> But we still see >> so that one case work versus walls. >> Yeah.
I mean this could I mean you I would still use this if I worked in Revit. I mean >> no that's useful. >> This is still useful if you can see see it like this. I mean you you're only seeing Revit like I mean categories as a category but this is still useful like if you're working in Revit and you need to check some things now we see >> colors they just represent different categories >> just we could have we could have maybe we could have add an edit for others or something >> because at first I thought that red one is bad green one is good then I'm like no it's just categories it's just the red and green like thing when you see it like this >> you immediately assume one is wrong. >> Something versus walls.
Okay, we have only one. >> Uhhuh. >> And then >> wait, this is a link model. No, can you select it? >> Uh, no.
This was a group uh group. >> Oh, yeah. Yeah. Yeah. I read it wrong.
There was like something on Live work or I thought it's link. No, no, that's a solid tool for sure. So nowadays you pretty much sit there with cursor and just like with a whip tell it what to do have multiple of them like sub agents command the whole thing. >> Do you still code or do you write both? I mean what do you I I wouldn't I wouldn't consider this uh that I have coded anything but I I mean we still provided some value right so >> I sure once you understand code you can navigate this but I mean like actually opening like and typing yourself like step one why from from just some some parts that I really really care about that that has to be like secure I mean let's say if if it has to do with like user data something like that then I really need to see the code uh >> Mhm.
uh to see that we're not doing something really stupid. But Revit is already kind of contained. Uh I mean security means that it won't break your model. That's the what's what can break. But you can already restore and like just fix the code.
So uh >> I see we should have added like a better transaction register or something. But I mean it's uh that's I don't see myself uh coding a lot in the future because um this uh the mod the uh the current state of the models is uh the probably the the worst state they're at. So they will only improve. Uh >> but maybe in the future we will do uh we could use the the machine ourselves instead of paying >> $10,000 to to uh some old provider. Uh there are some crazy Apple machines coming out because they have this architecture where RAM and VRAMm they all fused into one and for 10K you can get 120 or 250 GB of VRAM.
You can run crazy models on that >> but it's not going to be probably Oppus level but I think it's going to be solid ones as well. Uh I have a question. Mhm. >> So for people who let's say people watching us they maybe know a little bit of coding or don't know coding at all and they now think that okay I want to get in pirate game and start creating my own tools. Do they still need to understand basics of Python and Revit API or like just start chatting with kind of blindly like for you you you still need uh like an idea to execute on and >> uh but I mean I wouldn't you what I think you need is like some basic fundamentals for programming but uh I mean you the basics are still useful like u u have having your way along that you know where the Revit API is located or having other basic like basic programming rules still apply for this workflow.
Yeah, like how to work with parameters, what is transaction, what is FilteredElementCollector, how to >> Yeah. So like uh just this morning I ended up ended up in learning like the persistent engine thing in the pyRevit. I haven't used that a lot. I mean >> u the fundamentals or underlying uh codes or like programming is still very very useful to know. Um, >> but do you need it to uh do you need it?
I don't think you need it, but it's still very useful once you get into the deeps uh of like debugging things. Um. >> Mhm. Mhm. >> I mean the the because the models will improve faster uh than my learning like my uh my if I look at if I only go to myself like I I can't learn in the speed that the models improve.
there's no way I can learn in that pace but I can still like practice good programming fundamentals. Uh >> so like uh but like knowing how you should create how you need to create a class in Python maybe do you don't need to learn that but you maybe you want you need like in private context maybe you need to know like how it's how a script uh actually appears in the toolbar but like uh the ar the like software architecture part is still very useful to know. So you'd say that people who want to get started with all this agenting and stuff they still it's best to understand basics of Python or computational logic all this >> and also the Ravit API what actually kind of powers all the Ravit software behind >> so you can speak better or >> I would still say so but I mean I yeah I would still say so yes you you it's still useful I mean it's still useful to know all of these things uh but uh just look at what we did today. Uh >> and we didn't touch any code. >> Maybe this is super inefficient and wrong.
Maybe it is. >> Can you Can you show the code by the way? Just scroll through. >> Yeah, I mean I'll share it on I'll just add an icon and you can see it in added the toolbar and >> Mhm. No, I mean like so it's during the podcast I can quickly show what's going on.
>> Would be helpful. >> I just wonder like the style of coding it used. So then we'll go into the re review mode when you see this is all the code that it added this phase. Um and in my previous runs this morning. So this clash view here this is the this green part.
This is what been added. So it already has some pattern to follow here and some imports and uh how it handles navigating to libraries and stuff. >> Then we get into we >> filter categories and then having defining functions to use to reuse. Yeah. Some kind of yeah code group functions.
Yeah. I mean you could >> okay we don't have to we don't have to explain everything can I just scroll through I just want to see the structure so pretty much made a lot of different functions that reference each other and then in the end we have these 10 lines it's pretty much tell us give us results and then like all the functions they start calling each other and this is all the patterns that we have in our codebase but >> yeah this is the example view. >> Can you preview ZAML in cursor? >> No. Uh but I mean I can just iterate so fast.
>> That would be great. I mean if you could >> for people who don't know XAML is like HTML but for this kind of UI forms like Windows native >> very similar syntax but yeah I hate that there is not a good uh viewers like Visual Studio is pretty much the only one all the other ones they have some issues. Uh what do you think about MCPS for Revit? You know there's like this new AI assistant that fails badly. There's also ability to create our own MCP servers.
So idea is that in the end we can just prompt with Ravit without tools. I'm very pessimistic about that. But what do you think? >> For me like MCPS are useful between services uh that are like not colloccated. That's my take on.
>> You mean like sharing the data between like different services or >> and this could be like like between desktop app as well that where they are kind of closed in the environments. So like it may kind of make sense for to have it at MCP inside Revit. Uh uh but I really I um but it's it's not quite like really token efficient and it um I for me when I develop at least I want a a freer environment than MCP >> uh provides because MCP is is also kind of >> yeah you have to create like what explicit tools that it needs to create that that it can use but uh I like to free dangerously. So for me I I would personally more in like Joyce a closer uh like API like a a closer thing than MCPS provides today um >> Mhm. to like really connect to the models uh for me as developer to be able to do things like uh >> within the models.
But for I mean for uh what I've seen the Autodesk Assistant does and like and what I saw in the preview of it, it didn't um it it meet my expectations when I tried it in the preview uh in the tech preview. Um yeah, back in what version it was in the preview. But um uh the uh like the Nanite Pro and others I've seen uh there's I have a project colleague who uses struck IQ or something they have a chat as well and that seems to works a lot better than the auto life assistant. So for me, I would personally more like see Autodesk providing like the MCP interface, not the chat assistant because I think the the industry will take care of the chat part, the deployment of that and like they should focus on the close I think the close uh integration. >> If they just give us the bridge, we can add the tools much simpler.
When I look at MCPS, I'm very torn because many people start a thing and it's like it's the magic button like we just write finish the project and it does the thing. I think it's good for tasks where like analytics like exploring like this kind of not changing the model but looking at the model and giving feedback because if you give enough tools to look at it maybe color it or something like this that could be really good but for like geometry and modeling it's so tricky to give it to users. I saw a really good example. It just shows you how prompting can go bad and it was a very simple example. Imagine like we have like a bunch of different doors and there is numbering and you just write something you know what uh renumber doors for 1 5 to 1.15 and logically you would think we need to remember all the doors right one after another but the looked at it and like oh I found the door which has already number one.1 so I'm going to change just this door to 1.15 so technically the prompt is correct it took the door 1.1 1 change it to 115 but logically everybody would assume that all doors have to be renamed in this kind of pattern.
>> So this is also the issue like you can give even the best MCP tools but I think the prompting also stays this kind of human uh what is it um human error can still stay there but now it's in prompting which can be tricky. I mean for me for me like the current um state of the autodesk assistant it feels like the earlier chat uh that uh agents did. it doesn't feel like very agentic in a way that it really thinks about what it's supposed to do and like but maybe that's maybe there's something I don't understand that makes it that they have to do it this way but u u >> I still I I for I mean geometry is tricky like that's also the hard part like when you're doing dynamo scripts as well uh like geometry is quick is um is hard to like really understand like if you Let's say if we had a MCP for fixing these clashes that we have we just created or like discovered having that it it takes quite a bit of coordination to um to fix these things smart because they all there's always so many rules that apply in a project that a a simple textbased chat prompt can't really fix. you it needs like visual >> context and it it's geometry is hard so and the data part is easier but it's also easy to like mess up >> of course >> but I mean these are things are hard but I think autoes can focus on like the API and like the close-knit part of the API to allow like things like to >> things to like rules and skills things that that kind of supplementary parts of their ecosystem to to evolve uh around and then third party actors can create these ID parts for >> Revit. Mhm.
>> So like firms can uh create their own rules and apply those in their firm. I think that makes a lot more sense than having a generalized autodesk assistant like this. No, I think that's a good input. It's like with API, they gave us API, we started making plugins and Revit wouldn't be where it is without all the third party plugins. I think same with AI, you have a very good point that instead of trying to make us perfect AI, which we will hate no matter what they do because we cannot control it, right?
And it's autodisk and >> everybody works differently, you can take the same project and 10 different offices going to build it in 10 different ways. There's no way it's going to be even close in how we kind of work. Well, it could be, but usually it's not. >> So, like it's a better suggestion would be like instead of approving or add an AI assistant, create like a maybe a keynoting system or share parameter system where you can embed data into the file, the project file with rules and skills and how we how we handle stuff, how we call, how we numbers, cluts, etc. >> to be added into the Revit family like Revit project.
So when a new agent starts whatever they start from they have something to like add into the context that for me that makes more sense for us to develop them. >> Yeah more like infrastructure so we can build on top >> that's because yeah these rules and skills it makes such a difference to AIS because once you give it like examples how to do not to do all these still takes a lot of work to make it properly and good but once you have it it's a day and night difference. All right, I think we're coming to an end. Usually I ask all my guests what uh um how they would recommend beginners to begin with programming, but he but out of this conversation it sounds like they shouldn't. >> Well, they should and they should take your course because I this that's where I started like my real development journey using AI.
I take I took your course and I went through it all and it's it's gives you a I'm I'm I'm giving you a shameless plug here but it's actually really good course. >> Thank you. I appreciate it. >> So yeah I would for new pyate developers that need that want to go this route like uh your course here gave me a really head start. >> Oh thank you.
Can you share like before and after like taking the course what's what was the noticeable difference? Yeah, I mean just just the like code examples to see like okay this is how I could you use this. This is how I can select elements. This is how we can filter elements create or like >> the uh like oh how do you say like approaches to architecture like code behind or oh this model view let's call it model view view model >> oh MVDM >> yeah like Yeah. Yeah.
These patterns are very useful to to know because you will eventually run run into these. >> Mhm. >> Uh if you're doing like the harder. >> Yeah. Uh if you would like to share any socials where people can find you, what what they can ask you and stuff.
Be my guest like give you links where they find you on LinkedIn and so on. >> Yeah. Yeah. Uh I'll I'll send you it to it, Erik. >> This was fun, Erik.
I'll I'll share the code. So it's if anyone wants to continue it. Yeah, sure. Be my guest. >> Yeah, just send me the message.
I'm going to drop whatever you want in description. The more you give like the more you put there. That's perfect. Okay. Uh thank you everybody for watching.
Appreciate it. It was very interesting topic. Very not controvers controvers controversial but something that definitely on minds of many of us. This AI thing is yeah, we definitely keep thinking about this. It's something on my mind all the time because I keep thinking like should I teach it, should I not?
And yeah, it seems like we're going more in AI. So, I think we should stop resisting it as much at least like I did and embrace it more. And yeah, Jonathan showed it really well what you can do. It's already like performing really well and you can probably get some ideas how you can use it in your work. Now, for the next podcast of Py, just let me know in the comments which guests I should invite.
And as usually, happy coding. Goodbye everybody.
### Real-World pyRevit Hooks + PowerBI with David Vadkerti | pyRevit podcast #6
https://learnrevitapi.com/podcast/py-pod-06-david-vadkerti/
David Vadkerti, architect, civil engineer and BIM manager, on real-world pyRevit hooks and connecting Revit data to Power BI. pyRevit Podcast #6.
## Transcript
All right everybody, welcome to podcast number six. Py ravit podcast is back live and today I have a very exciting guest. His name is David Vadkerti. I hope I pronounce it right and he's definitely an expert with parit and he has quite some cool things to share with you today. So aoy David, how are you doing today?
>> Um I'm doing great. >> I saw that you have a master's in both architecture and civil engineering at least according to LinkedIn. uh it's like a single single uh master's degree which is like some somewhere in the middle. So something like that. I don't have two degrees.
>> Okay. Cuz that was my question. I thought like usually people choose between architecture and engineering but you have like completely combined >> like the first first maybe like four years uh were actually uh about the civil engineering and then the second uh like last two years was more architecture and I was actually uh working also as an architect and as a civil engineer or project engineer let's say >> that's a pretty good experience because you kind of cover both sides. Well, I think it's kind of advantage for later as a beam manager if you had also the cost design stage covered and also the construction dogs and everything in between. Yeah.
>> And uh while you were studying, did you use Ravbit right away or did you discover it later? How what what what was your introduction to Ravbit? say >> like I came across rabbit uh uh like two years before uh ending the university and it was like very very new then because it was like I don't know maybe I can uh show because I have something here on my screen which actually was me sure >> okay so so this this is this is my journey basically so here is architecture desktop somewhere like uh here I like bought my new computer And like in like 2006 the rabbit was not very well known at least not in Slovakia. Uh so I started uh here and maybe I ended my uh university like in summer 2007. So it was it was something like this.
>> It's so nice to see this map like of your journey. Usually I ask questions to get to all of that but it's nice to see. So you started in with Revit in before 2007 and I already see Dynamo pop up around 2012. >> But basically this is like the introduction of Py and Dynamo and I started here. So I ignored it for like multiple years because I like >> Oh it when they came out, right?
>> Yeah, the first release. I I mean I meant the first release. Yeah, because I I think uh somewhere here I'm not sure the API for the Revit was actually released as well. Uh and I remember when this was like introduced uh it I really uh like struggled to get what is it for because it has it had like the 3D environment and I was not getting that this is for programming. So I was totally ignoring it for I don't know 4 years or something.
So, and also I remember for example uh uh coming uh across a pirate like very soon after its uh first release uh because I was looking for some addin uh to like improve something and I find it but uh that blog uh which actually was uh writing about it uh was talking about it that the first or the best advantage of this tool is that you can write your uh scripts on your own and at the I I was like totally I had totally different mindset that writing my tools on my own when uh when we are paying so much for ev software like okay but as as you can see in one year uh like I was like creating tiny scripts so it significantly shifted >> wow you heard about pirate nearly on the first release I heard it like so many years later but I also started later it's >> a very strange coincidence but I understood that maybe like in in the all uh all of my schoolmates actually used uh Articad or AutoCAD and not the Revit like we were like three there were like three of us uh who were using actually Revit and there were like 40 of us in ended the year. So >> So when you started with Ravit obviously you started like many of us with regular Ravit stuff templates and stuff but did you know programming somewhere or did you learn it later on after you discovered Dynamo in Py Ravit? So what was your kind of programming background? >> Oh, I had basically known which like like uh like there there is some uh some background but like very very very brief. I I was uh aware of HTML and I was like u trying to do something because at this uh time like 2000s you needed to know at least something to post because like uh HTML 2.0 wasn't a thing.
uh and I tinkered with like media wiki because I was like u uh Wikipedia contributors. So this markup languages um was u known concept for me but uh I started with the visual basic but at that time I had no internet so uh I just uh learned uh from a book uh which was actually like borrowed from a library but I don't know whether I was so stupid at the time or the book was old or I don't know or I had a different version of visual basic but after maybe third or fourth uh page uh I was not able to follow the book so I returned it to the library and that was my programming. So it was somewhere in crash course you know >> and uh then I uh came across because uh I started with uh graphics and tinkering with graphics like Photoshop, illustrator and later in design and I came across micromedia flesh and this was uh it was actually the technology where you can like draw something and program it like Peter and uh this was like my first uh programming geek or what it All right. And where does this programming journey kind of joins Ravit? When you started with Dynamo, did you know any Python or C# already or you just started with the ro?
>> No, no, just just this just just the basics of some terminal in Linux and X is actually the programming language in flash. But uh it was like uh I had no like um no clue about the data types. It was very like a visual because like in flash it was like more as a dynamo but not uh like uh with the wires but you draw something and then u wrote a code just for that element and then created some other so I had no no uh no prior experience. >> Okay. So you like most people start with Dynamo got comfortable with kind of automating Ravit and uh how far did you push Dynamo at the time?
who I don't know but uh during this like first uh two years uh I started definitely my first script was like the renumbering the parking places because at that time we were working on a project uh which uh had like 1,200 or something like that parking places. So I was not going to do it by hand. I was uh actually uh uh looking for some addin and I u came across a video where somebody shows this on the screen. But it was something like this uh renumbering and changing parameters was the first thing during this uh >> first first two years maybe. And then like the texture of programming was uh I think also the usual pattern which you can observe uh in in in others uh that I just see that some other packages in Dynamo uses uses the use the uh Python scripts and I was not aware what they were like doing.
So I was starting to or I I I started to to learn Python then. >> I see. And how was it for you to learn Python? Was it like straightforward, easy or did you struggle? Uh it was it was very strange because I uh didn't get uh the thing that you need to like uh not just uh learn the syntax but also something else because at first the the first video which I actually used was uh not for the beginners but for the beginners in Python which uh or who had actually some experience uh with programming because it was like 40-minute video which shows basically everything in Python like the data types but very very very very uh like fast pace >> uh because I like this but uh and I I I I still like that but it uh doesn't explain anything about it okay this is uh how you create integer this is how you create list this is dictionary pieces but not this is dictionary and this is advantage you can use it like this no no uh no such thing so uh I really didn't understand that but then I installed uh an application for my smartphone uh to use to to learn Python and this was a game changer because it was like normal structured tutorial and uh I was able to be learning uh on the bus on the train during boring uh meetings I work and so on.
So, >> so you learned Python from phone. >> Yeah, like partially from YouTube videos and partially from from phone. >> Yeah. Yeah, of course. >> But but it's like the sounds like the lingo for Python.
>> Yeah. Yeah. There was there were actually no videos. I think it was more textual and then there were like uh exercises and also uh some challenges that you can like challenge uh some complete stranger and to compare uh with the stranger and to gain some kind of game and some kind of tutorial but mostly that show I think >> sounds cool because I know comparison is like game changer at least it was for me I use something like by cheek where it's kind of gified. There's like ah there's little game you have to help solve something and and you do pretty much you solve problems with Python, right?
Like list manipulations this and that. And what I like the most is that once you're done, you can see all the other solutions. And there you can see other beginners struggle do weird thing with Python. Then you can see professionals doing it always in one line which is unreadable, impossible to digest. And then in the middle there were also very good explanations and very simple one.
And sometimes you see your 50 lines of code could be simple like five lines easy. >> And I I was like, "Oh, that's how you do it." Not like you take each item from the list manually depending like lots of if statements. It it was a mess sometimes. >> Uh it's called Peko >> I think it's one of the websites. There are like many similar ones and u I think now there are similar platforms out there.
Somehow they became worse over the years. the beginning it was way better integrated. Now they made it worse. I I checked it like last year. I don't know why >> but I know that comparing code to others this was amazing because you see yours versus others same problem same task and you're like ah >> all right so that's how you learned Python and what was the issue that led you to Pyravit why did you decide to go from Dynamo to pra like everybody maybe struggles with Dynamo a little bit uh when you try to deploy it in the team uh like back then I had like no experience uh how to deploy it uh how to like install packages on some like natural location and uh set everything up.
So it always like worked on my machine and u almost never worked in somebody's else's and I need to like tinker with that. So but uh now I uh I'm I'm like much better in this. I can like deploy al also the dynamo but still the pirate is much better. So like like the dynamo is maybe better that in that sense that you can like see the stuff >> but uh in every 3D stuff and stuff it's amazing >> or or maybe for beginners because you don't need to know anything about like Revit API just find a no. So >> but uh >> I noticed there are like two camps.
There are people who prefer Dynamo as the first one and there are people who like Python or even C from the beginning. It's something about probably how we think and when we find when it's aligned then it like just clicks instantly. But I but I know many people prefer Dynamo to begin with. But now I think Paravit and C have an edge because of the AI. AI is really good with the really good with the code not so good with the dynam at least for now like I don't think it's going to change anytime soon actually tried that approach that just u ask AI to uh write Python code for a single Python note in Dynamo and it works but you can you don't know what is actually doing so the issue with with the Python text programming if you don't know anything you you cannot check it.
>> Yeah. Yeah. That's the danger. I mean it gives you it gets you dangerous really fast in a good sense and maybe sometimes bad but mostly in a good sense right you get some results. >> Yes.
Yes. >> When you need to tweak it that's where issues come in. But even there like sometimes you can like kind of interrogate AI long enough until it makes something right. >> Yeah. Of course.
I think like maybe you don't need to like uh know each uh thing uh which is in the code which has been like provided by AI but you need to like uh evaluate the results or the state of the beam model before running the script and after like creating some schedule or something like this >> and and comparing it. But most people don't do this. So what this is why this is dangerous. So if if if they do at least this it would be okay. >> Yeah.
Yeah. That's what's the this whole hype about Revy 2027 is there's this AI assistant and it's not a very good one. I don't know what even LLM model it's run on but definitely not OPOS. I had little tests but I saw what others did and so far well underwhelming to say the least. I'm going to share my opinion later in another video.
But yeah, I agree that you need a basic understanding of what's going on because with AI sometimes you make a pro. I saw a really good example actually with this new AI assistant. Somebody said, can you remember I think doors for let's say doors. Can you remember doors from 103.1 to 103.5? And instead of renumbering like multiple doors, you just found one door with 103.1 and renamed that one to 103.5.
Technically exactly what you wrote in the prompt, but everybody assumes different kind of outcome. And this is the issue with AI. Once your prompt is kind of can have two directions, you don't know which one AI will take. I think that's the >> sometimes sometimes my experience is that the AI is sometimes lazy. uh like I asked for example I was tinkering with or trying the MCP uh uh extension for pirate uh using clo and uh sometimes it uh like it did everything right but uh I always uh had some kind of schedule of that element uh at that elements which I was trying to like solve or correct or edit uh next to my like load window and I can see that for example this reaming that uh the AI reumbered but just a few of the elements for example half of them or two/3 of them and I need I needed actually to like ask the AI that okay but you are missing these other elements can you like revisit the >> Mhm.
You have to >> Somebody wrote, "AI works better when you threaten it." >> Okay. >> So, you have to be like, "Come on, work. Keep doing this. >> I'm going to turn you off." >> Yeah. Yeah.
I remember there was this big change that you describing because before AI was doing whatever you ask, but it was consuming so much token and power and so on and some people like ask something and they don't even check out. They just close and forget. So they all of them started making these changes where it became lazy as you say because it tries to kind of cut corners or make you do something sometimes instead of doing it it explains oh you can do it yourself David don't worry click there choose the number and I'm like what are you here for like just do something um I think we're going to get back to AI in a moment um after kind of parit so for now I'm also interested like how was your journey transitioning from Dynama to actually parit because That's quite a big difference because you lose this 3D preview also now you go to uh full Python with Revit API. So can just describe this change for you. So >> I I didn't have the struggle with this 3D because like uh many times I just prototype something in Dynamo.
So I results and then I re rewrote it in uh uh pirate but uh as you see like there was maybe like two years gap and uh and also uh there was a gap uh when I was because I started uh with Python in maybe uh 2017 and uh I was able to create some scripts uh some applications also. and everything without Revit. But uh I I really struggled to know how to connect the Revit with Python. I was not aware how actually Revit API works, how it is connected. This was it.
It took me a year to get it this and uh if it wasn't like Essan's uh YouTube channel because he started uh his new playlist or what it was about Revit API. Uh maybe it would have taken even longer. So >> and this was very beneficial and this was uh also a game changer for me because after this I like watch every single video and after this I was able to get that what it actually is because all of these like uh I was opening for example some Dynamo or some pirate script and there was some Autodesk blah blah blah dot or DB something and what's this how actually Python knows about Autodesk I I I struggled to get this. So >> yeah, I think most of us were in the same boat >> like Dynamo and Python is one thing, but once you start to understand Ravbit API, it's like you described like what the hell is this autodb where it comes from then you found documentation. It's another at first overwhelming like sea of information.
>> I was not aware of the Revit API website or SDK. So I was totally stupid at that time. So I was just okay where it is. I had quite similar approach. I just was looking for little pieces of code here and there.
>> Yeah. >> And I knew that if I want to remember how to work with parameters, I have to find this Autodesk University talk somewhere there. >> I think it was Danny Bentley or something something like this. The name he mentioned it there. If I wanted to work with FilteredElementCollector, there was another person with another presentation somewhere.
Then Ashan tutorials somewhere also. >> In the beginning, I remember it was a mess. Every time I would just find this then eventually I would write it down. Okay, parameters you do something like this. I didn't understand much how it works.
I just kind of knew that if I like a dynamo, right? You know, you take bunch of blocks and join it. I was doing the same but with the code like okay, if I put that one, that one, and that one, something like this happens. And >> I think for example, I don't know, I'm not a very good programmer. Uh, and I think I still do the same thing that I just like assemble some Lego pieces and afterwards it resembles kind of castle.
So, it's something like that. So that's a good analogy but that's in a nutshell that's what Dynamo is. Every single block is just a piece of code. I'm just want to explain for the audience that many of them use Dynamo. They don't think much about code but in reality like there's a code behind every single piece of note.
when you switch to Pyrait, the biggest difference is that now you don't have this kind of spaghetti monster as we call them, but you now have like a text editor, but you can also make the same like like you make functions and they can act like your nodes. So for beginners, I know that this analogy helps a little that nodes become functions and they join it. But now is the format different. >> Yeah. So sometimes there is just the one like a single or or two lines in the node and sometimes it's very very like complex.
But for example, one distinction uh in Python can be much simpler sometimes than Dynamo because if you are trying to do some uh loops in Dynamo uh maybe it could be like uh made out of I don't know 20 nodes but it's maybe five uh lines of code in Python or pirate. So >> yeah, sometimes even it can be compressed with list comprehension to one line. Exactly. >> But yeah, loops is also a big thing why people switch to Python instead of this nodes cuz nodes you cannot really create true loops especially easy ones. You have to make all these kind of as you say lots of nodes together.
>> I tend to I tend to create a Python now then just to create a shortcut and then continue. Yeah, >> I think that's how it starts. Start with Dynamo then you realize certain things better in Python then more and more you get comfortable and then eventually like do I really need these nodes? >> All right so parit is not so bad and was there any kind of specific tools that you could not well not could not but were not good enough in Dynamo but parit made a lot more sense in the beginning when you were switching. I think the interface is the best thing that you have like icons uh with uh some uh like manuals and uh text around it because like when I started with Dynamo uh Dynino player wasn't a thing.
So >> Mhm. Even when it was a thing I don't know this Dynamo player I was not a big fan of it ever because when I explained it to others they also they kind of get it but they're like it's a little bit weird. >> I liked it. is significantly better than just the dynamo for for a person who >> doesn't know anything about it. But uh like a icon uh which is actually uh always at your toolbar uh in Revit is significantly better because it's you just need to click on that.
Yes. >> You need to choose uh clicking dynino player uh and finding some uh uh script which you actually don't know how it is called and uh just clicking the button clicking the button is better. So >> yeah definitely yeah I think that also it's so simple to do many people don't realize it but parate is just a folder structure and it just works. This was biggest um kind of how to say it epiphany kind of for me when I like first heard of pirate I was like it got to be hard there's no way like it's easy then I start going looking into that I'm like oh you just make a fault the structure and now you get I'm like what no way then the more I start looking at it the more I got like sucked into this par world >> the system is so uh so like simple that like anybody can do that yeah >> just just copy some codes or uh or even like families or any any content and you can create like uh extensions uh just by copying from others. So >> yeah, that's what many do because it's also open source.
So you can access all the code and for people watching this in Pyavit and all extensions based on Pyravit, you can hold alt click on any button and you're going to find the Python file. You still better understand what's going on inside before you copy. But still it's a like so good to see working button and ability to see code behind it which you can learn from steal redo update make better like this is what I think that why paravit is such a good kind of tool because you keep working on existing work instead of starting always from like scratch looking for example it's always sometimes hard in internet but here you can see the buttons you can get them. I mean this was really kind of a big shift for me why I went to parit that openness and uh that it is actually open source is a huge thing. Yeah.
>> Mhm. Yeah. I think otherwise I don't think it would survive as good. >> We can actually uh like learn uh from each other. >> Yeah.
So so much better than like struggling guessing h what is that what is this called? All right. And uh so you started with parit I assume like you started making tools for the office sharing them and what is the origin story of your custom tools cuz your main power extension called custom tools right yeah >> at least that's what I >> uh it's not a very straightforward name like original or something but yeah I'm so boring >> straight to the point if you if you type a custom tools to Google uh anything else like uh you will find anything else you need to like uh write my name already. >> Yeah, if you put David Pavid custom tools, you'll find the right one also. Is it still on Bitbucket?
>> It's still on Bitbucket and and I think the first result is GitHub. I don't know, maybe GitHub is like largest tool. >> I remember uh one of my colleagues introduced me to your extension and I remembered it more than anything else because it was on Bitbucket. I was just thinking all the time who uses bin bucket like was it for like >> but yeah I saw your code it's quite impressive what you do you have lots of configs lots of hooks a lot of like logging and checking here and there you were miles ahead of me when I found you and I was like ah I should learn more from this but I also had some for me I don't know why I don't recommend to anyone I had some ego that I had to figure out myself not copy from others maybe because I make tutorials I didn't want to look like I steal code and then teach not stealing the GP license so you can do anything every day. >> Yeah.
Yeah, I know there. I don't know. It's a weird That's why I say I don't recommend to anyone. For example, EF tools, everybody just steal everything. Learn, do whatever you want.
I'm fine with that. >> But yeah, for some reason it stopped me to explore more. I didn't want to like look somebody else like copy tools or something. Even though that's the right approach to probably start making your tools. Probably it's YouTube and tutorials, you know.
I don't want to look like fraud just stealing code or something. But yeah, it cost me definitely a lot of time and learning. I learned the hard way. That's why I don't recommend it in the first place. >> But yeah, uh can you maybe share a little bit about the custom tools?
We can just go to the main topic because you wanted to share a lot about hooks, logging, and other like tools you have there. So maybe we just jump into that. >> Okay. >> Hey everybody, just a quick note. >> Uh this podcast doesn't have any sponsors.
Well, except for myself, I guess. So therefore, if you are somebody who is interested in pirate rate and you would like to either start using pyate or maybe you want to get better at it, you can get more trainings and additional resources at learn rateapi.com. You'll find my challenges there, my fast track and I have a few things in mind that I'm going to share in the future. So check it out. It might get really useful.
Now let's get back to the port with David. >> So we can see the custom tools wiki. >> Yeah. Yeah. Uh actually the the custom tools uh I I started custom tools uh just after I uh watched the Exon's video about the Revit API uh because I struggled uh to create uh a certain uh dynamo script for creating uh start work openings in the uh uh in the concrete for pipes and ducts.
Uh actually I I did that but in Dynamo uh sometimes it worked and sometime sometimes it doesn't or or or it didn't and I struggled to understand why. So I recreated it in Python and uh this was the beginning. >> That's quite a tool to begin with. Uh yes it was uh like a longer tool maybe I think this is this is the first first version of it which is a very very I don't know maybe in 2018 or something like that and this is the tool uh it's in Slovac so is something opening openings for the for the MEP elements so so basically it was very simple back then because now it looks It's more like sorry more like more like this. So like I don't know how many tools are there.
Uh but basically it's not just the tools but I also uh like dedicated some time to to other tools which are not on the taskbar in the in the ribbon. Uh for example like uh hooks and some other telemetry and everything. Uh so wait a moment maybe I need a break. >> Yeah sure I will. >> Um meanwhile I'll just mention for people watching that in Py Ravbit a hook it's like an event trigger.
So when you do something in Revit usually you can subscribe to events. For example you try to delete a column that's an event. You try to open something that's an event. And with pyit hooks we can subscribe to certain ones. So when something happens we can react.
Let's say that somebody deletes a model uh a column in a model. We can detect that and we can also prevent it. We can give a warning or we can also for example write it somewhere. Just some explanation beforehead. What is parade hook?
>> Okay. So maybe something more about the pyate hook. So I'm going to try the paravid wiki and there is some talks about it. So uh basically uh this is it and this is like the list of all hooks which are like supported by pyit and actually uh this is the name of the file uh of the hook. I'm going to show uh how it actually look look like and this is the name of the event uh uh in the Revit API.
>> Mhm. >> Uh let me show it what it actually does. So sorry. So I have my G repo somewhere here. So uh normally this is at the app data and pirate folder but uh this is my G repos G repository.
So it is in a different location. But I'm at the root of the extension. And you need just to create a folder u which is called hooks. And in this location if I put it like this you need to like create a file which is exactly or which has exactly uh the name uh like it is in this table. So for example uh this is for init initiation of the application.
So for example when rapbit starts this is being triggered. Uh when for example you are closing the document uh the the ravit model this is being triggered and you can like write some code uh which is being triggered and run uh when uh like this trigger or this fire fires. Maybe we can go to the custom tools wiki and I have a hook section also here and I use you can copy it from me for example don't be afraid and uh these are the hooks which are used in uh like uh custom tools. So all of these files which are here are uh here in the schedule and I for like So it's like a documentation internal >> like explanation what it actually does and what can you what can do with that. So uh here are some columns that these hooks actually uh it like showed some GUI window uh and whether it is cancelellable and whether it locks the results.
So I'm going to show you what it actually do. So I'm going to start or I will start the Revit and the first hook is actually uh on in it and if you like I can show it here uh how the how the code actually looks. So this is the app in it. it will fire uh in a minute and I'm going uh I will I will go I will skip this and somewhere this is updating the custom tools and I think uh this is opening uh mass message window so if I go back to Revit uh mass message window uh it's a window actually uh it's a web page where we share some new things about Revit or about me uh about the view. >> So now it has I haven't opened this this this has been opened automatically pyRevit.
So this is the Revit mail message and this is just our u web page and you can like uh see for example I don't know some uh this is this is some wiki wiki article about ACC. >> Okay. So this are like last changes new tools like news. Yeah, interesting. Or something like that.
And now I started uh now I started the Revit and actually I'll come back to it. It's uh just uh it looks like long but it's very easy because it's repeating it over and over that this is just >> Can you zoom on the code a little bit? >> It's a little Can can you zoom on the code? >> Of course. Is it okay or too too much?
>> Way better. >> Way better. Okay. So uh these are some these are just outputs as you can see uh these are my outputs from my library and I have like c in custom output module I have like different default uh parameters. We will come uh back to later and uh each single one uh I treat like this way that for example I try to uh uh read it from the uh custom tool settings in user config.
Uh this is a config file for a pyroit. Uh which is uh I will show you where should we oh not here to do it like this. So in data you have pyit this is it and this is the file. So we are going to open it. And here are actually all your settings for pirate.
And if you scroll, >> it's individual to all users, right? On each computer, there's going to be individual. >> You need to set it for each user. So this is not like very good for deployment. You need to maybe seed it then uh then it's then it's better.
So for example, this is for custom tool settings. Uh this is for my other two tools. And what it actually does maybe I can like uh this is the one string and this string is uh is uh like read by that application that other script. So this hook locks is actually read by by this. So user config is that file that uh this file custom tool settings is this section and then uh hooks is actually uh this variable and you can write it here.
>> So and and how do we get user config variable? >> This is actually the like preferred way normal typical I haven't like this is private thing. Oh okay. So it's internal. It's like this done the ravit and >> I haven't created this.
I just used the system which actually like uh created. >> Okay. Uh uh so and I'm doing this for every every uh single variable and if you don't uh if you don't find uh this thing in user config uh then you uh like create it or you use just the default one which is in this output u uh custom output uh uh module. So modules are basically in uh I need to go here in parid extensions in the lip uh folder and if you go there this is the custom output so basically there are like dev log hooks and this is the default just to be there it's uh almost never like used so it's uh it's just hardcoded so you don't need to uh do it do this this way >> and Then uh wait a moment I will expand it. >> Okay.
So when user runs ravit application it fires up this um starting script where you just pretty much set up the config correct way so everyone has the correct paths correct default settings if they don't have any right >> yes yes but at the same time I don't know where it is maybe because this is like uh the company config is actually a thing which uh because it is just for the single user but you can use it You can uh do the same thing for the whole company. So uh it is in uh we have it here. So this is our uh like city config in and the main can find it here. Maybe it's in deployment where the moment I need to find it. So you have actually this file you can copy it from here or uh the copy is also uh in the GitHub repository uh and you can just copy it and place it uh anywhere and actually what it does is that prior to uh the setting from the pyit uh in it looks here and it changes the settings in the pyabic ini.
So you could like change it here. So uh for example in some network location which is accessible for everybody uh in the company and you are sure that everybody has all of these things like set uh like correctly and the same way. So for example if I need to change the language I can do that. So we can do that together. So now I think it's still in Slovak.
So if I create new file, >> oh I can see EF tools by chilizer. >> Okay. So this is our template and I will create for example architectural column and if I create architectural column uh there is a uh there is actually a pop here which is the in the code and if I click uh that more info that I want more info about architecture columns uh some uh rabbit uh rabbit wiki actually triggers and I can like see that okay this is about it is in Slovak but it says that you need to use structural columns if if this can be applied >> uh or for example like in place element or model in place you can click on that and you have like some brief explanation why is it uh like wrong approach and if you uh if this is not enough you can click here and there is an like um uh article about it explaining it like further or more in more complex way maybe or you cannot like cancel nothing is like created or you can click on that and click create but now I can create for example I don't know floor or leave it like it is because this is also stupid approach so we can do it that way and I create some inputs family and this is it but now uh this actually uh triggered a lock And I've uh like everything has been uh like written uh in lock. I can show you uh what's the code for this in place element uh hook. So where are the hooks?
Uh maybe here. So this is the hook and I I will just show this hook how it is. So as you can see that input development is actually u not in uh the standard list of hooks. So if I come back to this the you cannot find impulse element here but what you can find is at the the end there are like two things like comment before exec and common can exec and this is uh for image user and there is like comment id and how you can use it actually is like comment uh before exact and you can write the name of the function but what's really tricky uh is how to know what's the name of the function. Uh, and I think wait a moment I can copy from this other computer to here.
I found while ago. Oh, this is too too small. I understand some PDF like this. Sorry, this is too too large maybe. And this is list of all uh this is very very like old 2015 but I haven't found anywhere >> I I uh I'm sure that somebody knows better than me but this uh this is totally okay because like many or most of the features are here actually this is the uh uh like name of the feature for example this is the tool link cat and this is what you need to like u write in that name so I'll also quickly add to find those names you can use Revit journals because when you execute all the commands as you know there's journal file that kind of records what's happening you can find it somewhere there >> okay I was not aware of that I'm not aware of that >> u I heard it before I did not do it this way I also searched online usually I found it but recently this AI assistant I just started talking to Tai in LinkedIn that well we need to make a private hook for that and he went ahead and he found in journals what's the name of this command what fires up and he already implemented py hook for blocking this AI assistant >> okay so I'll open this in in place component >> and >> mhm >> it's something like this that uh there are some like uh imports uh name of the of the window or of the of the book and uh this is just the warning window so this is actually This comes from pyrovate.
Uh so you don't need to do anything else. So if you start um uh where it was here. So this is the window and it's like very sorry. This is it. Uh it's uh maybe not readable because uh this actually comes from another library.
uh and because you can change uh languages in custom tools. So for example now now it was like this was actually in uh in English. So if I click this, this is in English. Uh I'm going to now just save this. Uh by the moment I will also create work sharing file.
Okay. And save it somewhere. Uh I don't know maybe here like EF test maybe. I'm working in central but it doesn't matter for now. Skip.
I need to like restart the private and what I what I what I'm uh going to do is actually to go to this excel location and edit this config in and uh language is here and language zero is English and language one is sol language uh three is I think German and four is uh French I think so I now I'm going just to save uh just uh B managers and me uh have actually the permissions to edit this because otherwise it would be like uh like not very uh safe and now I start Revit again and uh it will magically like change. So if I come here uh what it actually does we can like open this uh hook text for example. So uh where it is is it is in module called like hook translate and hook translate is in uh library where it is here. >> Mhm. So library and this is a hook translate and actually uh this is just u uh order of the languages and then this all is uh one giant giant dictionary which actually uh uh contains all the texts of for all languages.
So basically it's this we actually like uh Rudolfph Steiner like uh actually help me to uh like translate it to German and to French and this is actually it >> and I just like parse this to that code uh then automatically so so basically this is just the GUI for editing that uh dictionary. So uh this is uh this is it. >> So this is actually the the dictionary. This is the first uh first item and this is this is the second item of the dictionary and >> just returns the text and uh these are the these are these are the buttons and here you can like provide what's uh uh what's going to what's what's each uh button going to do. So, so this is the the first button uh and this is not going to cancel the thing but it will trigger the hook and uh is all others actually will cancel the event because cancel is like uh true and the this uh last one is actually if you like click the cross uh in the uh right upright corner because uh >> you need to do it that way I So now I restarted it.
I open the the EF test and hopefully everything should be installed like now. So this is it. And okay, this is also another tool. Uh oh, sorry for that. I don't know why this triggers it again.
Never happened. Okay, but light demons. I don't understand why does why this doesn't work. Can I try it again? because this never happened.
>> Uhhuh. >> But now it works. So I don't understand what what I happened. >> Mhm. Okay.
>> So >> So on your when you open a project there is Ryan model checker checker for everybody right away as well. >> Yes. This is another hook and that hook uh uh contains uh this function. So it actually checks uh the it actually checks the model uh and uh writes the log uh and you can like view it in PowerBI. So if we come here now I will for example copy this because this is actually the in place element.
So this is uh some mistake in uh in Revit. And I also create this and created some duplicate elements because this I just created some warnings here. And now I reopen the project or I just click on this model checker again. I can see some there is some warning and some uh in place. again see employments uh eight eight of them that's okay so this has been changed but also locked so now I can go to dashboards and find this file and show it in uh PowerBI so uh I have this there is something wrong here it should be here this is yesterday it was here okay So I'm going to show show it how it is like manually.
I I don't know why it is why it is not working. Wait a moment cuz like it is always here maybe. Wait a moment. Do we have time? What are we looking for?
This is here. Okay. And it should be here. This is it. Okay.
It's empty. Okay. So I'm going to I'm going just to copy everything was here. over here yesterday it was there so should look like this and if it is like that if I click here on this dashboard >> uh it's it's there and I can open uh the model checker file history for example >> uh can you explain this part a little more >> okay uh so you click on the dashboards what's this menu what's happening what are we seeing >> okay so uh the dashboards uh are actually uh Just opening the explorer window uh which is actually like this but inside the pyate window and uh you are seeing uh one specific uh one specific folder which is actually uh uh like set up in custom tools uh settings and these are py uh powerbi reports. So now I can click on any of them.
There will be some popup and that's it. >> And this reports the individual to the project you have open or is it like companywide? >> Uh these are companywide. There are also like specific to the projects and there are also uh like PowerBI reports which are companywide. Those which are uh which are actually here are companywide and project dashboards are here.
>> Okay. So now I I will I'm going to uh uh to uh talk just about the company wide because these templates are actually available in custom rules like I provided like four of them. So now we just um maybe update this right I can >> so every time user runs this model checkers all the data also is put here in PowerBI. So for example this is uh one uh file uh and you can change it for any other file. Uh these are the dates and these are for example the critical warnings.
So there are like 61 critical warnings in this time stamp. So this is this is the time on the uh x axis uh there is a time and this is these here are the values and you can see that uh here we like purged or cleaned uh the file and how long it took uh to be exactly the same like before for example. So these are just the warnings uh number of sheets or number of model groups detail groups families in place families. So you can check like everything and I'm going to show you uh exactly this on uh this E file which we have just created how it actually >> Mhm. >> what it behaves.
It won't be that elaborated like this because we just created the file. But uh there should be two timestamps. Uh this takes some time. And now I'm just going to filter just today and find here. H this is so interesting.
Okay. It's not there because I have I have a filter here. Okay. So now it will be there. Okay.
So I made a mistake. This is the EF test. So this is our uh this is our file and I can see that like at the beginning it has like no warnings and then I created one or for example that uh like uh there were like uh just single in place family here the uh this this one here and then now uh eight of them are there. So you can like track everything down like this and you have like uh exact timestamps and uh if anybody in the company actually like opens the file uh it uh the hook is being triggered and everything is locked. So you can actually know by another uh dashboard uh which shows you uh who uh saved or synchronizes when uh who it actually is and uh it's not for like um uh preaching to people but just to like explaining okay uh why this happened and you can maybe like educate that this is not the right approach or something like that.
>> Uhhuh. No, this this data is so valuable to all B managers because most of the times well we can check something in the model but we don't have like this time data which is super super important and you also said that we can track who did what which sometimes can be really useful because it's not just to punish maybe users but at least to point out like hey maybe stop doing this thing please I can see you they start to be a bit more conscious. >> It's certainly not for punishing it's just for edit because sometimes uh it's in a inevitable and you need to create some warning or something or for example we have like plenty of architectural columns because we need to have them because they are on a facade and they are not structural is completely okay but if we don't have that uh in model you need to avoid it. Uh so for example you can uh check if you open the file uh by this that okay each of those elements were like created by by me this is very simple because I was here so obviously it was me. Uh this is something like uh who put it in pirate but for multiple elements.
So you can like select 100 elements and you don't you don't know just the creator but changed uh who changed the type and everything because sometimes also the type is very important and >> Mhm. Yeah, I like delete this and also uh delete few of this for example and like do it again. I can like immediately see uh the status here. But if I want to like see what has been what has happened whether I like purge it efficiently or enough I can just refresh it here. Mhm.
Interesting. >> So takes some time, but now like zero critical warnings and also like just two in place families because there are just two of them here. So and uh like you can create this uh hook system for like anything. Uh you just need to like think about it for a little bit. like actually the system uh which I do in uh custom tools is like this that you have this QA QC page here and basically it's like the hooks are for preventing things actually because you can like uh see uh the the effect or the logs instantly but then you I don't use uh this Revit batch processor anymore because the Revit page processor I don't know like whether uh you know what it is but it was actually I can show you where it is I have ink somewhere here um I know the project I I talked to developer tried to get him on the show last year but he was too busy he said maybe he will join in the future but I think the project stopped uh being updated on GitHub or something.
>> Yes. Yes. uh and but I think some other contributors always uh managed to update it for him but it was sometimes it was late uh so it really like holded me uh down uh because of like I wanted to upgrade to I don't know 2025 but the version was there wasn't there yet so I I needed to wait >> but uh then I uh like uh created this distributed version uh because Let's let's see whether I find found the >> but why did you use in this pipeline? Why couldn't you just take the hook and send the data to power? >> Yeah, originally I used it a lot.
I think this is it. Wait a moment. Yeah, this is it. So this is Revit B processor. In the 2024 we used it and in like in 2025 I actually I think created this distributed version.
Uh so basically this is the GUI version of the Revit based processor and this is the C which is like much better because you can use uh task uh scheduleuler to uh schedule uh task in uh Revit batch processor which does that thing that it opens uh for example uh Revit uh 2024 and runs Dynamo or Python script on every single model which is in the file list. So it's very easy to like configure and you can >> so it's great for using this kind of time task like every day make some exports every day open Revit models do some uh dashboards and this kind of stuff right >> it's like task scheduleuler if you don't know what it is is like putting thing in u in uh windows and I don't use it for uh rev bas processor anymore uh maybe I I will do or definitely I will do but not not now but for example now I have this kind of uh uh this kind of action info uh I don't I think it's it's here just to just trigger uh Python script and it will do something so we can do anything. >> Mhm. Honestly never used this but I can see potential. >> Uh this is very similar to uh what is called bird tools dynamo multiplayer.
I think I used also that but this is only for Dynamo not for Python. Zerid B process is also for uh Dynamo and Python as well. Uh but you need to adapt the Python script for uh that version uh because obviously like the pirate uh libraries aren't uh accessible for that. >> Mhm. >> So that's that's basically it.
Maybe we can like this was actually the the distributed model checker. Maybe we have time we can like show the content extension very briefly. >> Yeah, sure. >> We still have like 30 to 40 like minutes easily, even a little longer. So that's fine.
>> I just want to say something right away that I'm so impressed how open everything is cuz your whole custom tools extension is open. I know that many people struggle with that because company many companies try to lock everything. Ah, we made it. We're not going to share it. We're not going to show it.
In your case, everything's super open. You have even a whole wiki opened. You even have like PowerBI templates. It's amazing how pro opensource everything about custom tools and what you do. This is like definitely like the big impression.
think that I owe it to the community because I have also learned this way and I understood I understand that uh when I was talking about how how I struggled to get what the Revit API is or I don't know what else I struggled all the way. So uh everything or every single example actually if it's also if it's even if it's not very elaborate or smart it helps because you suddenly know that at least it works. Maybe it is quite lame, but it works. So, >> well, it's definitely smart what you're showing. It's impressive.
>> Okay. >> No, but it's cool that your company is also on board with everything you do kind of shared publicly, especially the wiki. I did not expect to see wiki this open. I knew that you had some kind of wiki, but I always thought that you have internal and external completely separate. It is actually it is I'm I'm showing you both but just single one is open like uh this is uh this one is completely public this is public page uh but uh this one in Slovak is our internal one >> we fine basically my uh no not this one where it is this one is basically my project and this is uh one >> uh but I think like maybe half of the tools uh I share and half of them I don't would not share.
It depends because it you need to evaluate some evaluate some things but uh >> yeah it's still massive what you're sharing all this wiki because people now have not only template of like pyit they can also see how to create internal wiki how to document stuff how to kind of communicate it with others >> and I still think that for example the concept for the custom tools wiki I just copied from asan and firease wiki because I it's still in the ocean So, so uh it's very similar and uh it's really works. It's very like uh uh it's not time demanding to create something. Uh it's not because I I used to do this in HTML, JavaScript and CSS and it was uh like I learned something uh some things along the way. Uh it was like I appreciate that but it was time consuming. So >> yeah.
Yeah. Notion is straightforward. You change it's done. >> Yeah. It's big editor.
So the other thing >> like anybody can you like even nonprogrammer can do is this content extension uh it's uh like just uh uh structural folders uh and for example if I want to create it uh this is obviously everything in SL but this is just a chair very simple one or like I don't know sofa uh is in 2024 because we use uh we still use 2024 and 2026 at the same time. So it's something like this and you know that this is the content version of that sofa and everybody uh has this extension and this is actually like mapped uh from the network location. So this is not uh for example shared. This is just uh this is only internet tool but you can do it very easily. Uh if you have your own families which you uh want to prepare uh and it this is not just for the families but also for uh containers.
For example, if you uh want to have like this is for Windows for example, I want to upgrade the model and you can have like some system families or some schedules tags all in one f >> accessible for any monthly. Uh >> so it's like company standards coming to any project. You can copy the schedule. You can copy anything to your project that it will be uh uh it will be like set up or for example room schedules with parameters and everything uh and some standards for example the data standard uh for the parameters how you are you need to use them or AI assistant and some norms and everything. So >> Mhm.
Can you share some code how these buttons are made so others can see that this contain buttons fairly is not code or uh there is a one liner maybe some sometimes so if you click uh if you out click on any uh any icon this will actually open and what it actually is if I go uh where somewhere here so this is uh network location like the network mapped uh f uh folder And this is the extension. So you just need to create uh tab and then the panel and then some pull down. The pull down is actually uh uh uh this this button and then to create uh for example this is door uh one wing door uh interior uh folder and then go inside and there is a uh there is just the Revit file which or Revit family file and it needs to uh end with the content RFA and that's it. There's nothing nothing there. Uh this is the here are the icons and the bundle actually.
Uh wait a moment I blocked myself out. I will do it this way. Where's the subline text here? So the bundle is as easy as this. So the tool tip and the tool >> and just the description of the button that's shown on the go here and uh here here is not >> this is actually it.
So but there are some uh oneliners maybe here in these containers. So if you go inside here is actually a script because you cannot I think open RVT or like RV RFI. So at the moment uh there is a mess on my screen right now. So this is it. This is like a very simple this is I just tried something.
This is not necessary because this is commented out but it's just this one line that you just Sorry I going to like maximize it. I I I'll just use this like hardcoded uh uh location because every for everybody this is the same because it's just an internet that's it. >> So this is very very very easy. If you don't uh need this containers uh you can do this without any programming knowledge at all. H just to quickly recap so everything takes to create it is just a folder structure that paravit can understand while David is showing you you will notice that they have special names like blah blah blah extension tab panel that pulld down content parade understand it as how to put it on your toolbar and how to function for example this dot dot content folder is what you see all these buttons and a ravit file well family is just brought into the project.
Just a quick recap so everybody is on board. Okay. No, this is looking good. Very simple way to share a company standards >> that for example like uh I understand that I like uh haven't shown uh that also these hooks uh which are like triggered can be uh like analyzed in this PowerBI. So you can actually like go here and here should be the books.
>> Oh yeah, this was my question probably. So you just open it like everybody has access to this show you like everybody in company not not just the be managers and this loads this is a little bit slower because this is PowerBI obviously like there's nothing here because it's 60 and it haven't uh it hasn't been uh uh like updated. I'm going to update it and hopefully I will be there doing all of these uh nasty things. So, uh this is me. So, I'm going to like just uh maybe filter last five days and this is this is it.
Oh, sorry. Uh uh is still not everything because it should be maybe it it hasn't been like uh maybe it hasn't been uh uh saved yet. So I'm going to do it again. So uh where it is now I'm have a bad position. So for example this and now it is it in Slovak because we like to change it.
And I'm going to click on this uh for example columns. It doesn't matter columns. And I create something uh for example this this and this. And like without anything I should be here if I refresh it. >> Mhm.
Also after that, can you explain us the PowerBI connections a little bit more? >> Sorry. Mhm. This EF text. Okay.
Okay. Maybe uh maybe there is some other thing. Okay. because I wanted to show you also the the the exceptions should be here at my simpler. Let's see if I am correct or not.
No, it's it's here. So, so I I don't understand why this doesn't work. I'm going to save it. And maybe create some different thing. I don't know why this doesn't work.
I don't know. Maybe our maybe some maybe import somews insert and uh like our link cat. So this is also uh like locked and I think should be something now. I need cat. >> Yeah.
Okay. I need it in three 3D. It's another hook. So it it is here and it should be here now if not so I don't understand why because like it always maybe I don't know it's not here I don't know why because like it always hooks I tried it yesterday because I wanted to be But it it's here just a single one. I don't understand.
Okay. So, this doesn't work right now, but it should work on your computer >> because it always works for like everybody. So, but uh this you can uh actually I will figure it out maybe later or do we have some time? >> Maybe it's not so important. I don't know.
>> Uh we have some time. I just wanted to ask that's okay that it doesn't work. We kind of get the idea. Probably there is some filter somewhere. Uh I just wonder about how this connection with PowerBI works.
So you explain the hooks pretty good. So hooks fired up. You create a logging. How does this kind of event breathe into PowerBI? Can you just share this little moment with us where documents and get recol and here here and here are the hooks.
So for example I don't know uh document synced. So if you're syncing the document the hooks is also like triggered. So how it's actually uh saved is that uh I'm just getting the uh central path and the file name of the of the file of the model. Uh I'm doing this only for the file extensions of RPT because I don't want to like trigger anything from RFA or any any other >> to the project. >> Yeah.
And then I uh like read the user configs because this path is in the config. Uh and uh then if if not found the default is being used and uh then I just like uh like concatenate the sync path and the file name and then appended this thing. So this is uh uh the the temporary uh file and uh or sorry at the moment. >> This is it. And if I go if I go back uh and I can show you the location where it is stored is in here, here and here.
And for example, the hook locks are here or the sync syncing is here. It's this is the EF test which I actually just now use. So I can show you that. So where is the this is it. Okay, it's here.
And this is the synchronization. Okay, I understand what's actually wrong because I need to like uh yeah, I've lost the engine or or something. I need to restart the rabbit. So that that's that's maybe the the thing. So uh this is the uh time stamp uh when I actually like sync to the the file.
Uh this is the duration of the of the synchronization and this is the user. So and if you like open like uh anything larger, it looks like this. So >> and uh >> so all the time stamps are the same >> and and then in like uh PowerBI you have this uh transform data and in that transform data you need if you like use my templates for example you need to do uh this thing that data source settings needs to be changed for something else your location >> just set the folder where all the logs are recorded and it's automatically refreshed. >> Yeah. Yeah.
Because like at the uh like the underlying data is just this and you can go uh in par ABI uh where it is sorry data and actually it like uh does this uh steps I don't know 10 or 12 steps each times and uh for example replace you nothing and uh like creates that that uh schedule or dashboard. So yeah. So so there you just clean up all the steps. I I know this menu. So there like you take the initial data and then you kind of clean up do this do this do this.
So the final data is better for PowerBI right >> basically like for each file uh one log file is being created and constantly it's appended and all the folder is read by the PowerBI then as the principle. >> Mhm. >> And it's being passed that's very easy uh to do in PowerBI. You don't need any like programming for that is using the uh power query. Can we go back to the Python code?
Because we stopped at the temporary file, not the log file. >> Oh, wait a moment. I will where this maybe this is it. And I can use uh for example also this is very simple like at the beginning but I think it's somewhere at the end. Oops.
Sorry. Uh this is this is slightly different but it doesn't matter because this is this is actually the logging in like uh app in it. So I need to open this uh version locker for maybe it will be simpler to do with something else dog sync and dog sync or dog updator. I don't know which will be the best. Uh maybe do saved.
Okay. Okay. So basically this is it. So this is the log file. So I just like uh open a file with this um uh flag appended.
So if if that was like W, it will like rewrite uh the the whole thing. But I need to like actually I need all of the other like um data to be to be there and the append actually just appends one line for this uh syncing or this is saving actually in the end. >> So uh that's actually it. This is maybe a little bit uh like more complex because I also like read the temp file here. Maybe I was.
>> Yeah, this was was my question because I saw the file first because there are like two two uh two hooks like doc saving and doc saved and doc syncing and doc saved. Doc syncing is starting syncing and docu uh synced is uh like when the process has ended actually. So maybe I can also open the because this sorry doesn't work stupid Windows. Okay. So the temporary files they just kind of back up to store data or >> yes there is just uh the syncing is actually like much simpler and maybe I can like show it in the uh in the logs when somebody uh where it is there is only a time stamp nothing else time stamp and u and and that's it.
So maybe I can wait a moment open the logs. So where where are they? hook logs and maybe sync times and maybe no everybody is synced but here uh for no nothing is here I will try to sync but I don't know whether it is like broken and I need to restart the Reddit now because I think guys >> Mhm. >> maybe I can restart it because it should it should work. Oh, I I synced but I haven't.
Yeah, this works. So once again now the tank is there and now it's like erased. Have you have you seen that? >> It's kind of flash. >> Yeah, because it's like this is very small file but for the larger files it can take like 30 seconds or something like that.
>> So cool. So basically that's the that's the main principle that I will like temporarily store that's why it is called like temp like temporary because I like temporary store uh just the time stamp there and then in this saved I just uh where it is uh I just like create or calculate this time that's the duration so I just uh this is actually the date time which is like right now and that right now or I just like that's it. So, >> okay. Use it as a timer just something to kind of start and end the timer. >> It's not like a timer.
is like a time stamp and then I know what time is it or Python knows what time is it and uh I just parse the uh the text in the temp file do a date from that and uh then just like subtract it and then that's it. >> Yeah. Yeah. Yeah. Just to calculate duration.
Got it. >> This temporary file what confused me because we stopped on that one and jumped to logs and I was like what's happening in between? >> Sorry. Maybe I like make it more complex than it actually was. So >> that that's okay.
That that's why I keep bringing it up because I see there's a little bit disconnect that can happen. But yeah, >> sorry maybe maybe I like to arrange the the discussion too much. So that's my issue for sure. >> It's okay. Don't worry.
It's it's great. Don't worry. So what's happening like you have all these hooks that not only do stuff they prevent users from doing wrong, they provide additional information, but also what's important is the logging. This is what so many B manager miss because I had also questions like ah can we get this data out and I'm like only if you kind of track it yourself somehow and this is the perfect example. So you create all these log files for projects where you keep adding data and then you very in a very efficient way use PowerBI to grab all this data and just give you kind of reports which can which are really really useful from what we saw so far.
At the same time, >> you got like the timestamps, the users, the issues that like it's amazing. >> Yep. And at the same time, you can like you have like a tool set in custom tools to fix some of those issues like there there is a hint actually in uh the upper dashboards uh uh here below what to actually do. Uh but if you go here in this mult checker like all of these is for like uh fixing the issues for example like DWG schedule this is linked so uh okay it's uh it's going to work uh also in this like 20 26 but you can like find it like this but if I like just import >> the DWG let me show you this is another hook that you you are not supposed to duplet and I'm going to do like import the same thing maybe here. Okay, I need it in 3D should be at the same location.
I will is it there somewhere? It should be there. Okay. So if I go in manage links I have like two of them but this one I can uh click on show. But for this one which is imported I cannot.
So I don't know why it is not here. So you can still use custom tools for example because like here is DWG schedule uh entire project and uh import it you can like while linkify you can just like select it and delete it for example or or just show that is here is here. So this is like everybody knows this linkify. So >> there are like plenty other like features for I don't know um like just comparing uh text notes and feed factors or I don't know what else basically many things from the model checker. Yeah.
>> Mhm. Mhm. Uh it's there's so many things here which are really great which I really like. That's why I wanted you on the show because I haven't explored your full extension but I saw what you do with like hooks there like I saw some connections didn't understand everything right away. So it was really amazing to get you on the show to share it from yourself.
It's always best to hear from the developer, not somebody who tries to understand what's going on. >> Sometimes even I forget. >> Yeah. Sometimes even I forget what what tools I have. So >> I know this.
I once started making tool that I already did before. >> Yeah. This happens to me uh as well. Yeah. Yeah.
>> Yeah. Yeah. It just happens when you have like hundreds of tools. You're just like did I do this or did I not? Maybe I imagine this how I just do it faster than finding it.
No, this is amazing. Okay. Okay. So, uh one other like exception is that for example you have this kind of uh not obligatory like config file. I will show you where where it actually is.
And you can like cancel some of the hooks for be managers. But this this so for example if I now uh here is uh like this is like all the uh ones but if you sorry if you fill it with zeros and save it and now I'm going to I don't know what or maybe create oh sorry create a model employee base oh sorry this is not uh Not cancel at all. But maybe this problem is this. No, by the moment import cat should be consolable. So where is the import?
Uh insert import. Oh, okay. So now not all of the hooks are cancelable because also like I was I need to be like sometimes notified that I'm doing something wrong. For example, if I'm like importing something in 3D or something but importing you like sometimes you need to do this but you need to like know what you're doing. So you can like be managers can uh actually uh turn off the hooks but basically you are like if uh this import uh cat it's like on the second position.
So if you like change this to one suddenly the hook uh should arise. >> So but this is >> yeah so you have this kind of guard rails in place. All of this is actually like placed in I think I already opened it somewhere here but I'm going to repo reopen it in your like C and you need to create pirate extension. So it's very like u niche like no no no uh normal user will like um understand that should be here and there is actually u there is actually a manual for that how to turn off the scripts uh turn turn off the hooks uh here below turn off the hook and here is also video how you can do that and where to place it. Not impressive.
It definitely gave so much ideas to many people about hooks because people going to watch this. They will finally like have a good example to rely on. They will also some of them going to discover custom tools which is a good thing. There's definitely a lot to learn. Even for me, it's amazing.
Great. Um I think we have to wrap it up a bit. If you have something kind of final things to share, that's totally fine. We can also have a few kind of quick chat about AI if you want. So you can choose.
>> Yes, maybe uh like uh I wanted also like maybe uh talk a little bit about the deployment. And I understand that this may be was all covered by others but this is very like u much uh or a large advantage of pyrovid because uh for example I covered soft thing but also the installation process by using for example CLI and other things this is advantage over any other adding because >> because it is >> and I don't know what what else you want to cover so let me know >> we are kind of time restraint now because I would love to dive into that but we're already almost 2 hours in >> so I'm trying to wrap it up but it sounds like I have to invite you some other time on the show to talk I think we need to limit some topics it's amazing to talk about all of it just like I know that there are so many things you can share with us deployment is a big one also noticed uh a lot of people want to share it because that was a big pain everyone had with Dynamo and Parvit solved a lot of that and I know that you also have this auto updator which is great which is also not complicated. >> Yes. Yes. Basically that that's that's the main thing also I totally like forgot for that that this is like being upd updated automatically.
So if I change something like everybody on the team uh has it if it's like pushed uh uh to make it repos repo and and also like anybody in the world if you like installed it it will be like updating like automatically because uh it's just in the app in the hook that like just it just clones your your repo again and that's it. So, it's on Revit start and it's uh also on uh like uh system start as well. So, if you restart your computer or restart your Revit, you have like the new uh uh updated uh extension. >> Mhm. And the script they can find it in your what was it the hook for starting the ravit app start or whatever to find the code for the updating repo.
It's >> it's it's there. It's there. It's there or uh it's also like here you can manually click here >> and basically like uh this is it. But uh I think this uh like uh just triggers a cmd file which is also copied to startup location in Windows. It's still the same thing like similar to installation.
>> So if anybody wants to learn how to do that, we can find it in custom tools. Definitely >> you can just copy from there. Yeah, feel free to to steal because this is not >> that's the open source feeling uh spirit. Sorry. >> No, this is great.
All right, and we're going to wrap here. Just a few final questions. Maybe we don't have to expand too much on it, but I just wanted to ask you, do you use a lot of AI for creating your tools or uh what's your just opinion on the AI these days? >> I don't think I I use a lot of uh AI. I use I use uh defin I definitely use AI but I uh I'm really worried about these agents because I don't think uh like we have there is a definitely privacy issue and also you sometimes you don't know what has been changed so I need uh to be maybe more specific that do something just on this uh specific file uh but I use it also for coding but sometimes it's more hallucin hallucinating sometimes less.
So it's a for for for learning to code is it's a real game changer like it's is much better than it was like I I started like prior to YouTube with Revit for example. So if you if you compare these things this is like totally different world. So it it is totally different world also lots of new challenges especially the issues for B manager when this kind of agents come to models especially without really kind of uh how to without per like asking permissions and so on we never know what's going to happen but yeah we just have to get used to that I guess not used to that but we have to kind of keep this in mind that that's an option now >> but definitely I think like there reason like AI bubble or hype or something because like people cannot distinguish between what's AI and what's not what's like normal programming at all and uh and also I feel this danger or thread or what it is that if like like anybody if anybody uses AI for programming it's completely okay if it's the prototyping or uh if you can check the results but if you cannot uh it's dangerous I would say So >> Mhm. you can get blinded what's happening. >> You need to observe what what you're actually doing.
>> Yeah. Not not not blindly like uh like uh having a faith that AI is smarter than me because sometimes it is but sometimes it isn't. >> It's also about questions you ask and so on. And the thing I noticed that when people don't understand the topic and it can be anything programming like being about lawyers whatever when you ask AI without knowing the topic your question is already sometimes a bit wrong and AI feels it and gives you like answers accordingly but when you understand the topic you speak with AI in completely different level different kind of language I would say same with programming once you understand raid API basics or just kind of software basics in general speaking with AI about code is completely different cuz we can also fact check it. We can also notice like no way m that's not happening.
You're hallucinating and then it says like oh yes you're right I'm hallucinating. So I think this also adds to the problem because sometimes it's overconfident what it tells. >> Yes definely but uh I also like have it uh said like uh uh to not be so overconfident. Uh it worked for a while but now it is the same as it was. Mhm.
Yeah. We're getting back to more reliable path. >> Sometimes you you are get stuck uh in some like a hell that uh you think that okay uh this is so easy that I'm not going to write this. Uh it's just I don't know 50 lines of code uh AI will do it definitely. and you are trying for the 20th time and uh you you spend uh I don't know 20 minutes and maybe you have you you had uh done it uh if you had do it like manually like it's sometimes it's a waste of time even and some sometimes is not very good I don't know >> it depends on the task it certainly gets better but at certain point ravit API is so niche and after all it can only give you what it learned from online and documentation.
There are certain things that even we with like years of experience we start doing it we have to go through like and figure it out how it works. There are like always these edge cases and with ravit there are always workarounds sometimes even in API. So yeah so it always depends on the topic but if you ask something like delete me all walls AI is going to be great at that >> for sure. But but for example uh uh I have like limited experience but with the with this uh MCP py extension with clo uh I did it that way or I tried that way that I asked something and then I asked provide me with the code and that code was uh always okay but it it is a very limitative experience so I I don't know maybe I'm also hallucinating right My understanding with MCP is so we have like Revit, we have all this Revit API and we can create our custom tools but MCP is like the middleman who has access to AI and we can provide all the tools. So theoretically you can take all your code snippets and turn it into library of how things work and then it's more reliable.
So when it's needs to change parameter you can give it the precise tool include your logging tools and so on. So theoretically it's possible, but I'm still not sure how I feel overall about MCP. I haven't played enough with it also. Going to be honest right away like I need to get >> it's not like the silver silver ball like don't get me wrong. It's like uh that if it uh has managed uh to do this task the code was okay but uh it like uh very often haven't managed to do the task.
So yeah and I I the the difference is that the MCP the model context protocol the context is there so like the AI can see actually the database and that's the main difference maybe >> but I don't know >> you can also teach it things because if you ask it like I don't know create me certain like dashboard and so it can tell you like I don't know how you can also teach it things because there are like certain files you can create give it tools and then it's like oh I have the tool to create dashboard Erik asks Me too. So you can also provide it like literally with the tools how to work with Ravit. This is also what I understand about MCP is that can give you benefit of talking to AI because you can give it exactly how to implement certain things. >> Maybe. Yeah.
>> All right. I think we're going to wrap here and I always end with asking guests on one piece of advice for beginners. Let's say that somebody just discovered Parrait wants to get in and doesn't know programming. like do you have like one piece of advice you would share how to get into this world? Yeah, I would say like uh don't be afraid to break things and maybe uh try to see issues in the like the real world and uh like try to uh fix them sometime somehow with the code and maybe also that the issue is uh very often that the perfect is the enemy of good do it somehow and if it works it works and if it's lame it doesn't matter because it works.
Because if you are learning like it's okay. So >> and uh maybe uh like don't be don't stag in tutorial help like follow the tutorials. They're like uh very very great thing but always change something and uh find your real world projects and uh and build uh upon them and then come back tutorial back to another tutorial and >> create new project and and I think that this is the the the curiosity andol evolving is very very important here and also maybe like embrace your laziness uh because like lazy people improve the world and lazy and curious maybe so >> no so very practical approach find problem try to fix it see what happens >> yeah because sometimes people only like uh learn and don't do actually anything at all and they have like some experience but they don't have like any decent uh portfolio but in this approach approach you will get some portfolio done like very early on. >> Mhm. >> And you will be proud on yourself so very very soon.
So it's motivating. It's it will be driving uh uh yourself. >> Yeah. Beautifully said. Perfect.
Yeah. I think we're going to wrap it up here. Thank you for coming on the show. Appreciate it. >> Okay.
Definitely. Thank you for inviting me. >> Thank you everybody. I hope you enjoyed the show. And if you have any questions to David, you can find him on LinkedIn.
I'm going to try to leave his social under this um in description also links to his custom tools and everything. And if you have any questions, either ask him on LinkedIn or maybe in the comments he will see. Either way, it works fine. And one little question I have, if you have any other guests for Parvit podcast, I would also appreciate to know. Just comment below in the comments so I know who to interview next.
Thank you everybody. It was a pleasure David having you on and everybody happy coding.
### How Aussie BIM Guru became Automation Expert in AEC? pyRevit Podcast #4
https://learnrevitapi.com/podcast/py-pod-04-gavin-nicholls/
How Gavin Crump, the Aussie BIM Guru, went from Dynamo and visual programming to Python, pyRevit and automation expert in AEC. pyRevit Podcast #4.
## Transcript
I mean, I've got a bad habit of automating everything. Like, you're going to laugh when you see how this works, but it it worked sadly. And sort of realized, oh, like visual programming. I've done this before. This this sort of makes sense.
Actually, that's what used to come up in YouTube when you used to look for my channel. It used to be bum guru. It was just underwear ads. Oh, yeah. I mean, the package manager in Dynamo is a bit of a graveyard these days.
There's so many old abandoned packages. It's a bit sad. Then I was like, whoa, I need to learn that. Steel is one of my favorite things in Pyro. Just the amount of control flow that Python and written programming gives you.
I'm definitely Aussie and I'm representing Australia. So that's the Aussie part. I see the excitement about AI is a reflection of how frustrated everyone is with the state of technology in our industry. They have to give us the clear instructions what they want and then the second one like, okay, actually we're safe. They never do that.
But I mean at the end of the day, programming should be a personal journey for anyone. All right, guys. Today I have very exciting guest today on the show. You already know him. His name is Gavin Crump or you also might know him as Aussie Beam Guru.
Good day, mate. How are you doing? I'm doing well, thanks mate. Um really, really great to be on the show and finally sort of get to catch up again. Um I've been watching what you do with a lot of interest and I can see you're very passionate about similar things to me.
So I really look forward to um sharing our knowledge and our experiences and and also sharing it with your audience. So thanks for having me on board. Yeah, sure man. Likewise. I got to say that when I was starting with YouTube, I was looking to your channel non-stop like just to kind of validate my idea because in beginning I thought like okay there is not enough tutorials on pirate and it was before you started sharing about pyrait.
I thought like okay maybe I should share it but I was always having this like is anybody going to watch this? But then I look at your content because you cover Dynamo Python. So I saw that we are kind of aligned in this case. It gave me a huge motivation boo boost to kind of start. So thanks for that as well and all the content you share as well.
Oh you're welcome. I mean one of the main reasons that I guess I made my channel was I wanted to see more people um get passionate in sharing and teaching. So it means a lot to know that people see my content and take inspiration from from what I've done. And it's a very humble little channel. Like I don't I never really aimed to get a big following.
And I guess comparing to other industries, it's a small following, but for architecture, it's probably a pretty decent one. Um, but yeah, I just wanted to pass it on. Yeah, that's a big one because we were such a niche topic. It's not just architecture or beam, it's like beam, ravit, and then you go even in more specifics like Dynamo, all this stuff. No, you have a huge following for sure.
All right. I thought that I want to ask you like why Aussie Beam Guru? How did you end up with that? What was your like process when you were coming up with the name? It's a good question.
Um, so I guess in the Australian market, Bib Bim is known, but at the time I guess there weren't really any people that were really publicly representing it in a domain like YouTube. Um, there was people like the Revit Kid and Revit Pure Bim Pure now. Um, but there wasn't really anyone that I was aware of that was getting out there in the same capacity. So I thought, well, I'm definitely Aussie and I'm representing Australia, so that's the Aussie part. Um, BIM BIM was an interesting one.
I thought about doing something besides BIM because I always knew BIM has a shelf life, right? It's not going to be the way we do things forever like CAD and you know there's AI, there's all sorts of ways of approaching these problems that we look at. So, but I decided at the time BIM was very much what I was doing. Um, so I thought well it's going to last a little while hopefully and if I need to rebrand later it's okay. Um, and then I guess guru was a just a fun word.
I knew that um even before I went to YouTube, I I was on LinkedIn quite a lot and I had a lot of interactions with people from overseas um and particularly you know mentored a lot of people from India where BIM was really just taking off and I knew that that was a word that would probably resonate with them um sort of like a spiritual guide mentor um and whilst BIM's not a religion per se you know I like the idea of the the wise teacher who um is really just there to to guide you in life and I saw a similar opportunity in my channel for guiding people through the industry and some of those more difficult skill sets that you know were hard for me to learn initially. So I wanted to sort of make an easier journey for them. So it sort of yeah Aussie BIM guru sort of landed and I built my logo in Revit using field regions which yeah and then I just sort of started sitting in front of a camera and eventually people sort of liked what I was doing. Um I used to get like you know five views on a video. One of them was my mom.
So, um, I started I started small for a long time. I think I got a thousand subscribers after a year and a half. So, it, um, it takes a while for it to kick off as you probably, you know, experienced too. Exponential growth. Yeah.
But, but you've definitely, um, come a long way with your channel and and your brand as well. Like, I remember downloading your private toolbar and sort of saying, "Ah, Erik Fritz, who's this?" And then sort of started noticing you in the socials and you've really sort of made a name for yourself, too, which is great. So, yeah. Well done. Yeah.
Yeah. I got I found it really exciting. It started by accident. I mean like at first I thought like I'm going to make some tutorials on this and that and then more questions come in and I I just enjoyed the process. This is the big thing that if you if I would hate the process I would give up.
But I kind of enjoyed like making the videos sharing it and then further further along just more things came along. Actually in the beginning I was considering calling myself something like beam buddy. I was this close to make it but then I decided what if I Google it. Apparently in somewhere in Korea or in Asia, there is a big big Korean group called Beam and they have a popular song buddy. And I saw that as a competition.
I was like, "Okay, if anybody would ever kind of Google Beam Buddy, there's going to be this song with millions of views. It's pointless to like no, I gave up on that." And I'm very glad Erik Fritz is much happier with this than any other things. Personal brands are very powerful and I definitely encourage other people to like consider them because your name becomes your search. Um it does make you very accessible of course suddenly anyone can find you right but um you become more than your name in principle. I was actually um having a laugh because on the note of finding the wrong thing I when I first started doing YouTube there's a an underwear brand in Australia called Aussie Bum Guru and actually that's what used to come up in YouTube when you used to look for my channel.
It used to be Bum Guru. It was just underwear ads. was a very interesting search outcome. But luckily, I've beat them in the SEO now. They don't show up anymore.
So, now everybody looking for their stuff and finding you. They're like, "What the hell is Beam?" Like, "This isn't what I want. I want underwear." I see. That's funny. All right.
Listen, there are so many topics, but I like to start with the kind of the beginning of the programming journey of the guests. So, could you tell us just to the beginning to your first hello world statement also? What language was it? Just let's go there and kind of continue down this path. Yeah.
So, I I guess I sort of broke my programming journey down once and realized that I was sort of programming before I knew I was. So, I used to um hack Super Nintendo ROMs back in the day for fun, which involved breaking into the memory of the ROMs and changing addresses and memory and moving pointers around and doing things like taking doors and pointing them to different rooms to start rearranging maps. And I got really into this game called Super Metroid, which is one of my favorite Super Nintendo games. And um we effectively more or less rewrote the game from the inside out. And a lot of people since then have started making new assets in these old 32-bit ROMs.
Um and I guess at the time it didn't really click, but I was sort of programming already. I was looking at pointers and memory and you know very very like heavy programming concepts, but I was just having so much fun. I didn't think about the fact I was programming. Yeah. How old were you?
Uh so I'm 35. That would have been when I was probably about 15. I was doing that. Um, yeah. So, there there was like a few started with hacking.
Yeah. There was a few middle ground programs that other people built to help. So, there was like an address viewer where you could look at the raw hex hex codes that built the um built the ROM and there was a a tile editor that sort of built the world map for you. So, some of it was visual, some of it was um, you know, using pointers and memory addresses. Um, but I guess the second experience I had was about 2 years later.
I think I was just about to finish high school and I really enjoyed a game called Warcraft 3 um back in the day and it had a really good map editor built in built into it where you could build custom campaigns and it had a had a thing called a trigger editor where you could um program events to trigger on certain scenarios with conditions for actions to happen and it was a very simple concept but you could you could go a long way with it. There was four loops and sort of sort of things that you know Python does naturally um but built for video gaming. So that was sort of where I began. Um but I sort of took a break from there and didn't really connect programming to my career for quite a while. Um I found Dynamo in I think that would have been about 2014 I think I started playing with Dynamo and that was it was just a a huge gap where I just didn't really do programming um for recreation or for or for work for a very long time and then sort of realized oh like visual programming I've done this before.
this this sort of makes sense and sort of really found a new passion for for BIM and using Revit again. Um, which I'd got quite bored of doing manually by that point. So, I'd been using Revit for about four years and you know using Revit manually with no automation. You know, you've probably been there before too, right? It's not fun.
Um, you know, creating a sheet, renaming a sheet, all those steps that you know, just take so much time. When people discover now, they always have this kind of second kind of breath. they start hating kind of Revit so much and then finally find something new, something exciting, especially all this opportunity to automate. This is also for me when I discovered at first I was like ah this looks dumb. Then I start using it.
I'm like okay I'm only going to use this now. Forget about all the rest. The only way I mean I've got a bad habit of automating everything even if it probably doesn't need to be automated just because I know it's still going to be faster than doing it manually. So sometimes people freak out if they're like they want to do a task for two hours and I'm like I'll build you a script. it'll take you an hour to build the script and it'll take you 20 minutes to run the whole process instead of doing it for two hours and I'm like so for about an hour and 20 minutes they're holding their breath just praying that what I'm building that's actually going to work but um it's part of the fun I guess that that's a great way to learn as well I was on the same journey everything I had to automate everything the simplest task I just had to do it with the code and that what helped me learn it a lot faster yeah definitely and I guess um whilst I used Dynamo I was aware of like you know C and also pyRevit at the time and sort of found my way into those like extra layers of programming um as I went and you know just sort of became less abstract in how I approached programming over time which is probably what you found as well.
Did you begin with Dynamo or did you go straight through the Python pathway? Yeah. Yeah, I I began with Dynamo but I was very quick to jump on the kind of Python wagon because the way I started is I started watching some tutorials here and there and then we had this project in the office where we had to um make this computational design of the facade design. There are like lots of panels and they had to follow the curves and it was clear that we had to use Dynamo but nobody in the office knew Dynamo and I just started watching a few tutorials not long ago. I haven't done anything useful yet.
I was just kind of following tutorials and I just kind of started with this massive project in Dynamo. Somehow I made it. I still have no idea how. And along the way I also there was one node that was really really problematic. It was it was taking like 40 minutes to run and I thought well placing 15,000 panels sounds logical.
40 minutes is much faster than I would do manually. So I was happy. Then I noticed one node was so inefficient. I couldn't replace it with anything. I tried many things and I was so desperate.
Eventually I ended up seeing oh there's a Python node but I had no idea how to code anything again. I went to forums copy pasted bunch of stuff back and forth. It wasn't something complicated. It was something about list management. So it was like fine for beginner to kind of figure out.
made my horrible code and I saw like instantly like instead of 40 minutes, it took 40 seconds. Then I was like, "Whoa, I need to learn that. That's something cool." Yeah, I definitely had those moments. I literally um sadly enough actually stood up in my chair in the office and put my fists up when I first developed my first script that actually worked and everyone just looked over and said, "Well, what just happened?" And I'm like, "I think I just figured out the way I'm going to work for a very long time." I just suddenly it just sort of clicked all of a sudden. I was like, "Wait a second." like there's a lot more things I can do now because of this.
Um, once I understood list management, that was one that really made me frustrated when I first learned programming in Dynamo because I'd never really used lists as a concept. Um, when I used to program in in Warcraft, like you you had four loops, but you thought about them as groups of units instead. So, you were usually dealing with like battalions instead of lists. And I just abstractly didn't connect the the logic of what I'd done before. Um and I guess visual programming lists are quite different to like iteration in um in written programming.
So it was hard for me to connect to that. Yeah. You mentioned that when you made your first kind of Dynamo script, you were really exciting. Could you just explain what was the script? What did you do or what kind of problem did you solve with it?
Yeah, I took on a really classic problem um which was automatically numbering room uh doors based on rooms they were um pointing to and from. But uh I took it a few steps further in that I had to figure out when a door belonged to a room even though it swung the other way. Um so I tried to automate that condition. So I ended up having to build a relationship system where rooms knew they were more important than other rooms. So they owned the door in the event that they had the same level of importance as each other.
They went the direction the door swung. But like I made corridors really like unimportant. They were low in the system. self a door swung out into a corridor. It generally belonged to the room.
Um then once I'd wrapped them all up in groups by room, I had to then number them in a circle. So I tried to figure out how to sort them, generate circles by best point through through the points that were generated per room and number them from like the top vector and sort of spin around and pick up all the points. So it was a pretty complicated um first script. I did really challenge myself to begin with and it's it was an awful script. Like I looked back at it and went, "Oh my god, like this is like this could be 30 nodes maybe." Um, but it was something like 350 I think at the time.
Um, and I didn't know how to do things like index and shorthand. So there's a lot of get item at index, get item index, put them all back together. So I was sort of breaking lists apart and putting them back together. And it was very inefficient. But um, through that inefficiency, I guess I learned along the way different ways you could do things.
And and one really good thing I did which I recommend anyone does is I engaged with the forums like really early. So I use Dynamo forums from almost the start. Um because that was a tip someone gave me. They said don't neglect the forums. U make sure you don't just sit staring at a screen getting frustrated because you won't make it if you don't have the support generally in a new language.
So but yeah that's a good advice. I wish I followed that one. I avoided forums. Yeah. Every time I would go on a forum, I would write out all my problem in details and so on and then I would hesitate to send it because I already made the brainstorming and I was like, okay, I'm halfway through the brainstorming.
I might just continue kind of and I switched to Google and continue. And I I was very stubborn learner. I could have learned so much faster if I would just ask like, "Hey guys, how do I do this?" They would somebody would definitely explain me. It's easy. But even in that case, the forums become the forums become this, right?
They become the rubber duck. So by explaining your problem to the forum, you think about your problem. You might find your own solution even if you don't send the thread. So you can sort of use it like a duck debugger um if you have to. I guess that's the fun part of using forums.
Yeah. No, no, no. Forums very useful. I just always kind of I don't know why it's some maybe it's some some kind of ego or I just didn't want it to kind of look like absolute beginner even though I absolutely was. Oh yeah.
I don't know. There's something that always stopped me. I always like to find solution myself. there is I don't know kind of journey to find through solve your own problem. Ego is a hard one in programming, right?
I mean you've got to be vulnerable here and there and know when you're out of your depth and know when you might be wrong with a choice you've made and have to refactor bad code that you produced a year ago. Like I I have to do that all the time where I work like I go back and go whoa like I didn't I I really took a long way around here. I've got to go back and fix this. So, I think being vulnerable and humble um is often one of the first traits I say you need in programming because you're not always going to be right and someone's going to know more than you at some point and you know it's better to get a good exchange out of that. Yeah.
Yeah. I don't think that was the issue because I constantly rewrite my code. I I'm never happy with my code. I can spend like days rewriting the code and then I'm going to look at it. I'm like I should have done it better.
But I also talked with Ashan about this. He says like it never goes away. Yeah. Yeah, it's just kind of thing. It's just the iterative design kind of approach.
Totally. Because an architecture we kind of kind of uh change designs all the time and we are comfortable with that. This is what Ashan also shared that he thinks that what he learned from architecture kind of applies to programming as well because he's very free to kind of rewrite code over and over and over. And yeah, I think that's also very helpful because that's how you also learn some something in kind of when you rewrite you also change something it makes better or worse and you learn and I think learning we we learn to be more abstract over time um where it works better. I found that um as I go back to my code I introduce more abstractions to simplify how someone would read my code whereas the first time I usually write my code it's very raw dirty like lots of comments all over the place cuz I wouldn't remember what I was doing at the time.
Um then I come back and you know put break things down into custom classes and interfaces and things that help me you know code better in time. So I find that's that's part of the iterative process as well. It's like f refining our craft if anything as a as a programmer is so important um to make sure that we're always just improving on ourselves uh as well as just learning new things as well. Yeah, refactoring is definitely important. I also advise to any anybody that when they start they have to get to the end goal as soon as possible.
Doesn't matter how your code looks, doesn't matter how unoptimized it. It just like you have to go from A to B at least kind of get there just to kind of like a proof of concept and then you can start optimizing make it shiny because I also fallen into this trap where I spend days just on the first steps just to realize that I cannot reach the end because it just went too advanced because I had the bad idea from the beginning and I spend in the beginning so much time for nothing. Yeah. So yeah, it definitely helped to just kind of go dirty and quick through everything at once. One really valuable thing the CS50 course taught me was pseudo code.
Um, which is where you just basically write out your code in steps, but you don't actually write the code. You're almost just breaking your process down step by step. And and that helps you make sure that you're probably going to get to the end of your problem or figure out where there's unknown areas that you need to solve first before you go and do the really, you know, the stuff you know is going to work. Um, I found that's really helped me in especially C# where I realized I'm going to need a class or I'm going to need something that I have to build before I even bother doing this in the first place because I don't even have like the objects that I'm going to need to to enable like a form to work or something like that. I found that the pseudo code approach was really valuable.
Um, so I I use that in nearly every tool these days. Like if I'm planning out a set of tools, I'll write the whole thing as pseudo code and then sort of start filling the gaps. And the other thing that I found was really good about pseudo code is you start to recognize where you can use functions and methods in multiple places. So if you spend enough time thinking about the shape of your toolkit, you don't have to, you know, write out the same thing six times. You can start to find those common steps that you're taking in different tools that don't seem connected at first, but once you sort of lay them all out, you go, wait a second, I've done this over here and here and here, and it starts to build sort of the classes and all those methods you're going to need to to run them.
Yeah, I like to do it on paper, like a wireframe. I just write the steps and the way I do this I just rewrite over and over and over from scratch. It might be already like complete but I still rewrite it. It's this is just my thinking process because when I rewrite I come up with this kind of middle steps like I might have an issue between step one and step two. Yeah.
I like to compare it to um rock climbing um when rock climbers begin before their ascent they just stare at the mountain for the first 20 minutes and find their path before they even start. So it's like it's important to just survey what you need before you jump right in because once you're in, you're in, right? You're locked in. You're not getting out till you finish that thing. So better to know how long how long you're in there for.
Um as well, especially in a professional setting where you have to deliver code for a company with a timeline or a deadline. It's hard if you jump in blind and you know 2 minutes could become three hours, could become two weeks, could become a whole year. So it's it's a hard one. Mhm. There's a very big quote from I think it's from Abraham Lincoln that if he was given six hours to chop down a tree, he would spend the first four sharpening the ax.
Yep. Yeah. It's all about this kind of preparation, thinking ahead, and it really helps. Many people neglect it, but that they regret later on for sure. It's fantastic.
All right, so let's get back a little bit to programming. So you started with Dynamo, you started making your tools. How did you end up with Python? Like did you use Dynamo a lot before you kind of started kind of playing with Python or? Yeah.
Yeah. Um I used it quite a lot actually. Probably too long. I've always had a habit of staying too long in a something I'm comfortable with um before I sort of jump out to what I see as like the next step or the next iteration of my programming journey. And I spent about two and a half to three years just using nodes and custom packages by other people before I really said I need to go further.
um there's something missing here or I've got too much dependency. That that's actually what got me into Python. It was just having too much dependency on packages and and the trigger for it was actually my YouTube channel. So I realized eventually that doing tutorials where you use other people's packages is actually quite tricky because they change. So as a result your videos don't age too well sometimes like the node might get deprecated or it might change entirely.
And some of my videos are half half the comments are just oh I tried this and nothing happened. And then it's like, yeah, that node doesn't work that way anymore. Someone's completely changed its behavior, but people are just plugging in wires and not understanding what's going on. So, they just run it and it fails and better better make a comment. So, that sort of got me into at least trying to reduce my dependency where it wasn't necessary.
So, like if a package was like 3 years old in Dynamo, I was like, okay, I'd better get rid of this and figure out which things I actually need from it and then learn how to write this myself. Um, and eventually it got me to the point where I wanted to build my own package. Um, because there was a lot of things that weren't in any of the packages that I saw lots of utility. And I just said, I'm just going to wrap it all up. Some of the things I've built, other people have, but I built it my way or I've just built upon ideas that I've seen and said, I think that it can be a bit more robust or a bit different.
And that led to what I call crumple, my Dynamo package. And a big part of that was focused around uh bulk family editing or processing which was really relevant to my business because I was doing content uh management and editing and production Revit families in bulk. So it sort of lined up with my work at the same time. And the only package that could do that was one called Orchid um which is stored on GitHub and written in C. So all of the code was locked away and not available to me.
And I found the package a bit tricky to use. So I said, you know what, I'm just going to figure out how to do this and break this dependency away. And eventually it led other people to my package as well through the same sort of frustrations with other other dependencies. So that sort of got me into Python. Um I learned from a lot of other people's packages.
Just looking at code is often how I learn. I go, "Oh, that's how that that syntax works or you know how how do I get like an enumeration to work?" Those sort of things. Um I still go back to my own code. I still forget things and learn from myself constantly. Um, but that sort of yeah eventually led me to pyRevit I guess through just knowing that Python naturally leads to pyRevit and in the Revit API.
Uh, just to step back, so when you decided that you want to kind of break away from this dependency and create your packages, what was your Python skill? Did you already know Python? Were you absolute beginner kind of? Yeah, so I probably spent the first three months in very much a beginner space. Um, breaking things generally breaking fast like you said, failing fast.
It's the way to do it. um is the best way to learn. So I took a course from um I think it was a website called data camp at the time and they had a lot of like little mini courses on Python fundamentals and you know things like for loops just general principles. Um but I really probably spent the first two three months mostly just using Python and not really using the Revit API. And if I did have to use the Revit API it was very much through imitating other people's code that I could read and go I don't really know what's happening here but I know if I put this here and I do this here it's going to work.
So um and then eventually realized I had to actually take on the Revit API as its own its own sort of challenge um once I went into space where I found no nodes to reference. Um so I had to learn about classes, methods, properties and the API. Um I hadn't really built classes in Python myself at that point. So the whole concept of classes was still really new to me. Um, but I think the API helped me sort of learn about class structure and inheritance and other principles that I brought back to my own sort of um, Python code in building custom classes, which I know you use like quite a lot in your code in in EF tools, for example.
But um, yeah, that was sort of the Oh, it's a mixture of good and bad. There's so so many things wrong, but yeah. Oh, yeah. Totally. Yeah.
All right. So, you pretty much learn by doing. Yeah. Yeah. Always learn by doing is my take.
The way I see it's very similar to me that you had a problem and you just knew that Python can help you somehow and you just kind of brute force it pretty much. I think that's really the only way I found has ever worked for me. Um just brute forcing my way through finding little bits of tutorials and resources here and there but mostly just mcking around until something works and then suddenly I realize I wait I actually understand what this does and now that part is solved and I can move on to the next thing. And even jumping into C recently, I'm still to some degree learning that way. I'm still having to, you know, muck around a little bit, guess a few things.
We'll talk about AI later probably, but I use a little bit of that now as well. Um, but yeah, back in the Python days, there was like pretty much no AI solution. So, it was just, you know, bend it till it breaks and then figure out why it broke and put it back together and keep bending it. And it just sort of sort of kept going that way until I felt comfortable enough to build my own package and distribute code um through the package manager. and and that was also its own learning journey.
Like it's got its own rules and things you have to follow. Um but yeah, it was sort of just a a process where I just built layer upon layer as I went and sort of fell down occasionally to another layer and realized I did these two layers wrong. So I got to go back down three layers and then build up again. But it's sort of naturally just how I how I learn. Um how about yourself?
Um did you spend long in Python and Dynamo or you went straight to pyRevit or the way it was like so I started with this big project. There was like also massive massive spaghetti code and I just saw right away that RA API can be really useful because I just had like from 40 minutes to 40 seconds. So I knew like well I need it and then from that moment at first I kind of focused more on Dynamo because it was a little bit kind of I guess easier to get started with because I didn't know Python and I didn't have time to just take courses and stuff. So I started kind of using Dynamo and sometimes when I looked I had like 10 different notes and I'm like that shouldn't be that complicated. I should make it simpler.
I started kind of taking this kind of simple data manipulation algorithms and making a Python note. In the beginning, it was just math, right? You take A B C and then you do kind of simple math. A plus B divided by this just to kind of find spaces and stuff. And then over time, I started learning more and more.
Then I was like, oo, I need to do something with parameter. And then I found a video. Somebody showed me how to get parameter, how to set parameter. I'm like, okay. And it's kind of just back and forth between kind of Dynamo and Pyraits.
And I was just kind of trying as you said in the beginning automate everything. This is what helped me a lot that I would just practice practice and you know like little pieces from everywhere I would learn but I missed I neglected on basics so much just to explain it. I didn't know that for loops existed. I only knew about while loops for a while. I don't know how I missed it.
It is just absolutely the stupidest mistake programmer can make. But I literally when I needed to iterate for the list I would create a counter. I would count every iteration in my while loop and I would sort of recreate for loop with a while loop for some reason. When I found out for loops I felt so stupid for so long. The funny thing is I guess you sort of took the journey that the original programmers built because um you know you've probably seen the for loops and C um they have an internalized counter variable.
So if anything you actually probably learned the C loop method to some degree. But I just I didn't this is the only in I remember how bad I was because I was like oh I think I didn't even went through the course properly because every single course will tell you there is a for loop here's how it works and I never heard of it at this point but then yeah I started watching courses I watched I don't know I was just watching basic courses like non-stop like from this guy from that guy from like this university whatever and you know little by little I like watching over and over so I kind of find this little nuggets in between because majority of courses they're the But then there's the little things that everybody accidentally mentions or just something nice and that's where I learned a lot like list comprehensions like you watch many courses you never hear about them but then you see them they're like wow that's amazing because it's like just compresses. I found a good C# course the other day I think it was a Rhino platform and they spend about 20 minutes talking about um delegates and and events and they actually explained it really well and I had went nowhere near delegation and all these concepts before I knew of them. I knew how they worked and it was just such a golden nugget amidst all this generic stuff and I thought, "Oh man, that that's like a course in itself." So, I know what you mean. There's just those little golden nuggets that make them worth watching.
That's exactly the point cuz 80% is always the same sort of but this 20% sometimes it's so important. Definitely. Yeah. Yeah. So, you started with Dynamo, you started making your crumple package with Python and then you said that you started to hate all these dependencies and you discovered Py Ravit.
Could you just kind of take us to the moment where you first heard of Py Ravit and how eventually you got to actually start using it? Yeah. Um, so my my first encounter with pyRevit is probably like a lot of people, it's the patent tool. Everyone finds it through that that patent maker. That's it's a solid tool.
Um, and still is. I still use it for that. But um, I actually had a few people recommend to me here and there, oh, you like Dynamo, you like Python, you should go and do Pyrevet, like this is like the next thing. And I went, yeah, it probably is. And just sort of forgot about it.
And eventually I heard it enough times I'm like, "Okay, I should be going and doing this. Obviously enough people are finding this good." And a guy called um Kai Kaiu um who was in Melbourne at the time and I think he's coming back from from overseas. He he um he used at his company and said, "You've got to use this. This is like the thing to use." And I started looking into it and at that time I was joining the company I work at now, Architectus. Um and I was coming in with really just Dynamo and Python knowledge.
and Dynamo you can make it scale but it's really difficult to make it work at scale in my opinion. Um there's a lot of things you can do because of the package dependencies or uh dependencies backwards and forwards compatibility challenges like not every Dynamo is the same but Dynamo is tied to Revit. So like if you run a script in 2020, it may not work the same way in 2024 or back the other way. Like um like for example today I was I was getting a parameter that should go null if it's missing in an object and instead it gave me an empty string and I'm like and it threw off the whole logic of the script I was trying to build because I assumed it was going to work how it should work. So just little things like that.
Um and then one of my co-workers at the time she she told me do pyRevit just do it and I said okay I'm just going to do it. And um I actually looked at BF tools. That was probably the first custom toolbar um that I look at. Interesting. Because I didn't realize pyRevit's own tools were exposed.
I thought they were they were hidden um in the addin. Um eventually I realized Yeah, you can look at those too, but Oh yeah, that's so huge. Alt click and you see the code there is like what? Yeah. Yeah, the alt click.
It's such a such a tip that people all people need to know, but not everyone does. Um but yeah, look, I looked at your toolbar and um yeah, realized you can do custom extensions and run them. I hadn't quite realized it was that easy um to just structure toolbars using folders and files. It was very straightforward compared to doing it in C because I had tried to learn C and I just didn't find a course that managed to break it down well for me. Um but as soon as I saw your toolbar, it really showed me, okay, like I can do this.
This makes sense. And then I went whoa like I I have to abandon Dynamo now. I have to do everything in Python. I didn't do the whole Dynamo script with a button approach. So I just went nut if I'm doing this in a Python app in Python.
So that was pretty intimidating at first cuz you know all those geometry operations are very different in the API to Dynamo's own geometry engine. Um all possible but all quite different. Um and I guess that that sort of got me in and then I just started building one tool at a time. um started figuring out tools that belong together and stacks and pulld downs and eventually I said, you know what, I should probably just share this with all the users at the company and start releasing this as a as a toolbar to the firm I worked at and it sort of gained its own sort of little following and before I knew it, the whole company was running it. And then eventually we started putting like really big tool kits in there like um printers and room layout sheet generators and it started becoming actually depended on by quite a lot of people.
So it just sort of naturally snowballed over time and I guess I just found a new community in the private forums as well and all the interesting people that that work on the program and it sort of gave me like a second community to enjoy being a part of. So um yeah, it was a really interesting experience and I'm glad I found it. But I guess yeah, thank you for for making your toolbar I guess um available because it was a great learning result for me. Yeah, I didn't know that I created e tools before you. I thought you already also doing something in pyit.
No, no, no. I think you you were well before me. Um I think when did you start EF Tools? It would have been like what about 5 years ago? Oh man, I think in 2019.
Yeah. So about years No, six years. No, no, no, no, no, no. I started it but I released it I think in 21 man I don't remember what is it 25 probably 21. I remember it was September.
I don't remember exactly but I remember I thought like I'm going to spend a month take my best tools I made for the company and released as EF tools. It took me like seven, eight months to rewrite a lot of stuff because my first code they were like horrible and I wanted to make them somewhat decent. Yeah. I mean I rewrote them I now if I look at them I would still consider all of them horrible. I need to rewrite again.
They're great. But at the time I was like okay they're useful. I share it and let's see what happens. And it went pretty good. Yeah.
I also remember looking at your tools and going wow you take your commenting and um your your name spaces very seriously with all the ASI sort of art that you make for all the import names. pretty cool. Uh you see when I was a beginner I had this issue looking at my code. I tried to make it very kind of I like when things are very nice to look at because then it's easier to read and so on and I tried so many things. I tried like dashes equal signs making this separated this and that and then accidentally I found out that I can use asi art.
I was like oh I want to use that. I haven't seen anyone use it. I don't recommend anyone to use it. I don't many programmers probably cringe when they see this but I love it especially for tutorials. It makes it so much nicer to kind of make these blocks.
All the um all the game fact guides back in the day used to have a big asy art at the top of all the facts that they write. So it reminded me of that. Now it's sort of my like my signature when I see like newcomers start using these comments. I know definitely where they got this tip from because majority of people would never recommend anything. They just say like don't even use too many comments.
Name everything proper. You know people try to go the opposite. Just be minimalistic. Oh no no no. I don't I don't believe in self- authoring authoring code.
the self- commenting code as they call it where the comments are meant to not be there and your code's meant to be so obvious that someone can understand that it's just it's it's a nice idea but I haven't reached it yet. Yeah, I I know what you mean. Sometimes it makes sense on smaller examples on bigger ones. I just like the comment even if my function name and the description they kind of mean the same. I still like to have it just for consistency, you know.
Yeah, I was going to say I might just take a quick break. I just need to turn my air conditioner on. It's a bit it's a bit hot here as you can see. Hi, real quick. If you into Pyravit and you want to boost your skills in record time, then check learn rateapi.com platform.
You'll find free in-depth courses for any stage of your programming journey. You'll get access to pyrait basics pro and modern UI courses. Plus, you'll also get access to my code library and join my exclusive community for pyRevit developers. In the community, we can chat, discuss programming in Ravit, and most importantly, you can ask for help when you need it the most. If that sounds interesting, go to learnra ready.com to learn more.
And now back to so let's get back on track. You were saying about your pyate story and it actually remind me a lot of mine. I had very similar I also started with Dynamo was playing a little bit with Python nodes and then one of the colleague was like you should try pyate you should try parate. I was like yeah I looked at it I was like I didn't understand it like you. I was just like yeah it looks cool but probably complicated or there's there was this kind of barrier that that was non-existent but I made it myself.
And then he was like saying over and over, ah, you you will love it. You will love it. I was like, okay, I need to look into this. And then it was like so weird. I started looking at it.
I'm like, okay, I tried to prove kind of find a reason not to use it. I was like, probably it's hard to make. Then I see you make folder structure. You have your extension. I'm like, no way.
That's too simple. What the hell? Then like as you mentioned like out click, you get access to hundreds of available open source tools. I'm like what the hell is going on? Why is it like it doesn't make any sense to me.
like it's free, it's open source, there is community behind there are like tons of examples creating extension it was is still crazy to me you just make folder structure it makes it and like and since then I was like okay I need to actually dive into that and I was similar to yours I'm like okay I'm going to go full python why not it was a bit bumpy road because in the beginning there wasn't as many resources the python and pirate side was fine the problem was like ravit API and making it work because many examples in C and back and forth so yeah but once you nail the basics it actually starts to become so much fun because you start automating non-stop. Yeah, remember even just um the amount of tools that pyRevit gives you as a programmer. Um some things I was using and I didn't realize they weren't the Revit API, they were part of Py Reevit like Asan had built them. Um like some of the collectors and like the forms library, oh my gosh, the forms library so good. Like having RPW UI and his forms that he's built already was just amazing.
like cuz in Dynamo we used to have to use this package called data shapes to build um better user interfaces like staged interfaces versus Dynamo player and um that was the main reason I was hesitant to to leave Dynamo because I was like well I've got interface creation there and as soon as I found those those forms that were in there like I was like wow like this is this ships with the addin we don't have to install the dependency on top of pyRevit it's already there it was pretty powerful and the thing that really sold pyRevit to me and is still one of my favorite things about it is script.exit. Just being able to stop a script wherever you want. If if you hit a cancel point, you don't have to run the rest of the script through like Dynamo where you have to just null the whole script to the end. Um it was really cool to just have the ability to sort of gain that control flow um in tools that I guess I hadn't experienced in visual programming. So that that was like still it still is one of my favorite things in part of it.
Just that the amount of control flow that Python and written programming gives you. I think in Dynamo there was some note to stop execution like you say but I don't know there was something wrong with it but it kind of worked. I don't remember exactly. I just remember I had this need as well but I gave up on that for some reason. I think the main issue with stopping a Dynamo script would be race conditions.
Um because if you put like the terminating node on a different branch I wonder what would happen if like the other one's racing with it to to converge at like another node later. Like I wonder if that would work. So, my guess is they must intercept the idling event that Dynamo depends on or somehow um stop it, but yeah, it sounds interesting. I never came across it, but um it would definitely have been a useful tool in um in Dynamo for sure. I'm not sure how well it worked because I remember I gave up on that really quick, but I remember I found something.
It kind of became red or it was a while ago. I'm not much into Dynamo. I barely remember anything now. I'm so in pirate now. Oh, yeah.
I mean, the package manager in Dynamo is a bit of a graveyard these days. There's so many old abandoned packages. It's a bit sad. Like there's some really good package managers still around, but like for every good package, there's like a hundred bad ones stuck in the same list as like this one. Whereas like obviously switching to a GitHub style approach with CLI and saying I'll just pull the extensions that I want um was a really good change for me as well because in Dynamo it's it's so hard to find what the good quality packages are.
Whereas usually in pyRevit, the more information on the GitHub, the better the packages generally because they've put effort into it. So it's obviously a good thing. So um like there's still packages on the Dynamo package manager called test that people have uploaded like six years ago and they're still sitting there and it's like it's crazy. But Pyre was a big change in that regard too. I think the biggest issue is that the biggest kind of Dynamo users they a little bit outgrown the Dynamo.
They went to py ravit car you know they started looking for the next step because they they have like the most advanced dynamo users there's still many advanced users especially when it comes to 3D geometry and kind of this maybe a little bit gener generative design but many people kind of still started using at least on the side par so this also took a lot of kind of champions away yeah shout out to um Kum Karum Baky there have you I don't know if you met Karum Karum Baky before He he builds a synthesized tool kit and a few other tools like that. He's um he's doing crazy stuff with Dynamo geometry. He's basically built his own little mini engines of geometry inside the program. So there's still like a lot of amazing people in the Dynamo community and you know people like John Pearson that have supported and and made it such a fun program to use from a community perspective. But yeah, you're right.
it does eventually you sort of outgrow parts of the program I guess eventually and once you want more control over your application and you don't want to depend on the whole platform to run your code and eventually down the line you get into C# and you want to protect your code as well which is like another another challenge like Dynamo and Pyro to some degree um that you know that's the final frontier how can I stop another company from just taking my code and running it on their side yeah no yeah that's a selling point for C#. All right, we're going to get to C and AI later on. I think now you prepare that demo for us. You want you mentioned that you want to show us how you use P at scale. I think now is the good timing to jump into that.
Sure. Yeah. Now, now that we know how you learned Pybit, let's see what you made with it. Yeah. So, I guess for full context, this is technically the toolbar that I guess we distributed around our company.
Um, and it still sits on a majority of the computers in the company right now. um until about two weeks from now when when my C# tool automatically deletes it sadly. Um but um yeah, we ran it for the better part of a year and probably 3/4 year and 3/4 roughly two years um on pretty much all company machines. Can you show the screen? Yeah, I'll share my screen too.
I was just a bit of context. Um so you mentioned that you're going to run the C# code to delete your pirate extension. What was that? literally a tool inside my toolbar that's just going to gobble up the um extension folder um once my toolbar finds it sadly. Um but I guess this is this will distract.
Yeah. Tool leading tools. So this is the toolbar here. Um I called it pyarch. So like pyRevit for architectus.
Um and each of the tools eventually sort of became like stacks or pull downs stacked pull downs. And and I still very much subscribe to this way of arranging tools for the most part. and they also sort of joined together by function. Um, but I mean the first tool I built was uprev sheets. It's a very traditional tool that I learned to build in most programming languages.
And immediately you know that there's a a form that is given to me by pyRevit to pick a revision. Like cool, didn't even have to write it. Pick a revision, pick a sheet. And this is all built in pyRevit as well. So you've got sheet sets and filters and all sorts of good stuff.
And then I found a progress bar in pyit too. So um it definitely spoiled me like all those forms in that process were just provided by pyRevit. So I think that particular tool I'm just using PyCharm at the moment just was an IDE that I used to use. And I think this tool's got a little bit more stuff going on. But in terms of identifying like what what the tool was doing, there's a select revision form that's built into pyRevit.
If there's no revision selected, exit the script. So that's that sort of script exit thing that I really like using. Um, and then picking sheets to uprev script exit. Um, this is a fun little thing I figured out I needed to start doing in Python. Um, and in in pyRevit and I still have to do it in C.
And that's actually editable elements. So when you're building in Dynamo, you have the luxury of often running in like test models and you don't realize that, you know, most of the time your tool's not going to be able to run because it's going to have permission errors with trying to check things out. And this disc function effectively just tries to check all the elements and only keep the ones that it can. And it gives you like a little dialogue that says, you know, would you like to keep um what you can or would you like to stop the script at this point? And then we head into the progress bar, which is again a pirate pyroit feature.
Um and then I'm using like with transactions. So again just a pyit feature. This is like the context manager that I think pyit naturally abstracts for us. Um, and then yeah, formatting a message at the end. But the first version of this tool didn't look anything like this.
It was like something like 250 lines and much less efficient. Um, now it's like I think 80 84 lines including comments. Um, but that was sort of like my first tool that you know really got me into pyRevit. Um, and then there was more aggressive tools like the Nuke tool which is sort of like the eans. So that just, you know, launch Nuke, bang, and it just strips out the model.
So you're doing pretty powerful and quick stuff with um pyRevit. Like this has just stripped out all the sheets and views and whatnot. Um another really cool feature I like is um you can pro provide context to tools. That was something I learned pretty early on as well to stop tools running unless their conditions are met before you run them. So like um Oh, you mean like contextual this?
Yeah, like context. So I think if I go to like create work sets for example um it can only run in like a workshared model which is a feature that pyRevit um provides as well which in C is called avail availability. Um so I learned about you know bundle files and hooking up like wiki links to tools so that people can F1 to all the tools and it was just such a a great toolkit um that naturally sort of just lent itself to to large company setup. Um, and then I guess eventually we got to more custom complex tool kits like bulk printing. I think there's no sheets so I don't know if we'll be able to print.
I might need to go to another model with some sheets. What did you use for printing sheets? Uh, so this one actually we used to use XREV um, which is an Australian company that they're probably one of the most well-known batch printers. And then eventually I realized I can just get PDF24 as a print driver onto everyone's computer. And then I figured out if I overrided a couple of settings um in the settings to just say always print to this folder with a wild card and always print file name, I could actually get Revit to send prints through to a set folder.
Um so eventually we just built a toolkit that could could batch print and um you know you can do A1 A3 I'll just do the R rim layout sheet for example. Naming rules we built a naming rule system behind the scenes. Um, I can do of revision from a list of drawing sets, pick the sheets. And my question was more about the engine because I was wondering if I'm going to see PDF24 that open source tools mainly use for printing PDFs. Yeah.
Yeah. These days surprisingly doesn't Yeah. These these days I use the inbuilt driver for Revit where I can. Um like the for example the toolkit has evolved to give users the option of using print drivers or using the inbuilt um print print driver in Revit because they all have their challenges. But um I mean that immediately was like a selling point because we could just cut XR out of our cost um and just manage it ourselves.
Um and we could do things like building the company standard naming rule which is just like pretty much the only naming rule you have by default. Um, but with that there was like obviously complexities that came with like having to build like very strict string formatting for naming rule systems and educating people how to build their own naming rules out of like little strings and separators and you know characters that indicate a project parameter or a sheet parameter. Um since this we've we've built like more complex tools using C and forms. Um but we could have pushed this like harder um if we wanted to but as you can see it's a lot this forms that you show is it RPV flex form or that is yeah so that one I believe if I look for it cuz one thing I I learned to do in pyRevit was start to build libraries of utilities and sort of use them across multiple tools um which Dynamo sort of does in packages but not really. So um oh yeah that's a big one.
I think in this case it's probably in the export utils. So somewhere in here there's an RPW form. I think it's fair way down. Yeah, it's one of these. So like a flex form I think I was using in this case.
So um yeah, I was just building options out of there and checking if the form ran and um yeah, pretty much going from there. I was I was very flexible with return types. So like one thing I've learned since coming into C is that return types can be a bit more tricky in other languages whereas in Python they're like super flexible. So I was doing things like sending out like four booleans as a return type from a function which is like very unorthodox like usually you'd probably like make a class to hold the settings or something like that. Um but yeah these libraries of functions so that was that was pretty handy.
I think in the end of the day it's just personal preference. Oh yeah I've moved on programming now like most of my things are static classes. Um but back back in the day I like to use just just institute functions. Um, and I did like that you could like just import like a namespace from the library folder. That was really handy as well.
So I can just say like from pyRevit import and then reference the or import um everything from export utils. So if I go to the printing the printing code which I don't mind showing because it's changed a lot since the tool. Um, I liked that it let me abstract my code to make it simpler. But at the same time, I could just like I could very specifically import particular functions to save time or I could just import like a whole library. Like this one deals with reading Excel files for example.
I think this is actually my printer. My printer is down here. Reusing code helps so much. I missed it for quite a quite a while. Once I discovered it, I'm like that I need to start reusing my code.
Yeah. Yeah, definitely. printer is 66 lines of code including comments. So fairly concise, but behind the scenes obviously a lot more a lot more utility functions that are holding it all together. Like I mean my printing library is about yeah 750 lines of code including comments but um yeah it really helped me to be able to put these together and I think I was just starting to play with WPF right before I jumped into C#.
So that was me just starting with WPF and then eventually I sort of jumped over. Um, but yeah, it was really it was really fun just just being able to build such a wide variety of tools and utilities and there's more like fun ones that use like linkify like I don't know if there's any images in this link are huge. Might be. Yeah. So I was starting to use this like output or the console window as well.
So I think I'm just trying to find groups. I think I can probably find groups. There we go. So I used linkify quite a lot um just to output certain types of thing. These are all like the instances of groups in the model.
Um, for people that haven't seen it before, like I can select a detail group, but I can also go to its view, which is pretty powerful. So, I've just found that detail group. Um, but one of the fun things is that Linkify gets blocked by it security um, in some companies, and unfortunately, one of those was the one I work at. So, we couldn't actually take full advantage of Linkify. Um, but it still was a valuable report with IDs and things we can reference.
Um, but yeah, obviously if I showed you every call, we'd be here for probably a while. Um, yeah. Yeah, it's just kind of to it's nice to see that there are so many different tools, so many different problems you solved. Could you just share how do you kind of where do we start? I want to find out two things.
First one is what is your kind of coding process? Let's say you have an idea and just you don't have to code anything. It's just kind of general explain. And second question is probably the deployment. How did you share it with the team?
So, which one you want to jump into first? Um, probably coding style is a good place to begin. I mean, I can even just emulate the way that I commonly begin a piece of code. Um, I guess like anything, everything begins as a script and a folder. So, generally new folder or directory.
Um, you know, I'll usually have a name for it and it's not too big of a deal what you call it a bundle file. You know, test, you know, push button. I might think about the structure of the tool. Is it a pull down a stack? Is it going to have to sit in a certain way?
But from there, you're pretty much in pyRevit. You're in. You just have a script. py and this is where you actually create it always from scratch or you just copy existing tools. Um, a lot of copying.
Like I I would reuse a lot of utilities from like other scripts. So I usually have starter scripts that I often like to use. So this was like usually at the very least this is like the boiler plate for a lot of scripts. It would it would usually have like at least the pyRevit imports at the start. So the four pillars I depend on are Revit, DB, forms, and script.
Um they cover a majority of what I used to use. Um and then this was a little like function that like logs the um the run of the script. So I didn't really use telemetry. I preferred to run off a different approach. So this one was just actually writing files to a a server location.
It was much more straightforward. Um but it took kind of logging manually. Yeah, it was pretty dumb, but it got the job done. Um but I guess from there I'd be using pseudo code. So let's say I want to build a tool that's going to like let me select all revisions in the project and delete them.
So I'd begin by saying you know show list to user revisions. And I used to usually say okay what do we have now? We have like list of revisions and then I'd say okay um check if revs in use uh show revenues to users. So you'd like warn them okay the revisions can't just be deleted. You're going to like merge them with other revisions and you know finally delete revisions.
And this would be like my pseudo code. Um, and then I'd start going back through and actually starting to replace things. So, you know, it's actually been a while since I've written in Python. So, um, I'm trying to sort of even remember the syntax that I used to use cuz one thing I didn't have stub set up at the moment. So, I can't actually get like IntelliSense on this computer.
So, like this is where I'd literally be going to like other tools and going have to code it. It's just kind of the kind of the process more like brainstorming. What do you think about where you focus? It's more like this. I wonder if there is something that one thing I did sometimes is I'd talk to someone else about my tool and make sure that what I was building was actually useful.
Um which is something a lot of um programmers don't do at their companies as often as they should. Um to say wait if I build this thing is anyone actually going to use it? Um like usually it should be built because someone asked for it. But then you've also got to go wait am I solving like a big problem or am I solving a really small problem for one person? So it's like sort of going through that process of like sanity checking yourself is like so important as well.
Like there are some tools in this toolbar that I can say got ran like once like feasy feasibility toolkit. Three people in the company used it out of 350 Revit users. It's like it didn't make it through to C# put it that way. Um whereas like this tool got like you know thousands of runs a week just printing. Um as sad as it is room layout sheets we have a health sector um that depends on this toolkit now.
So like some of them were complete pillars of like justification for the toolkit and other ones were me sort of getting too excited and building toolkits because I could and then going wait a second like does anyone actually want to use this like so generally I recommend like building the prototype putting that in someone else's hands and saying do you reckon this is going to help you if I keep pushing it and you'll probably find that sometimes they'll just say no actually I don't need this and you'll probably save yourself a lot of time and your company a lot of money um but yeah most of these responded needs but not all of them. Um, and also the structure of your toolbar is so crucial as well because you might run out of room eventually, right? Um, so I found that it's where EF tools right now. I found real estate was so important like even the length of names of things like try to bury the length inside the pull down where it doesn't push the toolbar out. Even in G whiz like this is my little C# toolbar I'm building outside work for fun um because I can't show the actual toolbar at work which looks a lot more like this.
Um, just keeping things small, lean, navigable. Um, use pull downs and split buttons wherever you can. Um, try not to use too many button buttons. But, but that was sort of just like the I guess how I started off my tools. Um, I have a lot of trick question.
Yeah, sure. Yeah. Have you ever created tools that already exist in Ravit natively? Uh, sort of. Yeah.
So, there are some that like that they're pretty much the same thing. Like I made um super select everything of the same category or type and I think of same type already exists. Um and I I didn't realize you can select more than one thing at once and select all an entire project or visible in view. I it's only in 2023 or 2024 they added it. Um so I didn't even notice and I actually ended up building a tool that basically just does that and I was like oh okay.
Um, so I thought it was like really cool and then I just tried it out of curiosity and I was like, "Oh no, it already exists." Um, but funnily enough, sometimes people don't realize a feature exists until you build a tool that makes it more obvious. For example, like at work in my new toolbar, there's a dark mode and everyone's like, "Wa, dark mode?" Like, "I can't believe there's dark mode in Revit." And they're in Revit 2025 and I'm like, "This was in 2024. This isn't new." Um, you actually made your own dark mode. Yeah. So, this one, you can't see it in here because this is C, but um if you're in 2024 or higher, there will be a tool for dark mode there as well.
Um so, it's all it does is just toggles the UI um that Revit does normally, but because dark mode is like buried under file options, uh graphics, I think it's under colors, there's like another section they've added here. There is a button somewhere. Yeah. Users just don't know it exists. Um because often our Revit users, they're not like die hard Revit fans.
So they're not checking like the new features every day. Some people just use they have to, right? So So sometimes tools can help expose those opportunities more more natively to people as well. Um I think technically like this tool, yeah, I I'm a huge fan of dark modes, but Rav dark mode is just like yeah, it's the only software I stay with the light theme because dark is just makes it worse and reminds me on autocat for some reason. I think the main problem with dark mode, and I've told Autodesk this a few times, is every time you open a secondary menu, you get like a flashbang.
It's like dark to light, dark, terrible. It's like it's impossible to work that way. Like, cuz you just get blinded every time anything opens. Um, I mean, some tools are like really simple. Like, some are stupidly simple, like just boot up the internet, um, boot up Revit API docs, and they're not like hard tools, but like sometimes these little shortcuts just Hey, little little promo for you.
Um, but I guess even those things, they just make things that little bit more obvious to people. Like a button that takes you home to the home screen because people don't even know that Revit has a home screen in a model. Um, they just made the way that Revit behaves more obvious to to users. Um, some tools I even hijacked. Um, like I used to have a settings button that took you to the pyRevit settings and it was just a copy of pyRevit settings and you know, oh look, make pattern I've put the patent tool inside our toolkit.
Um, so I didn't write any of that. I just copied it. Um, sorry. Um, yeah, it was good fun. Um, but yeah, sometimes there are tools that like probably don't need to exist that get created occasionally by accident.
Um, but but at the same time too, sometimes the good thing about writing your own tools is you can make that them that little bit better than other ones. Like for example, purging views not on sheets. Um, so this is like a very common task that people do. Um, but the problem is that a lot of add-ins out there don't think about view dependency. So, if I delete this view, what other views will get deleted with it?
Um, and a really common problem. Oh, you mean like dependent views? Yeah. So, like if you have like a master view and three dependents, some add-ins actually give you the master as a deletion candidate, which is really bad. Or there might be a call out depending on a call out on a call out.
Um, so this tool we built actually exhausts all those relationships and says I'm going to check like and and as you can see it's not going to offer this view because it knows there's like three dependent views. Um, and that can be quite tricky to do with callout relationships but um it help it it helped us you know better understand what some tools don't do well for us as well cuz when you have those programmers in house they can look at these tools and go whoa like that's not right or this could be better. Um, so yeah it was just a a good fun opportunity that came with it. Oh quite impressive toolbar. Oh, thank you.
And how did you manage deployment and how big was how big is the team that you're working on? Sure. It sounds like a big office, right? Yeah. So, we have um about 700 people in the whole company.
Um and then we have about 350 of those are regularly jumping in Revit and probably I estimate about another 50 will, you know, open Revit on like an off day. Um so, it's quite a lot of people um spread across I think it's 12 12 studios I'm pretty sure that we were getting out to. And I'm I'm fortunate to have an IT department that is quite quite flexible and quite willing to work with us to figure out what we can do. Um, but I'm also very fortunate to work on a team of about 22 I think it's 22 of us at the moment that all specialize in digital and BIM. And some of us belong to sectors.
Some of us work together on computation and application development or web development. So I had a few people on my team that weren't necessarily building it with me but understood what I was doing which really helped in terms of deployment. Um I looked into CLI and some of those more automated approaches and realized that getting something like that to work in a large company with security barriers and um not being able to get the whole company the work off GitHub especially if it's a private GitHub because we can't share the toolbar. Um that sort of made CLI not really a feasible solution for us. um at least initially.
I'm sure there's probably ways we could have made it work, but it was a lot. Um so what I ended up doing is just saying the goal that we want to aim for here is we want to end up with this folder with my panel.extension in it in this this location on every computer uses your username at data roaming pyarch for people that know it app data percentage percentage. Um and that was our deployment location to get it locally on all computers. And then from there we have the um pyro config.in any and we were effectively pushing this out um without the clone. But in this case, we just put a wild card in here and pass the extension through.
So all we had to do was really just do like a a robo copy in principle. So we had like an installer through an application called Intune uh that would run when a computer boots up and just get the a copy of Pyarch onto the computers when we wanted it to to be there. Um, but eventually I realized that sometimes I'd be on a call with someone and there's a bug and I'd go, "Wouldn't it be great if I could just literally get a bug fixed to them like almost straight away." Um, so I ended up building this like hacky installer called update to latest. And this thing is like this thing is a total hack. Like you're going to laugh when you see how this works, but it it worked sadly.
Um, and this let me get updates to people like whenever I wanted to. So I think it's here. Um, all this thing did was download a zipped copy of my toolbar off of our SharePoint. So, obviously you can only access the SharePoint if you're in the company. So, that helps sort of secure it.
Um, and then it goes through steps. So, firstly, it downloads the zip. It I use a I think a loop to just wait um eventually to I think I I count and I use a while loop and I just basically wait until that zip has shown up in the downloads folder. Once it has, I unzip the zip and then I delete the old pierarch from the location it should be in. And then I just copy the panel.extension over the top.
And pyrovate extensions have this really cool behavior where as long as this has been loaded into Revit, um, if you delete the whole toolbar files and put them all back in the same place, it's going to still know where to find the scripts and it's not going to break. So I literally could like go and update that SharePoint.zip it um in in the middle of a call with someone and just say hit the update to latest button and I've just fixed your bug in the same call. So it was pretty pretty rapid in terms of how we could get this out. Um obviously not very secure. That was probably the main drawback to to having I guess such an open toolbar.
Um I don't know if anyone's taken my toolbar outside the company. I'm sure they've probably tried here and there. There's a few security measures built into it. They're very very subtle. Um but yeah, that was probably the main drawback.
But being able to give people updates like that quickly um was obviously a pretty amazing experience that you know pyRevit enabled us to do. Mhm. Sounds to me that py CLI could work eventually. Maybe not with the GitHub but with something like Big Bucket. I'm not exactly sure but as I understood Big Bucket is more enterprise oriented with more security features.
I might be wrong about that. Never use big Bitbucket. M but I think just the idea of the git for the code it would make updating much faster than because you would have an option to just update one file instead of the whole thing. Totally. I mean doing a comparison yeah would be faster.
Yeah I guess um I sort of looked at CLI and I sort of tried to appreciate that it wasn't really trying to be a closed solution as well. So I didn't want to use pyRevit in a way that was against the spirit of pyRevit as well. So, I didn't really want to come and bother um you know the community and say, "Hey, can you like make this enclosed way of using the toolbarss and I didn't want to make that like against the way that the community develops." So, I sort of said, "Well, I've got to solve this on my own two feet. If I want to use it for my own company purposes, I should I should figure this out myself." And that was sort of my my middle ground that I used at the time. Um I guess the thing too is I was donating to pyRevit um through um Patreon at the time and that was probably about as much as I could really do to support pyRevit.
So, I didn't want to put any extra pressure on the community to to modify the way that, you know, such a fantastic toolbar was already functioning. Um, because I know that they were going through the 2025 migration at the time, which as you know has been, you know, really big amount of work for them. Um, I think they've just just got the the final installer out, which is great. So, I think I'm actually running the latest actually. This is the latest pyit.
I've just hidden all the tools, but yeah. Yeah. There you go. Enough team. We made it compatible with 2025 half year before they released it cuz they wanted to like fix all the little things here and there before release.
I think that's what many people started kind of looking at pyit a little bit. Oh, we need to wait for the update. Yeah, that that's honestly that is one of the reasons we moved away from using pyroate at the company because I guess it just signified to us that again we we had gained a dependency. Um a brilliant tool and a brilliant toolkit and with the right amount of work and trust and and collaboration it will keep going into the future comfortably but there was like a year roughly a year of downtime I think on the installer. So, um, we actually figured out how to modify some of the pyrovit files to get it to work in 25 for us.
Um, because we didn't really use any of the actual pyRevit tools. So, we didn't have to worry about some of these tools breaking. So, we we actually just figured out there was a few variables in some of the um the loader files. That was the main issue I think they had at first and we fixed those internally. I did go on GitHub and say, "Hey, this if you do this, it it works." But there was all sorts of other problems that that change causes for the tools in pyit itself.
So that was sort of our work in the short term. We we installed the whip version and then we ran like a small script that modified some of the the internal files of pyRevit to to to keep working. So we had 2025 working about probably oh probably probably about seven eight months ago. Um but obviously pyit itself was still being developed at that time. So we appreciated that was our solution.
Yeah. All right. And eventually as you mentioned you moved away from parit to C# and where you are right now are you completely abandoning paravit? Are you going full speed on the C# where you are? Yeah good question.
So I guess um yeah we we more or less put it down for now. Um I'd pick it back up again if enough people in the company were really keen to collaborate in that language because I think Python is a really friendly language to work in. C is a little bit more um applicationorientated. there's a few more things you have to learn in order to make it work and and I think that class orientated programming is harder to begin with. So not everyone naturally finds C sort of I guess aligns with how they want to learn.
Um so that will probably be why I'd pick this up. But for now we are sort of putting this on the shelf. Um and there is effectively a whole new C# set of tools with like additions and changes and features. So, I literally had to sit down and from the ground up, I figured out how to build all the little bits and pieces that pyRevit had spoiled me with um over all those years. And some of them I built outside the company.
Like the real core of my C# tools I've actually just built outside and just called it G Whiz. And this is sort of like a a C project that's on GitHub. Um that literally just has like utilities and extension classes and all sorts of like cool functions. It has forms. So like I've built up some windforms.
So like I have I have like a list view like Pyroet has a list view. Um and I sort of just figured out over time how to build these things are still loading but it it looks very similar to Pyroit's list view if a little bit more more basic. And how long did it take to rewrite it? Because there are so many tools and files you have also the libraries. So some of it was easy.
So some tools were like very modular in how I wrote them originally. Like they were almost like a toolkit of things that work together. Um other things took longer. So I think I spent the better part of like 3 months of not quite full time but probably like half time um doing it. So about a month and a half of resourced time and that was sort of me learning so sharp at the same time as well.
Um I did some of this outside work just to lighten the load at work but also to make sure that I could actually share at least the core utilities that were like building this sort of framework cuz I knew I wanted to teach people on YouTube as well. So um luckily my contractors you know got a bit of flexibility built into it. I'm I'm sort of allowed to do what I want on my own tools as long as it doesn't, you know, obviously conflict with company interests and and and IP and values. So, in this case, I brought like some of these core utilities in house. So, I had to build like some things again, like for example um checking if the shift key is held down so that I could build my own sort of secondary fire modes like um Pyrevet does.
Um and then some of the forms I had to figure out how to build like a progress bar for example. That was really fun. Yeah, I saw your post recently on LinkedIn where you discovered something about progress bars. Um, obviously like C# lets you be a lot cleaner with how you lay out your code. So I use regions a lot.
Um, but like there were similar things in there. I use a lot of classes and custom classes and um, I might just show some of them in action. Like the up rev tool is just here as well. Bulk revision picker revision pick sheets. So, it's very similar in terms of like the general behaviors that I I've I've experimented with before, but now built just using C instead.
Um, I obviously tried to emulate some of the features in Pyet like colored tabs. So, I figured out how to do colored tabs. It was pretty fun. Um, I've got like a a command interceptor like Guardian. So, if you try to import CAD, it'll say, are you sure you want to do that?
Really not good practice. And you can say no. So, a lot of little things. So event triggers. Yeah, it was good fun.
And like I had to figure out how to do um like context again. So like at the moment these tools are all available but like before if I make a new project and it's not work shared um again I'll find it disable them if they are not matching something. Yeah. As you can see like but now I had to figure out okay how does this actually work? Because pyRevit actually abstracts this for us.
It creates a context system but in in Revit API it's actually called um availability. So I had to like learn how to build toolbars and control buttons and I really came to appreciate Py Rivet in that regard like that it it hides so much of this stuff from you. So you have to actually build like availability classes that provide um context conditions. Like if I'm in zero do I just always return true and that lets my tools run with a document closed. Um because by default it's just is it a document?
Um and then I had to build like what I call extension methods. So some people will know what they are and thanks to Sean Page for showing me how to do these. So you can extend the what class objects can do. So if you say like this in front of your first variable, it actually becomes like a method for a base class. So now the pull down button, the pull down button class has the ability to add push buttons to itself.
Um, but as you can see, I use a lot of comments and I try to keep it super clean. Um, and then eventually you actually have to build your toolbar. So I have like a section that's dedicated to just like I'll open this one for example. So like constructing the data for pulld downs to hold on to then stacking the pull downs into stacks. So it's a lot more complicated than pyRevit.
Obviously the way they do it is very simple. And then actually adding push buttons to pull downs. And you can see this is the point where I say you're available when we're in a document. So that's like context if you will. Yeah.
And then I had to figure out like how do I get tool tips? So I had to build like a tool tip resource where I actually read the tool tips from a big file instead of having to write them in in code. So there's a lot of yeah really different things I had to learn. It gave me a lot of appreciation for pyRevit and how much it does for me. Yeah, it definitely simplifies a lot.
Yeah. And what's your general opinion on this kind of debate between C and Python? Because many people have conflicting views. Somebody hates C#, somebody hate Python and everybody has their own reasons. What's your conclusion on this?
Yeah, I like both. I think that the best language is the one that works for you and the people you need the support, right? That's like that's the right answer to that question. So, if you're working at a company that only writes in Python, sorry, you're going to have to like Python, right? Like you've got to work with your team, not against them.
And and yes, there's going to be benefits to working in one over the other. I think with Python, the benefit is you can get going a lot faster. Um, but the drawback is you have to depend on a lot more being built. So you can actually run Python like usually through an interpreter or something like that. Mhm.
So like Pyrevet for example, like if you use Python, you're not really using Python. You're using pyRevit, but using Python to work with pyRevit to get the interpreter to run your code um in the API. Whereas in C, obviously there's benefits like there is a slight speed benefit here and there, but um obviously you have way more control over your code. You can compile it. You can protect it to some degree.
Um there are more complex features that I think are easier to do in C, especially when it comes to like event subscriptions. Um, I found WPF is a bit more intuitive in Visual Studio. Like for example, if I go into Visual Studio, um, so if I look at one of my forms, like you obviously have a visual editor, but then behind the scenes, C actually builds your form for you. So this is all written by the editor and you don't have to write any of it, whereas usually you'd be writing this out in Python, right? Or you'd be doing it in C# and then copying it into into Python, sort of refactoring it to suit.
Um, and then behind the scenes, it's very easy to just sort of wire up your your class and tell it how to construct itself. And again, a lot of this is just sort of very very intuitive. I found like this is an event sender. So it just it just takes the when I hit select, what does it do? Um, so I think that is powerful, but um more work.
Yeah. Can you go back to the previous file? Yeah, this one. Did you use ZAML for the layout or did you lay out it with this code? So this is all written by Visual Studio for me.
So I actually start here. So if I want to make like a new form um add new item uh Windows form. It should pop up eventually. So I want to pick a Windows form. I'll just say my Okay.
Using the Windows forms, not the VPF. Yeah. So I've used WPF at work a little bit more. Um but I found that initially it was too complex. There's there's always a broken call that happens here because I have a class name space clash somewhere in here.
I have to go behind the scenes and tell this thing it's a Windows a Windows form. Um but yeah, I generally started this way with most of my Windows forms. Um WPF obviously is a bit more a bit more complicated, but um I found that I guess Visual Studio is a very good IDE um to sort of hold relationships between objects very dynamically. So like for example, if I'm in a in a command class for example, I found the IntelliSense is very powerful. So if I go to like a command and I go to make a new I'll just work in a command.
Um I'll just start at the front of a command. So if I want to just pull in like a a class usually I use what are called like aliases. So I I say that forms is gform is my shortcut for like gwiz.forms forms and I just say you know G form and then I can say custom and then I can pick like a a form and it starts really prompting you through like I want to do a select from list I need some keys I need some values so it is a very a very nice experience I found um I did work with stubs in Python and try to get some intellisense going with the API um but it was nowhere near like what I found the guidance was like for C as well um one thing that a lot of people find really weird in C# is you declare the types before you declare before you say what the object is. Um obviously you can say var for like any type but I can also say I'm expecting a form results object or actually let's do a collector. So if I say um no the type hinting is a big one.
So if I list walls is new FilteredElementCollector doc. Um this is something I really like too system link as well. It's really cool. So I can say, okay, I want to get like all walls and to lists. So Visual Studio will say, uh, no, like that's not good enough.
Like you're not going to end up with I think in this case I probably made a mistake somewhere, but um, where have I went? Yeah, two elements probably is the one probably. I think I've made a typo somewhere or I've just put something a bit out of line, but cannot. Yeah, here we go. This is what I'm looking for.
So it's literally telling me I'm ending up with a list of elements where I actually need a list of walls. So you can sort of check yourself against your types and I think um you can like type hint in Python as well. Um but I wasn't really generally finding that was the the pattern that people followed in Python whereas I really like in C# that you can sort of force yourself to end up with like a consistent return type to know that you're you're definitely dealing with like what you want. Um so then if I just you know cast wall and you can see it knows what I want to do. It literally like the IntelliSense is pretty strong in um in here and it knows I don't even need to I just go to list now and it'll satisfy the issue.
So like things like that just little little helpers that I found guide me through the script writing process really help me um yeah just get to where I need faster. Um but I can totally understand why this is like a huge hurdle to overcome because I had to overcome it. It was a lot of work to get my head into this space and actually start going oh what's this? What's this? What's this?
And it just keeps building up. But um once you've got a few things working, you can start to sort of build on it, figure out where there's better ways of doing things. But yeah, once I sort of got my head into it, it it it got pretty easy. Um but yeah, probably like two months of frustration and then like now I'm pretty much sailing at this point, I'd say. Yeah.
So yeah, but I think I think it's not for everyone. I think C's like a very different way of writing code. It's much more about building an application than less about building a toolkit. Um, so yeah, it's not for everyone, but I guess I found it was for me once I sort of got my head around it. Yeah.
How about yourself? How do you feel about C#? Uh, I like that in the beginning you said that between C# and Python, you need to find what works for you. This is also very aligned with what Ashan said. I'm going to release the episode very soon.
It's almost edited. But yeah, he also said that everyone has their own kind of thinking and if the programming aligns with the way you think, it's great. And it's just like you said like whatever is used in the company or you know everyone has their own needs. My case I'm not really I haven't coded with C#. I can read C# really well because I' I've translated so many C# code into Python that I naturally understand all the kind of logic.
I don't know the deployment much. I don't know how to actually kind of make the installer this kind of part. But in terms of code I understand the logic. I understand all of this and that it's very object-oriented programming related. For me I'm die hard for Python.
it's going to be very hard for me to switch to anything just because I don't want to. And for the same reason, it's I saw recently a really good kind of argument for the Python. There's like Python is not always the best kind of solution to the problem, but it's often like one of the easiest and universal because if you want to build a website, probably you want to go with React, SWE, all these kind of frameworks. But if you know Python, you can use Django or you can also use vecttail and make it very quick. If you want to do something like data processing, you can use this and this and these languages, but you can also use Python.
It's not going to be always the best choice, but it's often going to be more than enough for majority of people. And I think for me that's a big point that because I focus a lot on beginners how to get people into programming. And with Python, I like it much more. It's much more readable to me. It's much easier to start.
And in my case, as I mentioned, I started without watching any Python courses. I didn't know what a for loop is. And I managed to make some code. It worked. It gave me results.
to solve the problem and I think in the end of the day that what matters to a lot of people but I see that many people many people say when they start with C# it was easier some people say when they started with Python it was easier like I think just everyone has their own way and the biggest issue I see when people start going there like and ask when they ask hardcore like Python user like myself is C# or Python better please I'm being honest and I say well first of all if you ask Python user probably going to hear that Python is better and if they're going go to a hardcore C# user and like is Python or C# better? They're going to find all the reasons to why C# is better. It's not always the case. Many people very transparent and say like look if you're new you never cod it probably start with Python and then kind of build on top of that because object-oriented programming is definitely a big big roadblock in the beginning. I don't know how was your journey but when I was with kind of learning Python I understood like okay here are the if statements there are the for loops there are functions.
Eventually I got to object-oriented programming and I understood how to write classes but for me big thing I never understood why would I want it I have functions I can do it with functional programming and it didn't click for a long time I already kind of okay I don't need classes gave up on that a few weeks went by I didn't try to kind of do anything with them and I I don't know this was one of these moments where I just like something clicked in my brain and I was like ah I think I understand why I need object-oriented programming and it started making more sense out of nowhere I wasn't coding. I was just kind of going about my day. So, I think it's the way of thinking that we need to adapt a little bit and some people can get it right away based on their previous experiences. Maybe as you said with Warcraft, it already kind of gave you kind of planted the seed for the programming, but maybe you didn't realize it. But for some people it takes a while to understand certain concepts.
This is why also when people say how long does it take to learn programming? I'm like I don't know. Some people start in second day, some people take month. It's Yeah. very depends on how fast something clicks for you because you have to make your own like connect dot certain way.
Yeah. Another follow-up question I guess that people I always give people is what do you want to do with it? Like you know what what are you trying to do because that will very much influence the answer of your question as well. Like if you're doing data science, you might not need C#. You might just because you might use this mapplot lib and pandas and you're sailing like it's already built for you.
Um whereas if you're you know building you you don't want someone to be able to open your code up. It's meant to be protected. Yes, probably you're likely going to be in C# at that point. So, it just comes down to those factors. And I found object-oriented programming took a while for me to get.
I have a really good example that I show people sometimes of like where, you know, object-oriented programming really helped me, especially in my own toolbar. I'll just share my screen again. So, like all my forms that I build, for example, and this is a little bit different to the forms in pyRevit. Um, they all actually end up outputting the same object, um, which is a form result. So I ended up building a custom class that has objects or an object.
And this is how I can handle like sending multiple objects or single objects in a multi select scenario. Um was the form canceled? Is the result valid? And was the result of the form affirmative? Yes or okay.
Um and that's like my return type of every single form that I I build. So I still do a lot of like functionbased programming, but I found like C with a return type. Um I'll just find an example of a return type of a form result. There it is. Um helped me sort of better understand.
Okay, like sometimes classes really help you abstract something into like a really simple scenario. So like for example, when I run my revision script, um if I open up the operative tool, when I'm actually getting revisions, I'm getting a form result, I'm checking was the form result canled because I send out a form result and then if it wasn't, then I get the object as a revision. Um and then for the sheets, I can ask for the objects instead of the object. So, it's a really flexible like sort of custom thing that helped me make my forms really intuitive at the surface level. Um, and and I always find it's a good example of, you know, where object-oriented programing programming makes sense because you can really abstract things to a more logical way of working.
Um, and a lot of things I do now are very much still very inspired by Pyrevet. Like this is very much how a progress bar in Pyrevet looks. You kick off a progress bar, you kick off a transaction, you you check if the progress bar has been cancelled, and then you increment the progress bar. Like pyrovate's almost the same in principle. So like I still take so much inspiration from like the way that Pyrevet sort of educated me to manage certain classes and objects and yeah, definitely I definitely um don't feel like I've abandoned.
I'm still very much spiritually in pyRevit when I work um but just using using programming in a slightly different way now. So yeah, just thought I'd share that. Hey, UI design is very good example for object-oriented programming because this is where classes actually they make so much sense there because in the beginning when you learn about classes then you try to apply classes to everything you do and it doesn't really work. This is why it doesn't click because you're just trying to take the same code make it you can do it that also going to work but in the beginning you just see it a bit pointless because it worked before why change it. Yeah, but with UI forms, especially when you go in VPF, it makes so much sense because you kind of have already separate like UI XAML format, then you have your Python format and everything is also a class.
Your form is just one big class of form and then you can modify it. It starts to make sense more but in the beginning it's just hard to come up to this example that you actually need because you always see this kind of tables about employees. You have a class of employee then you like you know the dogs, animals, all this and you're like cool I get the concept. Why do I need it? Definitely.
Yeah. I mean, that's what I encourage people when they ask me what what should I do to learn to program and I say find a problem that matters to you. Um, so cuz yeah, like you said, the employee table like I don't I don't run a company. I don't need an employee table. I don't have a ben examples that everyone uses like a class of person like all this.
I mean it's good abstract enough but eventually you start asking questions. Why do I need it? Yeah, exactly. But I mean at the end of the day programming should be a personal journey for anyone. I always find there's sort of like two types of programmers I run into on average that are learning.
There's the one that's doing it because everyone else is doing it. It's just what they have to do, which is generally like the wrong reason, but eventually you might find your way to programming for you. And then there's the ones that just they literally are just so sick of their job or doing things in a dumb way and they're like, I can do this better. And programming is like my escape from, you know, the mundane sort of of my career. They're the most common types of people I run into.
And I always encourage everyone to be more like the second person because you have like a really strong motivator to keep going and and to to escape from a problem that you can solve using programming. Yeah. Yeah. You need a little motiv motivation in the beginning. Totally.
Because there's like you know this learning dip beginning whatever skill you take in the beginning it's fun and cool. Then you hit your first big roadblock and this is where many people quit. But if you keep going this is where the things get fun once you go past this kind of learning dip. And I think on this note, it's also a good place to ask. I like to ask all my guests, what is the number one advice you would give to beginners like to programming in general?
Probably brave users since that's where we are. I think the number one thing for me is keep going. Um that that's advice I need to tell myself all the time because it is easy to get frustrated and it's very easy to get stuck in corners and not quite know where to go next or not know why something's not working. You just you've just got to keep going. Um make sure obviously you're being smart about how you keep going.
like contact people that might know answers, engage with forums, um try to find resources that might work for you. But um it's hard programming like it's not a it's not an easy thing, I think. Like it is an extra skill set on top of being an architect, an engineer, uh a designer, a business manager. It's it's an extra thing and it's not the core business service of architecture especially. That's a really important thing to remember.
like your code is only useful if it makes the business money at the end of the day like by making it more efficient or by adding to the service they can offer. Um so like it'll be frustrating because you'll have to sell why you're doing it to people sometimes that will be frustrating too but you just got to keep going. You've got to be patient with people, patient with yourself. Um and just it's all a journey. Like there's going to be struggles.
There's going to be good times. Um there's going to be really confusing times. There's going to be scary times when like AI comes along and tells you that no one's everyone's going to be a coder. I'm still waiting for it, but um you know like there's going to be a lot of emotional experience. They need to sell the hype.
Yeah. Yeah. Exactly. I think we're almost in the trough. Um but but I guess that that's my main advice.
Keep pushing. Um and if you get stuck, come to people like us. We're generally quite accessible people. Like um I think we're always happy to give even just quick tips if we're busy. Um I try to be super accessible.
Um I won't always be that accessible. like I'll probably have kids and stuff one day and it'll be harder, but my my hope is that other people get inspired and continue to support the industry and and I'll I'll try to keep developing resources as long as I can for the industry as well. But yeah, keep pushing. How about yourself? What's your your main sort of tip?
I think there are a few things. One of them is sort of you need the basics because without basics it's not fun. Yeah. You just like in the beginning people like ah why do I need Python? It's easy.
I'm just going to jump straight to Revit API. And then what I see people struggle with is they have Python questions when they deal with Revit API and they don't know either of them and now they're trying to juggle two things and it's very distracting and it also gives you this false feeling that everything is super hard but this is just beginning like once you have the basics like absolute like just the computational kind of logic how to create logical flow how to like you know if statements then once you go to Revit API you already have one problem less you don't think about logic as much you just think about how do I communicate this logic with ravit which is completely two different things right one is logic other is like I don't know how how do you work with specific things yeah so I think my main one is more into like this kind of focus on the basics don't skip on them because I skipped and firsthand I can tell you that you're going to struggle with so many stupid things that you would just in beginning would spend a little bit prepare yourself it's like the quote I mentioned about the axe just sharpen the axe before you're going to cut the tree and it's going to all work yeah I always sort of um use an analogy for that one because I agree fundamentals. Like if you're not bored for a bit, you've probably skipped something. It's usually what I like to say that there there are some necessary things you have to go through. So when I when I first played um Pokémon on the Game Boy, um I didn't actually read the instruction manual and I didn't realize you can catch Pokemon.
I thought the only Pokemon you get is the first one they give you and you've got to beat the whole game one Pokemon. And I beat the game. Haven't you watched anything? I beat the whole game with one beefy Charizard and then I realized, oh, you can catch these things. So like read the manual is another thing too, right?
read the docs. Like check out what what you're getting into before you start coding. Like have a look at the the primers, the wikis. How did you miss it? Yeah.
So yeah, just read the manual as well. Haven't you watched the cartoon where all they do is throw Pokeballs all the time? No. No. I didn't watch the cartoon and I just I just I guess like Ash is the same.
He only uses Pikachu, right? So he catches all these Pokemon and he only ever uses Pikachu. Um so I sort of did the Ash journey because this was my first question. How do I throw a Pokeball when I played in this game? Yeah.
the the old man in um Vidian City tried to show me and I just completely missed it and I kept going. So, but read the manual is the other tip I have. I see. Now, uh how are you on time? Do we have a little bit time?
Yeah, if there's more you want to talk about. Yeah. Yeah. Perfect. I just want to ask you about Well, AI is a big topic.
Somehow I missed this topic in the previous podcast because I I packed so many questions I had to skip a lot but now I'm smarter. Uh just in general, how do you use AI in programming? Do you use a lot? Do you rely a lot? And yeah, so um C was probably taught to me a lot through GPT.
Um I had a lot of conversations with the GPT um to really start understanding how this all works. I I learned you can feed code into AI and get answers back with context about the code. So that helped me. Sometimes I'd see something and go, "What does this mean? Please break it down for me.
I've got no idea what this piece of code is doing." Um, or I'd send code back at the GPT and say, "Is that the best you can do? Is there something more efficient than this?" Because occasionally it writes very verbose code, like very complex code that doesn't actually need to be that complicated. Like for example, the shift key, checking when the shift key is held down. ChatGPT taught me how to do it using internal pointers in C which aren't exposed to you naturally that you have to draw upon a DL to access. And it turns out you can just go keyboard key pressed shift.
Yeah, it's not always the sharpest tool in the box. So, like it showed me how to do it in a very memory efficient way, but it didn't show me the best way. So, I threw the code back at it and eventually it was like, "Oh, whoops. Yeah, there's actually like a really simple way to do this." Um, but I found that that was really beneficial for me, but only because I knew what I wanted to get out of the exchange. I wasn't coming in blind.
I had a really set goal in my mind. I had a good understanding of the fundamentals already. I'd used Python. I knew about object-oriented programming. So I could have a con conversation with it.
Um, if I came at it as a Dynamo user, it probably wouldn't have worked because I would be talking a very different language to like what I was trying to get out of the the conversation. It would be like talking to someone in a different language and you only know like two or three words and they go, "Oh yeah, I know that word, but I don't know what the rest is, so I'm just going to make the rest up." And that's probably like the worst thing about AI is that it makes stuff up. It doesn't say, "My confidence is at 2%." So take it as you will. It just says here's the answer. And I wish it would change.
I wish they would put confidence ratings on things and say this is actually how this thing is in the answer it gave you because that's like the worst part of AI for me. That's actually a good idea, the confidence marker. Cuz with AI, what I noticed is that your kind of the output is going to be as good as your input. Yeah. Because you need to kind of direct it when you don't know anything.
It's still good. It's going to help you a lot. But what happens later on is that it's not replacing people completely with programming. It just makes good programmers much better programmers because they know how to ask questions. They also know how to guide it and they also they not just say like hey I have a tool I want to delete all revisions and that's it.
Now if you're going to describe okay I have this tool I want to do it this way step one step two step three step four. If you see something else just let me know. Blah blah blah. It's already so much better output. Yeah.
Yeah. And for the prompting, I have I've noticed one prompt that works really miracles for explaining code because you mentioned that you kind of gave the code and I also wrote on it. I just going to say that what I like to do is like I I dropped like the regular like I want you to act as seasoned Python developer and so on. But then I ask you to make a tutorial out of it. Then it thinks completely different.
Not like for the video or something just for me like explain it to me. And I I say like I will provide a piece of existing like pyroate code and I need you to provide short clear code override outlining all steps then write step-by-step tutorial tailored for beginner pyrovate user explaining each section of the code in simple terms and also for beginners I like to throw in like describe all Revit API concepts necessary for this example. This one I literally noticed big difference in the reply because once you say like make it a tutorial it just like okay tutorial beginner it just starts explaining each step and in the end it also says like oh you need to know FilteredElementCollector which does this you also need to know transaction which does this this one is actually you know I'm not so much into prompt engineering I barely like I want to take some courses to get better at it I just don't have time for this but this one I just kind of I don't know how I just end up coming up with this I was just trying like this this this and then I'm like oh that's actually a good Does it put the ad for Raid Shadow Legends at the start as well for the mobile? Does it put the ad for the mobile game at the start of the video as well? Because it's like doing the tutorial, guys.
Anyway, I'm going to tell you about our sponsor today. It's good fun. I think I think that's right. And I mean, one thing that does worry me about the culture of AI is I'm not sure if anyone feels motivated to learn like they used to anymore because they feel like it's got it covered for them. And I do worry that we're sort of disabling the next generation of people that become middle managers and upper managers.
And we're already seeing a real lack of middle management opportunities coming out of the younger generation because they haven't really been given those opportunities. And AI does become this like concept where it's like, you know, we don't need juniors anymore. And where do where do you where do your middle ground developers come from? Where do your senior developers come from? They're all going to retire one day.
Like it's like, are we cutting out the knees of the industry if we're not careful? That's the thing that concerns me. I know Meta's, you know, saying we're going to have like just everything's going to be done in AI. It's like, oh yeah, they're still doing their metaverse, which nobody wants and ever use. I don't know.
I don't know anyone who uses it. I tried it. No, thank you. Yeah. And I also subscribe to the idea of like dead internet theory where eventually it's just robots talking to robots, right?
And it's like at some point we're just going to ruin man-made environments. Like the internet will just get ruined beyond the point of use. And it's like is it even worth it? Like so there's and I feel like that the moral and the ethic fabric of AI is being sort of conveniently ignored to some degree as well, right? Like there's a lot of companies that are skipping some very due diligent based steps here where it's like, you know, I think you forgot a few social barriers.
So I'm just I'm a little bit on the fence with those sides of AI, but I see the promise. I've experienced the promise. Um I think it's going to take a long time before we see, you know, like the whole architectural process replaced. I don't think that's ever quite going to happen, but we might see it redefined in the next like 10, 15 years. There is a good joke about this one.
There was like all right guys, AI is going to replace us. All clients have to do, they have to give us the clear instructions what they want. And then the second one like, okay, actually we're safe. They never do that. One of my new quotes I like to say as well is um AI won't replace your job, but someone saying that someone who knows AI replacing your job will definitely not replace your job because we got this new generation of people saying AI is the best.
It's going to do all this stuff. I'm like you're not a threat because you just talk about it. You're going to do it. So yeah. No, definitely.
Yeah. AI is just kind of tool. This is what people mainly kind of all this hype made that AI is like our replacement. It's just a tool like anything else. Back in time, like if you go like 50 years ago and show them Revit, they're also going to like freak out.
They're like, "Oh my god, they're going to take over our jobs." No, it just creates new jobs. You just don't understand it. Just made more work cuz back in time, there were like jobs that you would find hilarious. There was a person who would just wake up in the morning and go and light candles in all the light posts. This was an actual job.
Then would when electricity comes and all these guys think like, "Oh, they take our jobs. It's no, it's just going to be a new job. Now you're going to service the light bulbs once in a while or something. Yeah, they became the light bulb repair shop instead. Yeah.
Um but I guess the other thing too I see is like I mean I see the excitement about AI is a reflection of how frustrated everyone is with the state of technology in our industry. Um in that people are getting quite sick of Revit being like one of the only viable solutions for delivering the way that we deliver an architecture right now. If you want to use a different platform, you have to sort of change how you work. I think like if you want to use Blender Boom, like it's it's a whole different process to using Revit, there's going to be challenges and differences and you've got to learn how git works at the company level. So I think that's part of it.
Like people are just so tired of the same thing and they're like, "Oh, this thing promises to take it all away, right?" So that's sort of why the hype train is is so is going so fast at the moment because I think people are really hoping this is going to be like the next big thing. And I mean, I don't know if it's going to be in our industry. It's definitely going to be in some industries, but like I don't know if it's going to Oh, yeah. There's certain industries already at risk like call centers. Oh, they're screwed.
That's for sure. Because AI is definitely better at that one. But something like re I don't know. AC is so slow to changes. This is why Ravit is so dominant.
Like there are there are tools that arguably better than Ravit, but it's so hard to find people who know the tool. It's so hard in case you have this kind of tricky questions. There are no forums like which go 10 years back who had this issue. And this is why Ravit is so dominant. It's like the community, the forums and just the presence just that all the companies AC they're so slow to react changing from Ravit to anything else.
Oh my god, people still part of it is ego as well. I mean there's a lot of BIM managers out there who have invested very heavily in Revit. But not only that, they've convinced their their companies to invest heavily in Revit. off you if you pull the carpet out from under their feet and pull them off somewhere else, they're going to go, "Wait, why did we spend the last 25 years building all these families?" So there's this there's this like sort of pain point where it's like how easy is it to just pull away from this thing that has become like the lifeblood of your company's delivery model. So I think that's a real a really interesting point the industry is going to find itself stuck in.
Um and the only way out is going to be through it. Um a very difficult solution to just pick up a whole new platform. I think it depends on the way the company works. Like for example, test fit. If a company just does residential buildings, like my god, get on test fit.
Like because that thing will just completely change the first 40% of your delivery process into like a day. Um but don't tell the client, right? You charge this product service. So like um and that's where the service orientated business model is going to be the transformative component here. If we keep delivering on hourly rates as an industry, like we're encouraged to do more, to charge more.
But if we make our server our product a product out of our service instead and we we sort of no longer just make it how many hours are we spending on this, at least on the surface behind the scenes, we still resource, we still do that. That might give us the opportunity to change the delivery process, which will let different platforms shine. Um, so that's where I hope to see our industry move. And maybe AI might help with some of those pain points by making the administration side of the industry a bit more fluid. Um, a bit easier to interact with and not so rigid and sterile.
So maybe that might might be a change multip force multiplier for change if we see it go. But yeah, that it does feel like it's still a very long way away. Like it feels like it's out of reach still. It's like we can reach for it, but I still can't surprisingly can't grasp it. Yeah.
And in the meantime, we can keep building cool tools, I guess. Oh yeah, definitely. Now I have huge hopes in Blender Beam but I understand that the company is going to be so resistant to change but I think the heavy price tag of Ravit sooner or later going to finally like the blender beam going to catch up because Ravit is like three three and a half thousand like a year for user and once you have like I don't know team of 20 that's already substantial amount you're like okay maybe I spend the same money in training in the problem is like it's just not widely accepted yet there not as many use cases it's crazy what people some people do in blend with even Blender Beam. It's a bit of both. I mean, I guess like if you look at Blender, that's obviously a really unique example because the platform in itself is free.
A lot of the other like competing platforms in the market like you Hey, very cute. Um you like test and these sort of platforms, they're not cheap. Like they still charge a pretty hefty subscription. Um so like it's not like 10% of Revit, it's maybe like half of Revit if you're lucky for those new platforms. So you can only really replace Revit with like two platforms when it comes to cost I think in a in a business.
And no platform does even half of what Revit does for most companies at the moment. They pick up very small parts of the design process. Like most of them are feasibility applications. And I'm like not another feasibility app. It's like there's so many of them.
Uh, and I think like until something can take on the delivery side of Revit or like um producing drawings, printing drawings, the you know that really basic stuff, vector graphics, um that's that's what it's going to take to break free of Revit because for now our governments are still demanding that we give them drawings in PDF produced to graphical drafting standards and Blender BIM does seem to be exploring that space. how can you generate a drawing from the model? Um, it's got a long way to go, but like it's amazing how far they've come. I know Dion um relatively well. He's in Australia as well, Dion Malt, who manages the the Bonsai project um working for Len Lease, and he's a really interesting person with a lot of passion um both in a in a positive for the industry and a negative against Revit sort of sort of sense.
So, um so it'll be interesting to see where it goes. Yeah, definitely. thing like in marketing they say you cannot be like 10% better to replace something you have to be nearly 200% better to just like because people like yeah it's better but why change yeah I think there are some platforms where like they're challenging the delivery model um one one that I've got my eye on and I've been having a play with is called Arhole and um they're sort of like occupying a similar space to what like apps like former and other apps occupy where you're doing your blocking your stacking your areas your yields But um they they've taken it from a very interesting direction. They're looking at it more as a a craft in developing your application. So the user experience is like so fluid, so friendly.
Um you've got sheets with views on there that change dynamically and you've got labels sort of like parameters for families on sheets that respond to changes in the model and it's much more fluid and sort of feels like using mirrorboard mixed with Rhino. Um, so I think some of those applications are going to like actually hopefully tilt some firms or maybe some firms might find they only want to do part of the design process and then hand it off to another firm or an outsourcer. Like you might just do the design stage and that that's it. You're done. Hand it off in design development to a firm that still uses Revit.
So some firms might find different niches that they can specialize in versus doing everything and anything. And I think they'll find they can probably reduce their employee count as well if they do that. Like if firms just do the design stage, they might be able to cut 90% of their workforce out and still deliver like you know maybe 50% of the work. So that that's where maybe the future might change for some folks. Yeah.
You mentioned the acral there's also this trend going a little bit more web browser cloud-based uh applications. What I like about acro it's following the trend. There's like do you know Figma? Yeah. Yeah.
So they're very much inspired. just like interface. Once I saw that, I'm like, "Oh, that's that's probably going to be a huge if they put enough effort because this kind of trend for the Figma, I use framer, which is pretty much Figma for building websites really quick." This is like if you're a designer, but you don't want to mess with the code, that's perfect. And like the acral I like when companies move in this direction of the trends because they clearly work. It's just the AC is a little bit slow to the changes and they might not appreciate it.
But I know like similar apps from other industries. So I appreciate this part. I haven't tried it. I think one of their main investors in the startup mode was actually the CEO of Figma. So they definitely are very closely aligned with that mentality.
And you can feel it when you use the app. It just feels like everything's been designed very intentionally and very cleanly. Like it's everything's out of the way until you need it. It's not just like the interfaces where there's like 50 buttons and you just got to find the one you need. It's it's a very different approach.
I think web based is obviously fantastic when it comes to deployment as well like you know just open up a web browser you're in you're installed like straight away that's obviously like a huge benefit as well. Yeah it's also updating is no issue it's just done in background you close you come next day new version done. Yeah I mean I guess we've got so used to the idea of no backwards compatibility with Revit that we've sort of forgotten what modern application development looks like. Um, you know, like it's just so strange to be in that scenario. Like when you go to Rhino and Rhino 6 can open a Rhino 8 file, it's like what?
Like cool. Okay, wow. Because they've like planned ahead and they've figured out their delta process for like new features and they've figured out how to flag the new features in their in their format that they write. Um, like Unreal, when you use Unreal Editor, it's like it's a whole different program experience. Like the interface is so much cleaner.
So yeah, I think hopefully people will just try these apps out and maybe get either frustrated enough to make Revit change or make the change I guess if they don't if they find a way out. Yeah, I think the issue is the legacy code because I heard we had an issue with the rooms and one of the colleagues reach out to Autodesk team talk back and forth a lot and eventually we get an answer that the algorithm that controls how rooms are taken. it was written in the 90s and they are a little bit either they afraid to touch or they just don't want to because it takes a lot of effort to rewrite it from scratch and therefore there is certain bugs. Yeah, we found a workaround that usually like draw lines this and that move things. But it was funny to hear that they also kind of admit that there is legacy code that they not willing to touch at the moment because there is just well they don't have resources or not.
Oh, fair enough too. I mean it's a huge product. So, I mean, I look at my code base for my addin and I can't imagine what it must be like to work on like a Revit in source. Like, that would be insane. So, like I my my heart goes out to the developers that are like having to maintain this beast and also add new features into the API and rewrite parts of a very old program.
Um, I have major respect for the development team at Autodesk. And I think like even they're in a point where Autodesk is like, "Wow, we've got a lot of tech debt here. we just got to manage what we can. Um so like whilst not I don't agree with everything Autodesk and the team's done in the past, I I admire um that they've managed to keep this thing running in a modern developer ecosystem the way they have and you know making the jump to net core in 2025. That that would have been an insane amount of work behind the scenes for them.
Um dark mode even if it's not perfect. I mean, that would have been so much work to just go back to all those forms and find all the variables they need to suddenly insert and control and the bindings they would have had to make. I don't know how they how they do it with the amount of people they have, but um yeah, mad respect to them. Um but yeah, I wouldn't want to change the stair tool or the railing tool. My gosh, imagine that.
Yeah. See, all right, I think we can wrap it up. It's already past the twohour mark. Can you just share what you're up to where people can reach out to you just kind of Yeah. Yeah.
So I guess um I mean in my 9 to5 I'm I'm working um so if I don't always get back to people during that time that's probably why. Um but these days I I've just come back to YouTube on my my channel the Aussie BIM Guru. So I'm actually teaching C at the moment. Um I think we're up to lesson two out of probably like 300 at the moment. Um but I'm starting with the absolute fundamentals.
So like like on Monday I I taught people about variables, very basic stuff. and we're just going to build up step by step until we're finally developing a Revit addin. And I'm more or less going to share how to build roughly the toolbar that I've already shared on GitHub. So, if you want like to get ahead of me, like just look at my toolbar on GitHub and see if you can figure it out. But, um, my goal is to get people pretty much to the point that I'm at because I feel like it's a skill set that people deserve to have available to them.
Um, especially given it's C# programming's been around for a long time. It's just been hard to access. Um, so I'm trying to create a series that I guess, you know, even the, you know, probably the Python beginners could could probably pick up and have a look at and figure out if it's for them. Um, but at the same time, I guess I'm probably hopefully going to get back to like Python and pyRevit eventually. I do have like another toolbar that I was playing with for a while that I wanted to sort of expand a little bit.
So, I think it's still like a really valuable. Yeah. So, I was just um just playing around with that, but I I stopped after I got about probably like 12 tools in there. Um, but I think I might might be able to get a few more in there and clean it up a little bit. Um, and I guess like personally I'm I'm actually just trying to teach myself uh more about WPF and model view view model at the moment.
So creating modless forms to to run whilst Revit's running as well. And I've just built my first MVVM form the other day. So that was pretty pretty cool. So that'll be like probably the next few weeks for me. How do you find MVVM concept?
Uh I think it's I mean like MVVM against like behind code. Yeah. I like what compared to like MVC or like other types of approaches. Um I mean I find it's a a fairly intuitive concept once you understand how they work together. Um it took me a while to figure out like okay like what points to what and what controls what.
Um bindings obviously were like the key to make it work. So getting my head around bindings and converting um converting objects that was probably like the hard part. Um, but I think it more or less makes sense to me now. Um, obviously building really complex forms is like always going to take time. So that's what I'm finding the challenges.
If I want to create a really flexible form, it's it's a lot of code um to get it to work. But um, but I guess once it does work, it's like super rewarding. Um, but I guess from there, like I'll I'll probably just at work be trying to focus on just scaling up my both my toolbar, but trying to find ways to empower, I guess, the people I work with in other platforms like Rhino and trying to introduce other programs to the company like Arcohol to see if there's like opportunities um to try out different platforms and approaches. Um, so that's sort of like my my road map in the in the short term. And I guess if people want to reach out to me, probably the easiest ways is obviously in the comments of my YouTube videos if you have questions.
Um, you can contact me on LinkedIn through direct message or just respond to a comment if you like what I say or don't like what I say. I'm always happy to have a debate. Um, I I actually spend a lot of my time on LinkedIn debating people because I find it's fun to see how people think and react and um, I think it's good for people to defend their opinions. So, I like to sometimes put people on the spot and say, "Yeah, okay. I don't agree.
Um, let's talk about it." So, if I ever do argue with anyone here in the comments, don't worry. I don't hate you. I just I just I'm interested in what you're talking about and I want to talk more about it. Um and probably the last way you can contact me is aussiebimgurmail.com. So that's my just my standard email in my um in my my YouTube closing screen.
So yeah, don't be a stranger and if you're struggling with something, just reach out. I'm happy to give you tips. Yeah. Mhm. Perfect.
Well, thank you for coming on the show. This was really exciting. I definitely wanted to invite you one of the first guests, but you invited yourself before I had an opportunity. I love that I'm an introvert so this helped me a lot. Yeah.
No, it's a real privilege to be on there and I really respect what you're doing in building an API community um and giving a I guess a secondary community for pyRevit users as well. I think it's a really exciting way to bring the two learning spaces together and I highly recommend anyone watching who's not checking out Erik's platform to go and have a look. Um it gets my endorsement. It's a very clean, well setup platform. Um, your videos are very to the point.
Like my videos, I don't get to the point. I talk for a long time, and it takes me a long time to explain my concepts, but I mean, Erik, you put a lot of work into your editing and your graphics, and I really admire the the the effort you put in, and it shows. So, yeah, check it out. Thank you. I think the biggest difference is because you're a native speaker.
When I watch your videos, I'm so jealous because you can just turn on the camera and talk for hours. Yeah. I still have this a bit camera shy or something. Oh, that's okay. And I need to plan more.
And usually when I watch my videos, I just cannot post it. I just cringe a little. I need to add a little bit of editing. And so now it gets better. In the beginning, it was like I would spend sometimes 20 hours editing a video to get 200 views.
It was just insane. Like now I look I think I should have just like posted videos like and ignore how bad it was. I would learn faster. But it's all part of the journey. I think I mean honestly your English is perfect.
Um I think you've come a long way. like I remember when you first jumped on YouTube and I'm like, "Oh, he's getting the hang of it." And now you're you're a pro, mate. You're a pro. Thank you. Oh, I've made a full-time job out of it.
You've done so well. So, um yeah, be be proud of yourself. Yeah. Yeah. Thank you.
I appreciate this. Yeah. All right, guys. Thank you for watching and have a good day, I guess. Bye-bye.
Bye, everyone.
### The Programming Journey of pyRevit Dad (Ehsan Iran-Nejad) | pyRevit Podcast #3
https://learnrevitapi.com/podcast/py-pod-03-ehsan-iran-nejad/
Ehsan Iran-Nejad, the creator of pyRevit, on his programming journey from architecture to software and ten years of building pyRevit. pyRevit Podcast #3.
## Transcript
oh my God I had no idea that thing existed and that's how you're supposed to ride your program why is that button 16 pixels to the left don't worry about me and software I'll pick it up I can see how Engineers work and I can see how us architect SL designers work and what I've realized is that all programming languages have a holy smokes I this is not something that I ever thought about and it's the art of programming really designing the right data structure that represents your state I'm like oh wow I didn't really need to change anything that's this is interest I've never been here before which is amazing like that's what I love about software all right guys today I have a very exciting episode and we have a p dad himself on the show his name is Essen EET and welcome to the show how are you thank you thanks for inviting me pretty good so you've created pit around like 10 years ago right yeah yeah this year was the 10th well 2024 was the 10th year anniversary of P Revit such a long time yeah I wish we had like had enough money to throw a big event and invite everybody there and stuff but a that would be cool I think nobody really knew that it's like 10th year anniversary I didn't know it existed for this long until I heard it in one of the podcasts I was like wow no way yeah it was it was a personal project for many years like 20 2014 was the year that I started it but it didn't really didn't really catch any sort of like momentum until end of 2015 maybe or like 2016 no but even still it's so many years since then this is amazing listen I'm really excited to talk about by RIT but first of all I really want to focus on your programming journey and see where you actually got started so I thought that we maybe go back to the moment where you just typed your first hello world statement can you just take us there tell where you are how old are you so I think I was about 11 years old 10 11 years old all right uh we used to live in southeast of Iran and I remember that when I got 12 we moved to Northeast to a much much bigger city but in that smaller City in southeast of Iran at the school that I was at they decided that they want to create a computer class um so they bought this old ass um olivetti uh computers from somewhere else I think it was like a university or something like that that they didn't need them they wanted to upgrade they bought all these machines and it was like I want to say like five six of them and that was the first time I actually sat in front of a computer and uh I'd seen him before here and there like inside Banks and stuff like that but that was the first time I sat in front of him I was like first of all oh my God this is cool um because my dad was a telecommunication engineer and since I was a kid like I was around electronics and you know uh machines and things like that um so I was like oh my God this is cool and then the best part was that they started us with a programming language called GW basic which is a graphical version of Bas uh basic if you remember the basic language you had to type the line numbers like 10 you would do this line 20 you would do this line 30 you would do this um GW basic was a graphical version of that so you had commands to draw lines and circles and all sorts of shapes and whatnot which fascinated me and it was still like a terminal back then oh yeah this is yeah yeah this is all uh text based um sort of like terminal environment um the Q the the basic environment is pretty well known for its like blue screen with the little menus on top and stuff like that uh GW basic had the shortcuts at the bottom and it was all black you would just write your U commands on the side uh your program on the side and then you hit uh run and it would draw the things and then you escape out and you change it and stuff like that and how far could you push it was it just to kind of draw shapes or what was the kind of the end goal of this no it had full basic uh support but um it had those extra um sort of like commands for drawing shapes and colors and Fields and those kind of things um and I remember there was a book that the my computer teacher um that class uh had sort of like shared with us and it was all this like different star shapes drawn algorithmically so you would write few lines and it would draw this like complex star shape out of all these lines and circles and stuff and like changing colors and it's beautiful patterns and that's where my uh Fascination kind of started and moving forward from there how did you pick up your Basics as you mentioned so you started reading books because back then you couldn't really go like to on the internet yeah so that was that was the first time I touched computers and we halfway through that class we moved to North of uran so I didn't have access to the computers until like a couple of years later where I was in uh High School in the high school they have we had a computer class that we would go to outside of school and um again it was GW basic I was like give me the GW basic so I can draw shapes and do graphical things so I started playing with that and kind of created a very preliminary U graphics program that you could just you know point to places and draw lines and that kind of things MH and then that class ended High School ended and I went to University well the study year for university the the year before and stuff like that didn't have access to computers again until I was at the second year of University second year of architecture school where I was like I kind of need my own computer and I need AutoCAD and a whole bunch of other stuff and that's where I that's was the first time I was like I think it was like 19 or 20 that was the first time that I got my own computer mhm what year was it you said you 1920 but this is 1999 20 actually 2000 okay 2000 all right yeah it was around like 2000ish that I got my own computer and I remember it had a decent graphic card at the time it was a Savage card and uh most other computers didn't really have a graphics card and I had a modem um things like this that was like super cool at the time and at this point you still kind of played a little bit with code but you were not like coding some projects all the time or something like this right you just had little understanding at this point yeah so one of the things that I did was that the when we moved to Northeast of Iran to the bigger city in that second computer class that I was at I was like I like this enough and I can see how fascinated I am with this so I started I knew basic at the time through that class but I was like I need to learn something better so there was this uh computer like technology bookstore in the city and I went there and I saw a book that says C programming language by Dennis and Brian kigan and that's a very famous book it's like a Bible for program it's called a k&r book um this was a translation in Far SE and I was like oh this seems interesting and I looked at the writing I was like this reads easily I can understand this so I started reading that book and that's I taught myself how to learn c um but I didn't have a computer so I would like write all these programs on pieces of paper and go through them in my head imagining that they would work the first first time that I actually got to experience all of this was when I had my own computer to kind of sit down and after C I started ring a little bit of assembly and but here and there like I would go work for companies and they would have a computer and like after work I would try a few things out um to kind of test out my programs and stuff like that but it was really when I got my own computer that I had a programming environment in front of me and at this point you haven't still started with python I think python didn't exist yet oh no no no this is way before yeah this is before all right and when does the python come into the picture so you started with this graphical language then assembly basic c yeah so um so I went to architecture school second year got my own computer started programming um very quickly realize I like the more technical side of architecture and I'm more I'm not on the very artistic side I'm more like on a little bit of a technical side so I spent a lot of time with the computers and learning different softwares and working for different companies like I work for publishing graphic design like all sorts of stuff Electronics with my friend all sorts of things around the computer computer was always in the center of all of this MH and then we moved and like throughout this time I learned C programming language for embedded microcontrollers so um I was writing C for chips like arm chips or admail chips and then uh we would uh I had a friend that he was a he was an electrical engineer so I taught him C and he taught me how to use Electronics Digital Electronics mostly and we would kind of like start doing projects and stuff together which was a lot of fun um I still haven't P touched python at this point I knew it existed but I really didn't touch it and then I moved to the US and while I was working here as an architect again I kind of realized that spending time writing scene stuff takes a lot of time so I kind of needed something that's a little faster that I can use it as a scripting language and by this point python was was pretty famous Python 3 was already out um so I started picking up python so this is sort of like around like 2011 is which I started learning Python and what kind of problems have you tried to solve with the programming language so what was your why reason learning programming was there like specific problem why you decided like okay this is the python or well part of part of it was always that I loved computer so much that I was like I anything I can do to spend more time with these machines and then the other side was that I have a lot to do in my day like for example I remember one of the things that I automated with python was that sending emails to my BS because I would supposed to every morning when I come to the office I would uh go through all these like government websites looking for jobs and they come with a pretty standard format like there's an RFQ and says like you know what kind of job it is and blah blah blah so I would go through and pick out the ones that I thought it would be interesting to him but then as I would download all these PDFs I needed the standard format to to send emails to him so I wrote a Python program and I would grab this PDF and throw it in this P Python program and it would automatically send email uh emails to him which he hated because like he would get like 20 very well formatted emails right after each other really quickly look like spam right yeah was spaming the inbox with valuable information arguably but um like I started doing that like renaming files python started really quickly becoming the Swiss Army knif thing yeah see right and you said that you started python you were already in the University right or it was already after it was after the university when mov to the US yeah I was working as an architect at this point 2011 is primarily in AutoCAD um doing stuff on the side at home like learning python I knew Maya a little bit of Maya so I was writing like C++ programs plugins for Maya exploring an environment because I touched grasshopper before uh inside of rhino but I didn't have a rhino license I had uh the version and I was exploring like writing plugins for it to create like geometry generatively things like that and where does ravit come into the picture because so far it sounds like you haven't been working or studying using rivit right yeah this is all before rivit um when I moved to inside of the US I moved to uh Portland where I live now and when I started working here there was this company that I got a job with and they used breit uh heavily and on the interview they asked me do you know Revit and I was like I've done a little tiny project but I I'll don't worry about it I'll learn it don't you know don't worry about me and Sofer I'll pick it up MH um and they're like sure so to that's started 2014 and it was RIT 20 2014 is the first one that I started working I by the end of that year I had the first version of P rabbit because like I couldn't work coming from AutoCat and all the others programs that had scripting languages it was really hard for me to work in Revit and do anything all right so started in ravit and by the end of the first year you hated so much you started creating by RIT to make it better it was like it was like mid mid through 2024 and I'm like this is not going to work so I found uh RevitPythonShell and I started writing Python scripts and kind of learning the Revit API I was like okay this this is great I can I can it's bringing my sanity back to me U so I would like run uh area calculations in my own scripts automatically and my like my boss would sit beside me and we would go through the plans and I keep running this and he loved it so so much cuz he didn't he couldn't do this with anybody else like he I was showing him live information that was hard to get from like Revit schedules um and those scripts that I wrote basically became the first draft of pyRevit tools uh they went into I figured out a way to put them in the ribbon um and um the first version of PIR it had U monsters for the icons for all these different tools and each one of the monsters was specialized in an aspect of the like sheets and blah BL blah which those later became the panels and you know that kind of stuff you have like a screenshot or something from your first pyit toolbar I really try to find stuff but I I can't you you can go back like in the repo is there you can go back all the way to the oh yeah actually to the original commits and all the icons are are still there somewhere in the history I need to check what's going on there it's actually quite interesting so and by this point was Dynamo even in the picture for you have you used Dynamo with python node no not at all I was sort of like I was a lot more interested I'm the if I want to simplify it I'm sort of like Frameworks kind of person I like to make tools that other people use to make tools MH um so I would I saw grasshopper I was like this is fascinating and I learned how it worked and I'm like okay I know what it does now I can move on to other things um and then when Dynamo came out I looked at it I'm like I've seen this before like this is not even as good as uh grasshopper so there's no reason for me to spend time here when I started working with Revit a little more I was like maybe this could be the platform that I could you know make things with in but it was missing so much that I was like I'd rather just do them in the Revit API and have a cleaner simpler environment with no plugins and stuff like that versus like a lot of dependencies so I have a question so you're already familiar with so many languages especially C why have you decided to create pyit instead of just using C# and making it natively like native ravit plugins um the biggest drawback for me was that um first of all I absolutely love python I think it's like for me it's like the perfect programming language it's there's no such thing but like you know it works for me the um C I don't like that language I don't like programming languages that are very complicated there are many ways of doing things um you python is very simple very simple for to just write a bunch of functions and write a bunch of data structures that's all you need it's very much like C in that sense so I had an aversion to like that's what never really learned C++ I learned it but I was like I'm fine with C I don't really need to deal with this cuz it's like all the templating systems and it's it gets very complicated and I know it has powers does c also have memory allocation like C++ yeah yeah see you're in C you're basically in charge of everything there's nothing there's no runtime in C um it's just a standard library and it's you but it's such a simple programming language that with like a bunch of a couple patterns like how you would deal with the memory and how you with with the file IO and stuff like that you'll you'll be pretty pretty fine um I wouldn't suggest like writing programs in C these days it's a you know pretty complicated language like if you want to use I don't know send an HTTP request it's going to take considerably more time in writing that in C versus python so you're not going to be as productive but um so python was kind of like that for me it was simple it I didn't have to think about the how I want to structure the program I could just write a bunch of functions throw in a module and have a couple of different data structures and start working with them um C I had a hard time doing this with in object oriented environments in C I kept like I to this day I still fall into this um uh sort of like uh loophole of trying to structure all this nesting of the classes and which function overrides the other one and there's you know that kind of stuff so I spend more time WR figuring this out rather than actually writing the code mhm um so the problem with me with C was that I need to have RIT open and I have a project that takes about 15 minutes to open um because it's so big and I want to write some tools to make stuff you know in this to automate things in this project but then if there's a bug I need to close Revit make some changes compile the plugin again load Revenue again open the project run the tool that cycle was too time consuming python completely remove that cycle if I had a script in a empty script in a place and I would run rev it that script will show up as a button in the Revit UI and I could keep just changing that same script while Revit is running and just clicking and you know getting different results yeah this is what's so amazing about py RIT that you instantly like you run it you get an error you go change one line back and forth that's Prett much how I also develop constantly getting errors fixing back and forth oh now it works and I'm happy yeah working as an architect then that sort of like time consuming software development cycle kind of didn't work python solved that problem python inside of python inside of Revit I'm not so familiar with CP but I keep hearing that many people say ah C is still faster than writing in Python do you have any thoughts on that yeah so like over the years I've looked at a lot of like different comparisons between programing languages and a lot of it comes around like performance and uh memory efficiency and those kind of stuff and and what I've realized is that all programming languages have a have a sort of like a mind um have a sort of thinking way of thinking about them and if that way of thinking aligns with your way of thinking about writing a program it's going to be a good programming language for you so like there people that love the love C love objectoriented programming languages the people that don't like I'm not a huge fan of it if I try to stop myself actively try to stop myself not going more than like two levels that deep inside in class hierarchy so if I have a base abstract class I only do like one derivative of that so that creates like these two levels for me two layers obviously you know I fall into this pattern all the time that I'm like I end up having like really deep nests and you can't figure out where where something's happening so it kind of it's It's hard to really compare programming languages but in terms of just performance like raw performance python is written in C so and it's an interpreted language so it's it as it's running is interpreting the instructions that you have written in the python file and execute them then one by one in a loop that we call the python interpreter Loop so there's a loop running inside of this CPython that runs these instructions uh C it's sort of similar it reads your instructions which is your C code it translates them into this uh Intermediate Language and then saves that in a dll which is your program but when it's actually running those it takes those interated language uh the IL code and translates it into machine code which we call jit compiling just in time compiling so when it actually runs your code it doesn't go through an interpreted Loop it runs the compiled code for the machine that you're running on so it runs on CPU read so when it runs it runs as fast as any other program that runs on CPU python has this Duality to it the right that you the code that you write in Python runs in that interpreter Loop but if you write CPython modules like NPI and scipi and all that kind of stuff that are using the python cap API that interpreter Loop calls into that module and that module is free to do anything on the CPU that's why napai is so fast because it's not inside Python's interpreter Loop um scipi is so fast you see tensor flow you see all these really um sort of like complicated extremely fast numerical libraries show up in Python first yeah because it had this connection to it that you could write on the surface you can write this simple code that goes through The Interpreter Loop executes very easily error handling is great but when it needs power it control it passes the control to that module and says go do your computation let me know when you're ready this was the beauty of python this duality of python that it's scripting language but it has a plugin that makes it as powerful for like scientific languages and all that kind of stuff yeah I see you could do the same in C if you have a very good mathematical Library um so they I would say they run as fast as each other in majority of the cases thing is just that Autodesk has C more optimized because they don't really do anything for Python and python pyit also needs a lot of work right now to kind of get it up to date recently spoke with jark they want to make a lot of changes to make it faster but it's all about the menpower yeah when you run a compiled program using like languages like C++ and C sharpen stuff like that shipping that language is a little bit easier because you don't need a run time in theory like if you write a Revit plug-in Revit guarantees that the runtime theet runtime is available right MH but when you write a program in Python you with the python application needs to be on the target machine to be able to run that that's sort of what pyRevit started guaranteeing it's like I guarantee that IronPython is going to be there when you if you share your scripts with other people that's the that has to be the general problem around Python and it's still to this day is a little bit of a problem deploying part-time python application is not as easy as um compiling a c application into an installer and send it to somebody how hard would it be to create kind of python plugin and ship it as the C plugin you know like with this installer like you're talking about is it even viable in ravit or you need like completely rewrite py as your own thing first if you want to run that python code you need to have the python runtime available so like this is kind of what I do right now with rhino in the new sort of like Rhino 8 I created this uh new script editor we decided that you know the all the script editorials have been around for too long we needed something that's a little more modern so we created this new script editor that has IronPython and Python 3 but the problem was like if I have a script how do I share it with other people so we created this mechanism that you can have a bunch of your scripts inside a project and you publish this as a rhino plugin so it gets compiled as like an actual net DL but it embeds your scripts inside of it somewhere so pretty much can share all your codes as a package as a package with somebody else yeah as long as they use the same Rhino version and about right because when that DL gets loaded it requires this new scripting infrastructure uh to say that I am carrying a Python 3 script can you run this for me as this command again guaranteeing that the run times exist yeah that's quite deep stuff I'm I'm far from going that deep in coding my python is pretty good but once you go into these compilers run times I'm a little bit lost myself but when you created py how good were you with programming languages would you say already were like an expert no not at all I'm still not not not a very good programmer like there are Prett a lot of people that are much much better programms than me um like at the same company that I'm working on like every time in the dev meetings I'm like oh my God I had no idea that thing existed and that's how you're supposed to write your programs um but for me it was like I've never really like I'm not I'm not very good in math and I wasn't really good in the sort of like the algorithmic complicated computer science aspect of programming for me the fascination was that hey look I can put a bunch of commands together and make something happen and that's why I love the scripting languages a little more um this the the time that I was like spending time on microcontrollers and stuff like that was slightly different mic microcontrollers are a lot simpler uh so you're writing C but you in charge of everything and it's still fun and you're putting things together your controlling timers and watch dogs and stuff like that on your um on your uh microcontroller and it's a lot of fun so I'm not I wouldn't call myself a good programmer but that didn't really stop me from you know putting together to many lines as long as you understand how variables work and how a couple of control flow structures like ifs and switches and forward loops and stuff like that work I think you can put a lot of good useful things together the hardest part doing thing on Revit hasn't been the programming language it was like dealing with the revid API cuz there's this thing that you want to do and you're like it kind of doesn't do it so maybe I can do it this way I can do that first and then do this first and then as you're doing this you're like oh it breaks when I make the first change or I'm going to need this other thing that cycle is the one that takes really the most time it's not really the program language itself hi real quick if you're into py RIT and you want to boost your skills in record time then check learn rate ai.com platform you'll find free inp courses for any stage of your programming Journey you will get access to pyit Basics Pro and modern UI courses plus you'll also get access to my code library and join my exclusive Community for pyRevit developers in the community we can chat discuss programming in Revit and most importantly you can ask for help when you need it the most if that sounds interesting go to learn r.com to learn more and now back to the show I like to say that programming is pretty much just a skill about problem solving not the coding coding is just what we use for solving problems and in the end of the day code is just kind of step-by-step instruction there's a really good video on YouTube I don't know if you've seen it's called how to write exact instructions and it's a dad who just asked his kids okay you have to write me instructions how to make a peanut butter sandwich and I was saying like Okay take the knife kind of put the peanut butter on the bread and he was he was literally follow and he follows the awkward instructions of this yeah it's really cool yeah yeah and it looks so stupid but in the end of the day this is how machines look at our code and of times when we write a code it doesn't work it's probably because we just didn't think about some step or it's just not exact instructions and yeah that's what programming is for me and many people focus too much on the code itself um there are a couple of old school programmers from like 1960s and 7s and stuff like that that they were involved in creating the Unix programming language um the operating system and the C program language and all of that there's stuff that we still use today um one of these guys said something that resonated with me so your program has only two things it either has logic which is let's say a a function that computes um factorial of a number that's just logic it's pure logic or it has a state so it's holding something in memory and you're manipulating that state that state might be uh the state of your UI things change and you need to disable and enable and update so at every point in time your UI is at a very specific State and this state is represented in memory somewhere M and your logic the pieces of logic around your code are mutating that state right the art of writing logic is just good math and algorithms and studying algorithmic performance and things like that so you write the piece of logic that runs as fast as possible and it does the thing and I don't know like and it's depends on the task that you want to do like you know depends on what kind of like if you want to pick a sorting algorithm it depends on what you're trying to do they're like Bui different sorting algorithms so that's that part is fairly clear the part that's unclear and it's the art of programming really is designing the right data structure that represents your state what do you mean by that so let's talk about the script editor that I made in Rhino uh Rhino 8 MH this is something that I sort of like started learning it was the biggest UI that I ever made UI application that I ever made and it was the the biggest C code base that I ever worked on so I was learning this as I was going through it the script editor has a bunch of codes open and a bunch of panels with some contents and there's like Explorer on the side and there's a whole bunch of commands running in this application it's not just the UI that you're seeing that has a state there's like all the commands that are in the memory that that are about the editor and all the panels that you don't see that are not visible in the UI maybe like a whole bunch of other stuff is outside of this UI that needs to be at the correct State at the right time and meaning at the correct state is that if I have a um toggle breakpoints button in the breakpoints panel for the debugger mhm if I don't have any break points in the script there is no reason for that button to be active that button should be disabled because it doesn't really do much right and the disabled enabled is the state of that button uh like triggers yeah yeah exactly so as I'm debugging the code if suddenly my toggle debug uh break points button becomes disabled that's a bad State that's not supposed to be there that's a bug right yeah so maintaining that state as the state of other things are changing is really complicated and you have to create this data structure that represents this as we call it in a sort of like the I or we call it the view model or the model for that um uh editor this model that represents the editor conceptually and there's a place on it there's a property that says um breakpoints button enabled and there's a property that says like do I have break points in there or not and internally these two are tied to each other MH so when the breakpoint changes it also changes this so this data structure internally manages its own state if you add a breakpoint it enables the the breakpoint button things like this they're talking about mvvm right now this patter model view view model right that that you have connected code to like interface and it's all kind of interconnected yeah I'm using I'm using UI as an example that's why sort of like the conversation goes a little closer to the mvvm models but this is about everything that you're trying to do uh like if you're writing a data structure that's supposed to hold a list of uh employees or something like that those are like typical examples that you see in programm languages um you could use a normal basic data structure like a list but then like for example if you want a certain number of like your principles that are listed in employees to be listed separately you might encapsulate this list in a data structure that knows how to deal with the principles list things like this so it's the art of that creating that data structure that represents the thing that you're trying to deal with that is really the art of programming if you write that data structure correctly if you kind of figure out how it's supposed to be working with it is very easy because it's very intuitive at this point and it behaves the way it's supposed to behave so also kind of going back to this choosing the right design patterns and most importantly deciding what you're trying to get out of it because sometimes you're trying to make something simple and it doesn't make sense to go into objectoriented programming but other times it actually makes sense to go into object oriented programming instead of dysfunction when everything is interconnected and yeah yeah I see it it's definitely very important to kind of decide on what you're trying to achieve before actually jumping in because that's what many people do they first jump in they start doing and then halfway through they realize they using well it's not going to work because they decided to do something certain way at least that's how I I did certain things I jumped into creating some plugin with UI I didn't know anything about mvvm vpf I just decided to spent couple days on the UI form and I realized oh actually I started everything wrong everything started to break because I just didn't think through what am I doing here yeah and that's absolutely fine like as I'm that's one of the other reasons that I like python so much because you can like let's say I'm creating something in Revit I can just start a script and start fiddling and trying to figure this out and um like if the art of programming is writing that perfect data structure you're not going to know that data structure right off the bat unless like it's super simple so you have to go in and write a bunch of like very bad versions of the way you're trying to do things and you're like yeah that's this is not supposed to work like that so I'm going to make a change to that over time you'll kind of understand the full scope of this thing that you're trying to create or deal with or it's like in the end whenever you write any big program then you have a look at it and you always think man I should have done it differently this or that then you rewrite it and you still have the same thought that you want to again rewrite it differently I don't know do you still have this kind of thing when you kind of finish kind of big code and you look at it and you want to do it completely different or just rewrite it yeah oh my God it never goes away right yeah that's what I'm doing R night it's it gets a little questionable like how much you can change um but a lot of like I wrote a bunch of bad code um inside of the editor because I didn't know how to do this better so I'm like going now after a couple of years I'm going cleaning that up making sure it runs as fast as possible that kind of stuff so rewriting those and I was WR and I was reading u i was watching this YouTube video of a guy that was a programmer and he suggested that limit the size of every chunk of your code to about a week worth of work how how how big chunk are we talking about is it like a file a class um depends on how you structure the program like for example if you have a module that's supposed to talk to your web server make that as big as about a week worth of work so if you realize that in the future you're going to need to change it it's about a week of work and then you can replace that module so modularize it in this way and there're sort of like separate components abstracted components so you could replace each one of them in about a week of work and make it better or use a different back end or you know that kind of stuff there's this principle that tasks always take the time that you allocate to it meaning that if you're going to let's say you have to write an essay if you're going to give it a week it's going to take a week because you're going to write it in the last day anyway you have 24 hours to write it you're going to write in 24 hours and I think this is also good thing like you said that the chunk should take for example a week once you give it time constraint your brain also knows like okay there's like ticking time it starts think also differently I think that's yeah that's a good point yeah just thinking about it that hey I don't want to write a big chunk of code is also help helping you focus on what is bare minimum requirement for you you know for that code at that at that time right interesting uh also we got away a little bit from p RIT I want to have a few more questions first of all what were the biggest challenges creating py RIT cuz at first you took ravit python shell and you decided pretty much to make it into how to say it reusable extensions right so you can put all your scripts in the toolbar what were like the biggest challenges in the first I don't know year or two of creating it um the first year or two the biggest challenge was really there were two things the first one was how to get all these Python scripts to show up in the ribbon which I learned from um RevitPythonShell so I was like okay rabit python sh does this I'm going to copy exactly what he did and start creating the buttons that's sort of like that was the first draft of um P rabbit we I solve that problem but after that it's been always deployment like packaging all of this in a installable and send it to people that have different responsibilities somebody's an admin somebody's not an admin somebody wants these tools somebody doesn't want the other tools like all sorts of stuff finding a way to get this program installed correctly on the target machine has been a huge Challenge and I kind of blame windows for a lot of this um but it's it has been it has been a big problem um that's part of the reason that sort of like pyRevit attaches itself to all the different Revit versions CU I I didn't really want to deploy pyro for five different Revit versions at the same time I i' rather have like one pyRevit installed that I can deal with um cuz like if like imagine you there's a customer that asks you a question on the Forum and he has like three different Pirates installed for three different rabits oh yeah it becomes kind of a nightmare trying to figure out no I think it's just a taking time bumb right at certain point you stop kind of supporting one version but the other and the hell broke close yeah I would say every other challenge has been fun they're like little challenges how do you do this how do you do that how do I like update P revenues and get and stuff like that um the U but then you know it's fun you go through it you spend a week or two you kind of figure it out and it's it's okay the challenges that gave me a lot of headache that one of them is just deployment creating an installer for pyro no I can imagine every time I hear Jean Mark talking about this I kind of my brain a little turns out about all this deployment how to make this managing keys I'm like it's kind of foreign to me I know what you're talking about but I don't know like this good understanding uh would you do it much different if you would had to do it today if you would kind of start py RIT let's say that py RIT didn't exist yet and you decided today like all right I actually want to make it how much different would it be um yeah I would so there's a part of pyit that goes around the um the your local drive and starts finding all these scripts and loading in the revid UI and stuff like that mhm I would definitely write all that in C like just have make it as simple as possible so that removes a lot of like python code that gets deployed to the machine and it would run a lot faster uh so the discovery of the scripts would be a lot faster and then it gives me the flex because it's fast it gives me the flexibility um to start having a bunch of listeners and stuff so as you change the layout of the scripts in the folder the UI can readjust itself to represent that layout stuff like that so I would absolutely rewrite that part and then I would keep everything about the python the same so the buttons the way like the bundles work all of that will stay a it works amazing it's the simplest you can imagine yeah that's I think that part is fine that's yeah that part is what people like it and it's easy to use and like just just throw an icon in a bundle and it shows up in R it that's great and then the other thing is Python 3 which the one that we have in py right now barely works it may be useful in some instances and stuff but I spent the past four years trying to make Python 3 work inside of rhino so like I would bring these experiences and those changes to py RIT to the new py rbit so he has Python 3 I'm not sure if it would need really Python 3 inside revid environment I think IronPython is doing a very fine job and there's not a whole lot of people that want to run tens of row inside of Revit uh the naai numai is a big one actually quite a lot of people interested in Python 3 some people because of the UI because there are some packages in Python 3 majority I hear about napai what is it mat not not matplot pandas definitely working better with XEL so napai and pandas all the time people asking me about this one I've shared how to do it but I also mentioned like five times during the video like this is not like in final version it's still buggy watch out also interesting cuz just talked to Jean Mark and he said that for 2025 one of the big things for p they have is actually rewrite this thing in C like you said all this loading of the folders and kind of increased improv the speed and stuff so I was glad to hear that there's already you right away pointed it out and he also mentioned this as a big point on there to list yeah I think at this point pivate kind of needs that to like load faster um like as the tools cuz one of the things about having a scripting environment is that you would end up having a lot of scripts for different things you have like you know copies and copies of these scripts that do slightly different things um so it's important for that environment to be able to load all of this a little faster I think the latest RAV API change since they migrated to that net 8 I think this I think this was like a wake up call that all right a lot of things need to be reworked it's all about the Manpower spyit well at least John Mark it's really good what he's doing right now he's pushing kind of kind of looking for people collaboration putting a lot of effort kind of organizing all this stuff this is really good yeah these guys were the godsend cuz when I started working at mcne I thought I can work on the editor and pirate at the same time but once I started getting into the editor I was like I'm way over my head like I don't have time to do anything else MH and that's the time that sort of like they started um digging in and getting more a lot more involved and we are at the point that there it's a a organization run by them at this point like um I don't do anything in pyro anymore I don't write code for it anymore I just help out if they need anything but you know they're pretty much self-sufficient at this point like I didn't do I didn't do any pretty much anything for the transition from um 2024 to 2025 it's all them which is amazing no I definitely have huge respect to the team because they all working kind of parttime for fun cuz many many people Al mentioned with jar that don't realize that P RIT is not like organization company for profit it's just a bunch of people who are excited about python they work in ravit and they want to make it possible this is what kind of keeps this project alive right now shark is planning a lot to kind of get the funding pirate needs to kind of hire developer like C just at least part time for a couple of weeks like okay here's the task please do it just make it better and so this is what I understand is the goal for pirate right now which is great to hear yeah yeah it's it's been amazing I'm I'm first of all I'm honored that there's like a bunch of people that decide decided that this is something that they want to keep alive otherwise it wouldn't been dead um the other part that I'm really happy is that people are working on it that are actively using Revit every day I think that's abs like you should not make software that you don't use uh like one of the one of the challenges that I have at my think right now is that like I'm not using Rhino actively every day for creating things and I'm writing this script editor part that I'm not using actively in production every day and so I don't I'm blind to um some of the important ways that this is used and the Annoying points about it and how it could make be better so I kind of rely on the feedback of the people on The Forum that they come and say like this is not running as fast as possible like this is this is not supposed to be this this doesn't make sense that kind of stuff yeah it's always the little things that matter and know you think it's it's not that important sometimes this one little thing can make people so much happier just the way it works right and it's people build muscle memory like um python Rhino has this editor that's been around for like 10 something years 15 years and um when I walked into Rhino and I was like um uh Steve said we want to put Python 3 inside of rhino I was like great can I have this project and he's like yeah do you want to work on it keep working on um so we kind of realized with the transition to net the old editor wasn't really working either so we kind of need to create a new editor that is consistent especially with uh Windows and Mac because like Rhino Mac didn't have anything it had a text box for the script editor and a play button um so one we once we started working on this um I kind of realized that um the I had never really used uh the old the script editor in production so I didn't really exactly know how this descripted is being used and it's a lot and Beyond what you can see in the UI and what you can see in the code it's all those nuances of like how people are used to writing doing things so the moment I introduced like Rhino 8 came out end of 2023 uh the and the moment people got their hands on it they're like why is that button 16 pixels to the left cuz I have built this muscle memory with my mouse that I can just go click that button and it's not there and or like it shows a prompt now instead of just closing and whatnot and I was like holy smokes I this is not something that I ever thought about that it inflicts physical pain on somebody when you move a button like 16 pixels on the screen doesn't make any sense but it's such a big deal breaker this is why in ux everyone is afraid of new designs this is I think I heard some story somewhere there was a developer talking I don't remember exact story but the point was like everyone was complaining how bad the software everything is buggy and so on he did nothing to the code and he just I think he just told them like this is we did this and that like internally we changed the engine or something like this he didn't change anything everyone started writing positive feedback it's amazing it's so much better finally he was like I didn't do anything I just kind to gave you the placebo and you just took it like and he was just showing that sometimes users don't knows themselves what they want yeah it's hard to it's hard to because I feel at this point in my life after being five years of on the M forums when I started working there and I would get all these negative feedback I would take it personally I was like oh my God I'm a horrible person I broke people's stuff you moved it 16 pixels yeah they can't do their work now but now after all of this I kind of realized that I need to get past that and sort of like read what they wrote the the problem and kind of start going Beyond beyond that like what is the actual problem there is it it's not it's a lot of times it's not what they're asking it's somewhere deep somewhere else um so you kind of have to have this back and forth and you know get him to give you an example or a sample this repeatable error and ask a questions about how do you use this like you know do you use this first do you use that first that kind of stuff so that communication is incredibly important to kind of figure out why they hate this so much is it really because the button moved or is it because like the button is not prominent enough or because like for other reasons finding that out is has been it's it's actually quite fun like I enjoy that on the forums now when people when I go to the Forum I'm like somebody's like oh this is not foring working I get excited I'm like oh there's new challenge that you know I need to fix you're like detective going in all right time to crack your subconscious what did you mean here yeah yeah exactly so I talk quite a lot about McNeil so we can switch to that and actually have one question or two from the community and one is going to be perfect for this so the Jo from the community wanted to ask with the success of the pit how come Autodesk never make you a part of their team never kind of show any financial support and how did you end up at McNeil can we just dive into that yeah yeah yeah I mean I don't really know about autodesk's intention talking to other people I've gotten this comment a lot that autodex doesn't really support open source projects mhm I don't think it's their thing they want a company to be representing that and supporting their customers and stuff like that and I think as a corporation they have a easier more legally sane way of dealing with an actual company that makes a plugin and supports its customers and all that kind of stuff versus the one guy there that sometimes writes this program sometimes doesn't but have you talked to anyone on autod Des C not really oh they never even reached out to you no no no nobody reached out we never really reached out I wouldn't I mean I talk to a lot about out of desk all the time so I wouldn't really expect them to reach out but um yeah I mean they may they may be doing Jean Mar and the team they're really they're doing really good job with like um branding prob a little better as it sort of like a bigger group of programmer taking care of this so they might actually have some success with this I hope that to is going to wake up and see the in community because P ravit you started this as just a side project it's been 10 years and it's still so popular people keeping it alive it's I don't know someone recently wrote me that py RIT is one of not many things that made them excited about ravit again because every time they go and ravit they look for plugins and so on and finally they found P RIT he found a plug-in but it didn't do exactly like he wanted then he found out that he can hold out click on the button see the code often times when you need this just tiny change you look at the code it's in Python so it's pretty much English you just need to especially with AI you just kind of give it to AI say like I have this I need this what do I do and without even code you can start coding because just you can replace a few lines this is I don't know I'm very excited about pyate I spent a couple years teaching people because I don't know I just excited yeah youve been you've been doing a great job man I really appreciate we all really appreciate the um the spreading of the word like I I appreciate not because you're talking about P Revit but I appreciate it because you are teaching people and helping people automate things that could potentially save a lot of time and also it sort of like starts introducing programming language to a lot of people that are scared of this like I always say if you grew up and you used calculators these days Learn Python because it's kind of the new calculator um you wrote a bunch of functions in it doesn't really need to be Beyond that if you don't want it to be it can just be a thing that you run in the command prompt and you run some math in there and write a function and do your calculations and you're done but just that flexibility that familiarity of how on how machine works it could provide this uh capacity to at least like at least copy and paste the coding to ChatGPT and understand the changes that you made to it oh yeah yeah yeah I think this is how majority of people get started with pirate nowadays cuz there're thousands of scripts you just need to find the right one and yeah try to change it yeah and start modifying it and stuff um you asked another question about how I got to McNeil um pyRevit had a um a conflict a dll conflict with this other project that McNeil was working on at the time and they're still we're still working on it it's called Rhino inside Revit so it was a dll conflict when these two plugins were running on Revit and Scott Davidson from mcneel he texted me on LinkedIn and he's like hey like we got this conflict can we talk about it he noticed that I'm in Portland so he's like you're close I was like yeah there was a bill conference going on big Workshop going on at the time um so I was like I'll be in Seattle for that I met him there the first time we sort of like walked around help people try to figure stuff out I think he liked something there in me and then uh a couple of months later him and Bob came to Portland and they were visiting zgf and uh Scott was like hey do you want to meet up I was like absolutely so I had coffee with him and uh I actually took him to dinner uh took Bob and Scott to dinner and apparently I didn't know that Bob hates this people like taking him to dinner and paying for his dinner and stuff like that good start and I did I did all the wrong things like I I dressed up which also like that's not the Pacific Northwest thing people don't dress up around here um so he he didn't like any of that a friendy but the um but I met them for coffee the next morning and he asked me a question he's like what so what do you want to do oh I was working as a b manager at the time I was like hey this this the been fascination of my life that I want to make tools and help other people use them and take care of them and all that kind of stuff and he's like hey do you want to come work at mcneel and do that and I was like it's great question let me think about it um I was I had I was going through an interviews with Airbnb at the time um trying to get into this like group that they were creating to create like prefab automate prefab manufacturing and stuff like that is it like devel software development or is it more like be management yeah yeah software development yeah um to automate you know um uh certain things around like prefab houses and whatnot and that project kind of died Away really quickly after that and I was in way over my head like the other people that worked on that project were you know insanely good programmers very technical people that kind of stuff with years of experience in these kind of things so I was like going back and forth between whether I should accept that job or this job this job and whatnot and I'm really happy end the day I got the mnal job because that's the sort of like that was the environment that I was looking for it's chill people are very nice um I work on a you know fantastic application that's been around for 25 years um and there's a lot of to do you can write python if you want to do you can write C if you want write C you can write C++ if you want to do that so it's been it's been great that's that's how it got me into McNeil a conflict with P rbit yeah it's funny that a simple bug brought to you all this opportunity and meeting these people you never you never know what going to open the next door for you this is interesting yeah and what do you do in mcneel since you joined them can you share a little bit day-to-day live yeah yeah yeah so um when I started joining McNeil I was supposed to work I was supposed to be the rivet guy cuz like nobody really at mcil knew what rivit is um KK uh Kik from Barcelona office which is the main developer for Rhino inside Revit he's the one that put Rhino inside of Revit first he has he had the most experience with all of this because they created another plugin for Rhino it's called visual visual Arc that's sort of like Bim for Rhino and theyve been setting that for years so he he understood a lot of these Concepts um but no nobody really had like production experience with Revit so I was supposed to be the Revit guy and then I started working on that project and sort of like after a couple of months this Python 3 thing happened and I got way more excited about this um so I kind of slowly switched to that one and uh we hired another person his name is jaffi way better than me in Revit a lot of years of experience doing um uh actual manufacturing and stuff like that doing a lot of like complex facade panels those kind of stuff is he a developer or or like real like B manager without coding well he he was so he's a RIT Guru but at the same time like he did a lot of Automation in the stuff that he worked on like especially with like Dynamo and whatnot as far as I can I know like he doesn't write code as much he knows I think he writes a little bit of python and whatnot um but his biggest skill is that um he knows how to juggle Revit to and make it do the things that you know he wants to do so now he supports everybody that he's using Vino inside Revit which is fantastic because that take took that load off of me um and uh it created a better dynamic between him and Kik at the same time they bounce off ideas each other and sort of like go around it which is great it's very productive and then the I end up like the only thing I do is like I make icons for the Rino inside Revit that's pretty much the only thing I do after that it was just me and this new scripting edit script editing infrastructure in Rhino 8 which is Python 3 python 2 c as a scripting language making plugins grasshopper one grasshopper 2 um running the stuff from the command running stuff from visual Visual Studio code outside of rhino rhino compute like this thing has everywhere Rhino is the scripting is also and uh do you write a lot of code or is it more like kind of thinking laying out the road map uh there was more thinking than lay at the road map when I started on this not so much of that anymore because we kind of covered the whole landscape as much as you know I could think of it but these days it's mostly clean cleaning up the code that I wrote four years ago to get it to run faster now during those cleanups I break things again apparently I did yeah last night so Rhino 9 is a little bit broken this morning but uh they scripting stuff but I'm going to go fix that um but yeah it's mostly like you know writing um not a whole lot of code but replacing bad code with cleaner code that is more readable so you know in 6 months when the 's a bug there and I need to read that code I can actually understand better what's going on here um that kind of stuff okay so pretty much maintaining the code base yeah and was it hard to transition so can you take to this moment you you are just joining McNeil you just started working with them was it like a really hard to go into this coding environment or was it easy for you can can you just share your experience if they basically let you kind of figure it out right so there's not a whole lot of onboard I showed up and my like okay hi do you need a laptop I was like sure okay buy one so I got a laptop and they're like here's here's you we added you to the Rhino Source on GitHub so you can pull Rhino and then here's a document that how you build Rhino you go build Rhino and you're like oh I built Rhino on my machine now and you load Rhino and there's nothing there and it's just a viewport and you're like where are the tools and they you reach out on the slack and they're like oh yeah you have to load the plugins so you go load all the plugins and okay now it's looking more like Rhino and then and then you're like okay so I want to make this change how do I do this how do I do that so you start asking questions you'll start focusing on the thing that you want to do and ask questions when you have a question MH and then every once in a while once it's you're happy with what you have done you show up on this developer meetings that we have on Tuesdays and we have a section is called show and tell and you go and show what you've done and people talk about it and you know some hate it some love it that kind of stuff and you get some good feedback before you actually put it inside right it sounds a little bit like startup WIP which is really good one when you got start the company is not that big everyone is connected yeah and when you looked at the code was it overwhelming to you or was it just fine is it like on did you feel like it was on another another level when you saw the code of McNeil what they doing with Ryo and all of that um it really it very it very much varies and that which part of rhino it is and who worked on that code and all that kind of stuff there's millions and millions of lines of code in there obviously right so there's like it's a lot of different modules like there's plenty of plugins that are all importer and exporter file formats so there like 40 plugins there that just a normal Rhino when I'm developing like I don't even load those PL because I'm not exporting and importing files but there's a lot of code there the geomet engine is huge I don't know anything about it the U um the display engine is huge I don't know much about it um there is a whole lot of other plugins the parts of rhino that I know most about is grasshopper IronPython the scripting stuff uh a little bit of the display the plug-in logic stuff like that um the only times that I've sort of like gone beyond these boundaries is like there's something that doesn't work and I need to go track it so that takes me to like how the plugins are being loaded inside of Rhino and I was like oh maybe that that's where the problem is that kind of so I start reading the code in other areas of rhino but there's really no way of reading the whole code base unless you have something like this year in Rhino 9 I have a project that um Steve sort of like helping me out with and he's trying to um get me into more of a display code inside of rhino which is great so I can like create new tools in the Rhino like I want to create this tool that you can um array an object over curve but then you have to be able to draw that curve and then select the object and array it and then provide some adjustments and all and then display the things that you want to display about disarray that kind of stuff and that's all C++ and that's the part of right now that I don't really know much about so like I'm going to be asking a busi in different questions from people as I'm dealing with this um so so it's it's a massive code basee and you kind of you know go around reading what you need okay focus on one part at a time yeah and there's also like in this so big software code bases the software itself is a is a big chunk of the code base but there's so much other code around it that's uh revolved around like building and generating documentation and like you know making sure the Builds on Linux and Windows and Mac are all built correctly and like just general tooling around maintaining that soft MH um so there's like a bunch of those things that you could work on too like we got Pi got people that they spend most of their time writing the tooling things around Rhino not Rhino itself but just making it build correctly on the everchanging like Mac OS and that kind of stuff yeah so you make tools for your own team to be better at writing tools for others which makes sense yeah like for Rhino 9 uh Brian in the developer meeting um he was showing this other um web application sort of like that he made to for us to be able to manage all these features that we have planned for Rhino I and we can see the progress MH um like these are these are really cool things that you have somebody at the office that can write a custom tool for you to look at this thing that you're trying to do which is amazing like that's what I love about software so you can create all these like custom tools this is what people also get excited about py RIT because majority don't even see themselves as programmers they just kind of start by accident and then it just goes from there because they see oh I can create a tool yeah just notice like coming from me after all these years of writing programs and stuff like that I don't I still don't consider myself a programmer like I didn't go to Computer Science school I don't know how many different sorting algorithms are out there I just know that they're plenty um I don't know how to write the best sorting function for you know or the best memory uh safe code and whatever but I work inside of C most of my life and C if you know C it handles a lot of those conditions for you so I don't have to be worry about like releasing memory I'm like okay I can do this and the doet one time will handle that or I don't have to worry about like my buffer when I'm making a u web request or something like that the library would handle that like it's a lot easier for us there used to be a term when I was younger they called it puzzle programmers uh that you basically you program by putting things together which I feel like that's the majority of program these days is that you use a bunch of libraries that you know are designed for that thing and you put them together and you make something else and sort of like that's yeah like not a whole lot of us are out there writing new AI models from scratch different algorithms all that definitely not this is where all these memes come that programming without stack Overflow would not be programming yeah CU pretty much you just go there copy paste whatever with pyit it's you don't you don't need stack Overflow you just all have all these tools at at in front of view yeah so can we jump quickly back to py RIT I just wonder how your thinking in programming changed so could you explain the process of how you used to create uh pirate scripts like a decade ago and how you would create them now just kind of the the brainstorming the logic how much you would focus to reusing you know just these kind of General things yeah how do you approach it let's say this is something that I noticed as I was working on this rhino stuff I was like I can see how Engineers work and I can see how us architect designers work the architecture school makes us very comfortable with iterative design so you sketch something and like that doesn't work out throw it out do something else and you're like you draw this beautiful plan and you're like yeah that's great I'm going to throw this whole thing out that's my the architecture Professor would do this to me he's like we would do this just judgment session with him and he would look at stuff preview session and he would Mark things up and then he would turn it up in front of us throw it in the trash go do it again oh and it didn't make sense at first but like they they beat this into us so if I write a function the problem with me is that like there's no fear in me deleting it and rewriting it again a lot of programmers write this and they're like this works why are you why are you changing this I'm like well it reads better they're like yeah don't do that um so that I kind of have to be careful about like which direction I'm going in but I kind of this this helps me like you know this design thinking wants to keep redoing things so that's how it kind of end up working too like if I have pyRevit open and if I have Revit open and I'm doing something I that's why I like creating an environment like pit so much because I have that script beside me and I'm like I want to do this and then hit play I'm like that didn't work out change it again then change it again change it that iterative design right A lot of times like I can't for the life of me I can't figure out what the index in the loop is at any point in time because I'm not good that good at math so I have to like run this five different times I'm like oh it goes like beyond the boundaries it's not supposed to do that kind of stuff MH so that it that that repeating part helps a lot um the part that is almost necessary to do that is when you're creating a UI because you don't really see what you're trying to create one of the things that I really liked about working in pror with WPF was that Visual Studio had this like beautiful editor yeah oh yeah and you can put the buttons where there like you know make make the choose the right colors like border thickness that kind of stuff and make it look nice and nice and pretty I have a hard time doing it in Rhino because like we use a different um framework it's called etto and etto doesn't have a UI Builder like that is it also for the vpf this designer so the etos uh encapsulates and simplifies dealing with UI in different platforms so if you write your UI C coding etto when it's running on Windows it'll use WPF at the back end when it's running on Mac OS you use the Mac OS UI stuff when it's onux that kind of stuff so you don't have to rewrite your code there's a library that um sort of like makes it consistent across all these different um operating systems uh but that Library doesn't have like a whole other application for you to create beautiful windows with um so I kind of have to write the code and I have to build and run right now like that's doesn't look right like do it again do it again do it again which I find myself doing a lot like this iterative process still exist in my workflow these days um partly because I think they just beat that into us um as I've gotten better over time like becoming a slightly better programmer now I don't need to do that as often sometimes I surprise myself these days and I write like I spend 45 minutes writing something and then I compile it and run it and it works I'm like oh wow I didn't really need to change anything that's this is inter I've never been here before um this is the new territory yeah this is like new territory for me but that's yeah that's that I would say like thetive design approaches still exist as you're writing programs because you're really designing something and you're not going to know all the all the boundary conditions on the first try then you're going to run it then you're like you know click a button and it crashes I'm like oops I didn't think of that go back and change it do it again I can relate to that I remember when I started I pretty much did know Python and I would write like five lines of code I go and print everything I just wrote like print every variable and see okay I write five more lines print and I always was printing back and forth then I started printing less and less and also had a moment like you described like I was coding maybe for one two hours and I was like oh man I didn't print for so long I went in there printed and somehow it worked and I was like I don't know how it works I just I don't know what's going on I also had this kind OFA moment like wow actually it's possible to write code without printing every five minutes interesting yeah you start to get as you become a better programmer you start building these intuitions about like how things are supposed to work like you know intuitively at some point you know where your Loops end and where the other part of the programming starts and you know what values are at any point in time that kind of stuff you're start learning how to hold all of this in your memory um as you're programming and I think you know it's good and also print debugging is is a very valid thing it's great it works I mean in the end of the day it works it fast yeah I like it all right I can see that we have around 10 minutes left um I like to end a kind of every show with asking for advice for beginner programmers could you just give a few advices for beginners intermediates and where should they focus let's say I would say if I there's something else that I was talking to a friend of mine a while ago and I think that's that would be something that I suggest if you're interested in um in writing programming pick up Python and just learn the basics don't do anything crazy just learn how what variables are are and what Loops are and what an if statement is and what's a list and what's a you know that kind of stuff just the basics so you get an understanding of how a programming languages does the things that you're tell it to and then go find something that you want to do oh yeah I think that's the most important part like find a problem like I want to fix this mhm and then go about create a project out of that and go about um creating your application your the software that you're trying to do I think that's the best way to learn any kind of programming language because also it's very rewarding at every step of the way and you can you can make it as complicated as you want like let's say I want to say I want to design a car um by writing programs right so the first iteration is not going to be me designing a car the first iteration is going to be a a tiny long board with on four wheels four tiny Wheels that's going to be the first thing I'm like oh I got something working it moves now um and then the second in like oh I got a scooter now it's a little you know it's got a handle I can take I can tell it where to go that kind of stuff uh but that just the beauty of that iterative approach into this thing as you are getting better and as you're learning more I feel like that's just the best way to do it and it's just the Le least scary way to do it I think also M um cuz like a lot of times when you show I've done this before like I start teaching somebody Python and I show them this like giant landscape and they freak out and then I was like yeah that kind of makes sense it's fun to me because I've known that landscape for a long time so I can take somebody around and be like look at this beautiful thing look at this beautiful thing but for them it's like there's a lot of unknowns um so I think yeah that would that would be my suggestion like pick up just the basics that's the half an hour YouTube video on how python works just that and then pick something that fun that you want to do it's actually very good timing I'm actually working on Mini course for python on YouTube right now perfect but would you recommend people who are starting to kind of try to do something with py RIT right away or first take Python and try to make something you know like with python like a little website like a I would I would say I would say let I would let them decide what they what they get excited about uh and want to do that like if they if they're working in Revit every day and they they want to get excited about creating this little button that does that for them that would be that would be it or they might be be excited they have seen like web applications they're like hey I want to open an application in a browser and some stuff like that now I think whatever that gets you excited is good because at the end of the day you'll it's very rewarding you'll enjoy it you have built something and also you get to use that thing which means that you'll find problems and um you want to you want to add stuff to it later which continues this like you know search I think being excited is really important this is because many people kind of keep doing it you need this kind of spark I would say that to kind of keep it going that keeps you excited to kind of open the code editor in the first place yeah CU if you're kind of scared and you hate it well you're not going to go far but once you get to the fun level kind of this is actually really exciting yeah learning I feel like that learning and playing combination is incredibly important you can't have learning without playing and playing doesn't happen without learning as you're playing you will inherently learn something as you're finding out new things about this things um that learning and playing pair I think is very important well getting to the end mark it was really exciting to have you on the show can you tell people where can they find you where they can reach out are you do you do something that you want to share just yeah these days uh to be honest with you if you want me to respond to you quickly send me an email or find me on mcneel Forum I'm atan mcneil.com and um the My Forum handle is EAD same as everything else that I've had before so it's easy just search foran on the M Forum you'll find me there and if you shoot me a message if you DM me there if you I'll see that message a lot faster CU like I'm spending time on the Forum every day so that's you can reach me there um The Forum is actually much better than email to be honest with you because first of all I see it faster second of all you can upload samples and put videos and all that kind of stuff about the things that you're trying to do which is great if uh you think this is like super Revit specific uh we have a forum for pyRevit pyRevit forums that is structured exactly the same way as McNeil for it uses the same application backand um so they you know it's the same you don't have to learn anything new they work kind of the same and also I'm on LinkedIn if you want to find me on LinkedIn send me a message I think these are about I'm trying to stay away from like Instagram and all the other time consuming stuff so I think these are these are the good ones is there anything you want to share the projects you're working on something people should know about you um we'll share some stuff in uh upcoming in like in a in about a couple of months about Rhino 9 stuff um but what I'm working on is clean up the script editor inside of rhino 8 for Rhino 9 so we can it can run faster and with less memory use less memory and just all that kind of stuff stabilizing a little more and then also getting into Drafting and stuff in Rhino 9 so hopefully I'll I will have a part in improving Rhino drafting features for Rhino 9 which is you know a lot of fun for me uh learning how to write C++ better this time around and um also you know make something for Architects that can use right man thank you very much for coming on the show it it was huge pleasure having you especially I had to had py rivit that on the show about py rivit thank you I appreciate I appreciate all of you guys using py rivit and making tools and sharing with other people I think it's incredibly important sharing all the software software really doesn't cost um a lot to replicate um and sending these out tools to everybody else it's great I appreciate what you doing for PID a lot also like teaching people how to um write code getting excited about their own tools all that kind of stuff so thank you thank you everybody thank you everyone for watching goodbye hi real quick if you into py RIT and you want to boost your skills in record time then check learnr ai.com platform you'll find free in-depth courses for any stage of your programming Journey you'll get access to PIR with Basics Pro and modern UI courses plus you'll also get access to my code library and join my exclusive Community for pyRevit developers in the community we can chat discuss programming in Revit and most importantly you can ask for help when you need it the most if that sounds interesting go to learn rap.com to learn more
### Deploy pyRevit for Teams using CLI with Jean-Marc Couffin | pyRevit Podcast #2
https://learnrevitapi.com/podcast/py-pod-02-jean-marc-couffin/
Jean-Marc Couffin on deploying pyRevit for teams with the pyRevit CLI: how to roll out pyRevit and your own extensions to every PC. pyRevit Podcast #2.
### Create AI Assistant for Revit with Python and OpenAI | pyRevit Podcast #1
https://learnrevitapi.com/podcast/py-pod-01-openai-assistant/
Learn how to integrate OpenAI into Revit with pyRevit and Python, and build your own AI assistant, in the first episode of the pyRevit Podcast.
## Transcript
all right so welcome on the podcast I to be honest never expected to start a podcast until you kind of wrote me with this suggestion and probably people from the title and so on will already know that they here to see how to add AI assistant in Revit but before we're going to go into this part could you just share a little bit about yourself what is your background your current role and just what do you do so currently I working as assistant information manager at Arup and uh talking about my academics I have done my masters in construction project management with Bim from labor University and before that I completed my bachelor in civil engineering at symbiosis Institute of Technology it was during my undergrad where I developed my interest for construction and technology so comes very simple that I love construction it's not that uh I developed my interest or it's just kind of study to me but Construction is something which I love and I enjoy using technology to enhance the construction industry so you can say for me technology is a tool to beautify what I love mhm is it something from the childhood that you love construction or is it something you picked up later from childhood I can't say from childhood but yeah I can say from when I started understanding the buildings that's like how it is being built how like that that looks very fascinating to to me how these buildings are being built and the planning behind this building or something so that's kind of thing which I really love uh I still remember during my childhood uh when my house was being built I really enjoy going there spending time with my dad so yeah that was something which made me develop my interest in construction how did you get involved in ravit in the first place is it something you learned in the uni or at the job I started uh using ravit during my under the grad studies and uh it was not kind of uh very much I would say from the University but it was uh a self- Learning Journey for me and uh I believe self-learning is one of the most powerful thing which someone can do yes uh because like if you see uh what we are being taught we are not sure that okay this is what we are learning or something sometime we get confused or sometime that is not what uh interests us but uh self- learning is something which comes out of interest and uh it is one of the most powerful way of learning what I feel as for me mhm I see no no I totally agree with you about the self-learning I had a teacher in the University who always told us that Revit is a very intelligent software but it's going to be as smart as you are right so you have to always kind of come with the right mindset to this I got lucky with RIT I just got to UNI and they just told us like okay don't load the ravit this is what we're going to use during the uni I'm like okay whatever and so I got an easy start start is like uh for me start was not that easy I can't say how the education system in different countries but for us it was more like books and all but uh I was very lucky going to my university which was symbiosis and over there I feel they were not just focused on the books or what you learn from the books they were more focused on softwares more focused on what is going on in the world how you can adapt to those things so that way I got lucky yeah I think software is actually very important when we learn we learned so many unnecessary stuff that you come to the job and they tell you like forget everything this is how we do stuff but the software is actually the first thing you need at the job right so yeah all right and uh well where does the code come in right so you kind of start working in ravit but what motivated you to actually start coding was there any specific challenge or something in ravit that pushed you I would say this is kind of my favorite side of story and uh covid pandemic was definitely a tough time for everyone MH but uh for me it became an opportunity to focus on my personal growth because I was a interesting uh coding like I had an interes in coding how the games like as we play games or we use website kind of Google search everything we use but everyone has that small kind of going in our back of mind that what really is going behind this I never had the time to pursue it seriously but uh during Co I finally took a place that okay now I have the time and now I am going to invest my time for my learning so I would say in that uh first 6 months I completed around 50 to 60 uh kind of online courses and over there 50 to 60 yeah online courses like I was giving almost 20 18 20 hours per day on kind of my self- learning um I got free license from my uni for the corsera corsera helped me a lot and uh there I kind of uh started diving deep into coding and how it goes and uh I started with Java and I feel I still feel I'm very afraid of java because uh I I I was not able to learn Java it was kind of hard to me so then uh Professor suggested me go with python then I started with python and that took me like uh um I would say around a year to get into it and kind of say that yeah now I'm good with python all right so majority of these courses you started with Java and then you switched to python so majority of these courses were on python right uh not only on python because like I was uh some of them were on iot some of them were on Revit some of them were on different kind of things so but yeah majority of them were on Python and uh how long did it take for you to see the first results with the code because in the beginning we learned how to print how to make very simple things but when was like the first time you actually put it to use to get the result like I still remember the first day when I got that uh hello world in R print hello world so that's kind of a first stepping stone for any coder but uh for a result I would say um when I was kind of working with iot where I developed small Hardware to test the uh humidity of cement and then I took it a Next Step where I kind of developed a tool to check the moisture content and water content of concrete so over there I that day I felt okay I can work more with coding and then I started working in further then I kind of worked with the safety modules uh uh open CV and all these kind of things uh so that was was it something you did in the uni already at the job because you mentioned this iot and for people who don't know it's internet of things pretty much all the smart devices where does this come from uh this came out of Interest like it was not in my job it was not in my uni but yeah it came out of my interest two names which I still like I will mention everywhere it was uh two of my professor one was s Sor and one was Professor wnav Dair so they were kind of the professor who used to even during my covid I still remember whenever I used to text them okay I I'm interested in this bit of the project so can you help me out with this and they always helped me out and uh with that I was like okay okay let's go let's interesting yeah and then when you come to rabit and decided to put your coding skills in rabit what was the first sort of win you remember it was not just with the Revit the first thing which I developed was kind of a web based tool with speckle so when when the name sple come I would just say that it is kind of something which is going to the Future in construction so that thing I'm I'm always saying to all my colleagues and everyone that uh try to put your hands on with speckle but yeah uh with I built a web based tool with where I was fetching the data from Revit and all these kind of things but uh still there was a challenge for me that I have to like combine three softwares first Revit then take data from Revit to uh speckle and then from speckle uh to my dashboard which I built that like uh it was a kind of web- based uh tool which used to take the data from revid through sple to my dashboard it was a small dashboard where you get to check with your data we get to extract all the data from your Revit and other kind of stuff was it just for you or was it used the companywide uh it was not in company it was used uh with my team at AC Global teamwork program at Stanford University so over there I got a lot of feedback from my mentors from my colleagues how I can improve that and I kept on working on that and finally it was kind of a uh good platform to interact with the data to down download the data to filter out the data if you are not familiar with revid you can just like kind of just select the things from the drop down and you can download whatever you want to from the Revit so that was thing but uh then uh I I had a understanding of uh revid API but uh I was not able to configurate it because as you remember right now in D 2024 you can't just download the API you have to kind kind of get the API and save it in a folder uh I don't remember the exact process of that you mean like SDK to get this chm file or right right right okay so it's it was kind of a lendy process I was I was not able to install it so that's why I switched to this thing but then after my AC Global teamwork program then I thought why not I had I had time to like explore other things so I started exploring revid API and it was new to me so uh once again thank you and uh that uh your courses were like uh the first stepping stone for me to get started with Revit API oh this is amazing and how long how long ago was it I would say around 3 4 months oh you still quite fresh to RIT API yeah definitely it's just I had a good understanding of python that's why it didn't took a lot of time for me to get on it but uh yeah to start with it it was hard for me to start but I can say that I have seen almost almost all your videos on Revit API here and I still have the ebook which you provide the first video in which we have to download the ebook and uh uh that ebook I still those those days I was reading your ebook and kind of getting started with it so it helped me a lot and then I started kind of building small tools and I always enjoy when I get the result and yeah yeah this is the best part what was your first tool um First Tool uh as you said uh seat one in which we can uh we can name different seat in the RIT so that was my first Tool uh which uh which was not my tool which I just copied your code and tried it out and I was like okay this is the tool which I created and I was very happy that uh it's still like an artist yeah it feels like okay I got the tool I I have like that was the first time when I saw something what I made on the river of the Ravid so that was kind of a big thing for me okay now I'm kind of adding something to Revit adding something to construction industry but uh then uh I was like I took step back during my uh AC Global teamwork program where I had few of the challenges which I took back to my practice and I started building tools in revidi so the first tool which was kind of meaningful was um having changing the name as as per the is code changing name of the file as per the is code changing name of the family changing name of the materials as per the is code or as per the project at once and uh U making a multiple levels making uh grids and uh there were different uh kind of small tools involved in that uh yeah I think it's a good step whoever is coming to ravit API R starting with small tools is best because first of all you break the false belief people think that ah ravit Epi it's impossible it takes like years to learn this and that but once they start making small tools they're like oh I just made something I made more more more and over time you kind of get addicted in my case I got to the point where no matter what task I got in the office the first thing in my mind I was like okay how can I do it with r API it can be a very simple task that will take I know maybe half an hour manually but I'll spend like two hours no I'm going to do it with RIT AP I don't care like I need to find a way yeah and you know over time you reach the point where this skill is actually kind of finally starts to save you a lot of time you automate and was there anything that you did with RPI that wasn't possible manually or it would take you so much time that it just doesn't make any sense to do it manually um uh that was about uh kind of naming the uh families and all these things because if uh generally in a big project we have multiple families we are using we have multiple seats we have multiple kind of U materials building materials and everything so it takes hours and hours to name them but uh with this uh like I was able to name all of them in a go like in just one click I have to like uh set the standards okay this this is going to be prefix this is going to be suffix this is going to be the project name this is going to be this this this and this and so one click you can get the uh changes you can see the changes so that is one thing which I feel was a lot of time saving apart from the chat integration and what motivated you finally at chpt to ravit was there any specific problem you tried to solve or was it just kind of for fun you want to take AI put in rate and see what happens uh it was kind of a mixed approach because whenever because right now in this era I feel if you don't use AI if you don't use uh chpt you are lacking behind a bit so whenever I was building something or whenever I'm doing something so it took me time to go on Google or go on ChatGPT and search for those things and get back to Revit and then make that thing so that used to take time so that was the first kind of approach for me to get ChatGPT get AI in Revit and the second thing was whenever you you were working in Revit you have a lot of data like in construction the main thing is the size of data it's a big size of data the data size is huge and uh um over there I felt uh that if we can like uh import our PDF or these kind of documents and then we can chat with them right now we have multiple uh yeah softwares you can even upload your document to uh ChatGPT and kind of ask questions around them so that thing was one of my motivation to integrate ChatGPT because that was my uh second add-on to Revit in which you can chat with the data you have in RIT like whatever you are building you can chat with that okay what is the total area of uh I I'll show you when we jump on to the uh demo phase so that is something like uh you can literally have a interaction with the revid how many columns are there how many beams what is the maximum length of the column so that kind of thing so you wanted to make it like context aware inside of RIT instead of saying like hey I have a big project it's highrise and like describe all everything with text they just can see the database right right yeah yeah ex exactly because in the end of the day rabit project is just a database of elements where all the information stored and so on it can be tricky to get everything out like in a concise manner but I think with AI that actually can be a lot easier than would be otherwise uh do you want to just jump into demonstration show show us what you got okay and then we can talk about this okay so uh this is kind of my first uh R reading as as I just said that uh kind of create add levels add volume total length total volume download the data from Revit download selected data and these kind of things so this was the first add-on which I developed and uh coming to the integration so as this is the F uh this is the kind of integration where uh ask Revit is a platform where you can just talk with yeah it's kind of a small ChatGPT in Revit and model mind was the platform where you can interact with the data in the revid so these both are kind of the I for now I've just separated them so that uh um we can like so that I have a clear understanding what I need to add more to this but yeah these both can be integrated and this is the the link to my Bim platform which the web based tool which is hosted with streamlit so here you can see it's kind of uh with speckle token you can uh get this speckle token and then interact with extract all the data whatever data you want to uh chat with or these kind of things and uh the main thing which made me use uh uh open a with the Revit was this platform where you can upload the document with where you can kind of uh uh once you have the data set from revid or other kind of U documents you can just upload it here and chat with the uh chat with the data set ah so you create like knowledge base inside of this stream lead and then connected to chat gbt right right does it use the latest uh open a models like this 4 what is it 01 40 uh this is 3.5 3.5 okay so it's a bit older yeah so this is using 3.5 and uh then you have view model you can view the model over here then you have some kind of uh uh all right so you go to Revit you're going to export all your projects to speckle and then with the stream L you can access all the data via the speckle and you can chat about it what's going on where it is and how exactly so here if you go to right if you select the model you can so the stream is different uploads is it different projects different projects and here you can kind of check the model you can go deep inside the model you can select different elements and uh and if I remember correctly when you view this model this is not an IFC this is kind of built up by speckle database right this a separate thing yeah separate thing this is coming from uh speckle mhm so you can check what it is and kind of other things and then you have the okay yeah the chat page is also kind of similar thing but here I Ed to like as I am extracting the data from uh revid API which is kind of more easy now uh so this is also kind of same thing I'll just run through this yeah so then you can select whatever subcategory you want to export from and then you can select the parameters like if I just want to select category Sport AS glow manufacturer Mark whatever it is and then you run MH so takes a bit of yeah so here the that data you can download it as CSV all this kind of thing and then again uh over here also I integrated ChatGPT where you can uh again interact with the data set like uh what is the uh maximum use material or who is uh which who is the manufacturer of this uh uh particular material all these kind of things so uh is this query only based on your filters right now because you said the that you want to see category so first you select all the parameters and then you can chat about whatever is shown up in this little database this table so yeah this this was kind of the thing and then if we go back before we going to go further can you just give us a little explain what what is a stream lead for people CU I knew a little bit about it but I'm also very new to this so stream L is kind of uh a python uh framework in which uh you have predefined frontend uh materials so uh you have predefined kind of pages you have predefined boxes uh if you can go to build the same page with HTML or css and um you have different other languages so that takes a lot of time to Define each of the boxes but with streamlit you can directly uh import different boxes you can import the page you can import the kind of pre-made it I would say in a normal term it's kind of a pre-build template from where you can kind of uh export different things export different materials and uh uh you can make a page so yeah this all all these things are um developed by the stream L which is kind of know it's very easy uh and also it has a uh it has separate template to integrate the open open AI with the python so that makes it more easy and kind of General overview if somebody is watching this right now and they think oh I want to build something like this could you just kind of uh break it into steps okay first they go to the stream L they probably make an account and what are the steps this kind of general ones just kind of being the picture of the how complicated it is so so I would say if you know python then it's literally uh nothing you just need to go to the documentation read kind of uh what what kind of box you want to import or what kind of um parameter you want to import what kind of background do you want so you can just uh go and read the documentation and then you uh come back to the python you import uh stream lit and then you start with it um but to host then uh when it comes to the hosting part because right now as you can see it's kind of bit slow it's because uh it's a free hosting on stream lit so once you want to host it once you are done with everything then you just go upload the project on uh GitHub and then you can uh create account on uh stream lit and you uh you connect both uh stream late and uh your uh GitHub page so once you connected then you can directly select the name of the project name of the page and then uh and then uh it takes like 5 to 10 minutes to get everything uh started so once everything started then you can then uh you're ready to host it but yeah while developing also you have uh G you have the general kind of how you develop on HTML CSS you have a general preview you can uh keep on previewing you can keep on checking what's going on and that way you can you have your page ready so uh with stream lit I would say it takes like less than an hour to kind of build these kind of pages and also now you have chat JP and other kind of stuff so with that you it takes less than an hour to properly have these Pages yeah perfect and do you know about the Privacy when you use for example this projects that you created how private is your data regarding like what you take from Revit is that somehow uh open to the stream lead or uh it's not open to stream lead or it's not open to uh even speckle because you have uh for the security I feel you have the speckle token if you are uh if you have not shed your uh speckle token then no one is going to see your speckle token and about the second part which I really liked about uh stream L when was when I was uploading my project and uh by mistake I left uh one of the speckle token which I was using for the testing phase I left it over there only so they uh stopped the kind of uh hosting and they asked me to change that part of the code so that thing I yeah that thing I really liked about yeah that that that is one of the best thing about uh stream Le that you can they literally pop up if there's something wrong going on in your project there's a funny thing about the tokens on the GitHub when people were testing ChatGPT they were just putting something like I don't know open AI key and then uh and then AI an auto suggestion for somebody's keys from the GitHub cuz AI was trained on it and I saw like oh somebody used this one as the kind of continuation to what you wrote so maybe you want to use this token and some people like found it really funny that that's that's a lot of problem like uh but now even on GitHub if you're sing the your open a key or some some key then they give you a popup that you sing your personal information so do you want to continue or I think they learned their lesson yeah so now it's it's kind of fine but yeah every time technology uh has some kind of backfires but that gets good with the time so that's what I feel all right so now we're going finally to the assistant okay so this is the this is just the kind of uh page where you can if I just want to right show some magic uh if I just this is uh same this is a smaller version of CH GPT if I just want to ask so what is the maximum height of the door as per Indian standards yeah so as you can see as for the National Building Code it's giving a kind of mhm so it kind of pulls up whatever it finds in the database yeah so this basically Works kind of uh in a way I can say that uh I I I will definitely show it in the code also kind of overview that how it takes the uh command how it takes the query from the Revit and then it takes to the to Python 3 where I have kept my ChatGPT and then it uses a subprocessor to connect python 2 and Python 3 so that's also kind of something which I would like to highlight further in the yeah we're going to go into this NE and grey stuff a bit later yeah but for now can you kind of communicate with chpt about your model if you're going to ask how many columns you have and so on so this was the as Rev which uh was a small CH GPT and again the Mind model which is uh ah okay so of keeps leveling up yeah see yeah so the previous one was just regular ChatGPT right it's similar to what you speak online version like hey how are you doing exactly give me some code whatever it gives you this and this is already with integration into ravit yeah so if I kind of ask how many structural elements are in the model 1989 structure elements in the model all right so how many columns are there so there are total one 2 39 structural columns in the model and was this one how precise is it did you test cuz when you ask it let's say that it's 1,200 pretty nice columns it is kind of I would say I'm kind of 100% sure because I have tested with the download selected function in this uh like where I used to I have downloaded the number of columns and then I have rechecked them how many columns are there okay so you verifi the data to make sure it's correct right right right definitely because with AI for some reason even though it's so smart and amazing in many features it's not so great at counting things somehow definitely can you ask it to categorize the structural elements I just wonder what what kind of results you're going to get I can try just a thing in here we can just try to make a bit more examples just to show people what's possible so how many types of columns are there in the model there total of that is kind of bit off answer I don't know why um but let [Music] me uh don't worry we all been there when we ask a question and it just goes completely different yeah okay so pretty much it's too lazy to do it it tells you to do it for it yeah because uh I feel uh uh for this you need a proper model also I'm not sure about the model uh kind of how perfect the model is because uh I just had this model for the testing phase so I'm not sure how perfect the model is but uh yeah um there there are few of the these kind of complications in the um in this kind of things but uh um this will take time to improvise because this needs a lot of tasting and then you need to go go for that uh so yeah this this is also one kind of example which is there for the technology that uh why the training needs to be done with the um why why we need to provide some training to the uh to AI so yeah this is one of the example which is definitely yeah no no that's fine I just wonder can I show us some more examples I just just something different how you use it okay um I just wonder how much can you get out of it because you brought the charger P to RIT it really sounds amazing but I just wonder what are the real use cases okay let me no pressure uh I'm also I have not tested it like uh in so depth but we can try like uh so what are the differ different types of walls used in the model yeah all right so okay based on the data so what's the maximum wave of the walls this was uh answered in the video which I uploaded on the uh LinkedIn mhm but I don't know why it is so now it doesn't want to just try it again so what's the maximum wave now it's the wall in the model so now it's giving correct and same question it didn't answer over here mhm so yeah I think it needs to be very very descriptive right so it just what's the maximum W of the wall it doesn't think about your model first of all it just thinks like well maybe in the world um there's one more thing which I feel uh is there that uh um if if we talk about the natural language processing then it it needs to be bit particular at this point of time uh and with ChatGPT it goes like takes multiple synonyms with the uh with the same word so that might also be a kind of uh uh point where it needs a bit of work but I feel there but I feel yeah I feel there there are multiple Works which we need to do because uh if you see in Revit we don't uh we generally uh describe that height and some places we uh say same thing as width so for those kind of things we need to train the model we need to fine tune the model okay if these kind of words come then this is going to be what it means as per the data set because uh at the end of the day it is going it is taking the uh data from the data set like it is taking the data from the revid data set so we need to kind of bit uh do the fine tuning of the model so yeah that is something which I feel is still there we need to perform I think it's still quite amazing that you already brought open AI into ravit it certainly opens a lot of ideas everyone watching here now sitting there like I could use it for this or for that that's quite cool can it execute any code or is it only for kind of communicating about the data right now uh like I said if you like write something like can you create a wall can it execute something in your models uh no I have not given that here yeah this see uh that's uh a good idea I thought about it but uh uh as as I've seen in some of your videos also that uh about the creation but uh I feel that creating uh something is not what capability we need to give it to AI because uh uh that again comes up with the imagination what you have and if we just give um a line that okay I need to create this wall and this the kind of things then still uh we are losing a point where we need to give our imagination we need to get our imagination to work so that's why I feel that that is something which for something like creating that's right but I'm moment like for example let's say that you write okay find me these kind of walls with these parameters and change the comments parameter right it's just about the ability to let it make changes in the model based on the input yeah that can be definitely done yeah yeah so many people done it the that beam girl recently made also a video describing how they did it in C think hers could make changes if I remember it correctly uh the the main thing is uh right now uh once you get to have your kind of uh your uh language to the model then you just need to add those to the uh creation tools so I think I think uh that's uh I have not seen what you're talking about but uh that that could definitely be a good thing I'll definitely have a look to that but yeah uh I have not tried that yet uh she just posted it recently I haven't watched the full video myself but I saw uh just the idea that okay this works that's that's the thing that's that's what I feel that uh slowly it is going to come into play because uh uh right now everyone is just working their little bit their bit on different kinds of project but uh uh I feel once if we all get in a get get at a place to work on something then I think it's going to be possible for us to kind of get what we want mhm mhm because as as you see in uh right now as you see on GitHub as you see on other kind of places that different different people collab rate in building a game or some kind of website or something like that but we still need in construction industry we still need a platform where we can collaborate with people like us to okay let's let's collaborate and build something like this let's uh we can set our ideas and then we can um build something which I feel is uh one of the next step which is important in construction and definitely I I I'm going to start kind of soon with that kind of thing becoming more and more open source people are willing more to share because back like five 10 years years ago people were holding a lot on what their Creations they didn't I think let it out as much as today today people kind to normalize more the open AI even like companies like meta they spend like huge Millions on training all this AI models and they they just tell like here do whatever right all this llama 7 billion what is it 30 million 400 billion all these crazy models just for free and yeah this is great direction we're going but but definitely there's one thing which is stopping it in the construction industry because construction industry is all about how secure your data is no one wants to uh share their data set no one wants to share their plan no one wants to like these kind of things so that's uh one thing which is taking us a step back in the evolving Technologies yeah for sure all right and uh could you also tell us how your this kind of AI system actually works where does p rate come in open AI integration like just we can start with a general overview of all the steps that go in and then we can dive deeper in the code if you're okay with that yeah I'm definitely fine I'm I'm definitely going to send you the uh code and then you can kind of make a proper video to work with it I'll just share my screen the main thing which uh I'll mainly try to talk about in this is how I have inte created like python 2 and python three with the use of sub process uh subprocessor so as you can see I have kind of given a path to the Python 3 which is uh uh in different folder uh again I have created a virtual environment for that uh Python 3 and uh this is the path for the code where my server for the python uh for openi is working so here is so this is the python free script right okay yeah so here I this is kind of just a normal uh UT of uh normal execution of the code for uh python server we have just taken the open API key and then I have made a function for the ask question function where it takes the question as the input and then um I've used GPT uh 3.5 turbo and these are kind of the maximum token and then uh how much does it cost to run like a question or 3.5 is it free or this is kind of I would say almost free it's so that's why I'm using 3.5 because it's like penis right yeah um because we don't have that much of d u data right now and I was in the testing testing phase so that's why I have like used 3.5 but yeah definitely you can go with gp4 or anyone anything you have once you have created all the model then have just kind of uh made a function as you have seen that uh the we are not getting the answer for some of these things these are this is for the a handling and coming back to uh the code here I'm just like taking the uh this is code for the model extraction here I have extracted that data from the model and then uh with uh that data is again sent to GPT where um we have been interacting with the model and for GPT sorry so GPT only is aware about this data that you provided if you're going to go back just where we were right now it's just aware of these so you only provide this kind of ID category name area it doesn't know anything else about materials it cannot kind of look into them I have I have one more file I will try to find that in that I have uh imported all the other materials but right now I have given the material ID which I felt like for the testing phase was enough so but yeah definitely we can work with uh so kind of manually getting kind of all the things yeah but yeah yeah we can definitely go with other IDs other materials and there's a basically a as we know there's a pick uh list of the data we can get from thej GPT so once we get the data then we data is sent and again we are taking the um questions from there and uh here I have uh kind of given the um like as I said I not very much sure about this part um this is kind of integration with the front end and the back end like here is the front end part yeah so this is the front end part so this was the part where we were talking we were interacting with the model and uh taking into a sorter version this is uh the same kind of thing but uh here you just I just have uh used this used the kind of uh a bridge to connect the uh ChatGPT which is again here which is running on Python 3 and uh this is on IronPython so yeah this is uh I I think uh this is uh one thing which uh Ravid API developers must need to think that they need to get on Python 3 because right now I don't feel everyone is very much comfortable with python IronPython because that is something which was used like 10 12 years back so yeah this is this is something which definitely um uh the iron Pon needs to think yeah I think it's on the road map to implement kind of there is IronPython 3.4.4 version It's it's not supported by pirate yet but maybe that would be able to support some of it I don't know uh no I I think in that also uh some of the library doesn't work yeah yeah true I think panda panda also doesn't work with uh that so I mean you can make it work with CPython but it limits a lot of things lot of for like vpf examl it stops working because you go to with CPython and it needs IronPython and that's a big big Topic in the Community people really want to use napai pandas maybe I don't know some other libraries I tested a little bit for me I did not need pandas as much so I was like I was quite lucky I didn't need to dive into but I just dived once for the community to show okay this is how CPython works but it tells you maybe in 10 different places that it's not as stable yet in py RIT and hopefully in the future it kind of becomes more stable but I think it needs kind of more support from the community in terms of like kind of donations and stuff to actually hire developers to make it happen but uh what I feel is like uh with the subprocessor I think we can use all these kind of things because uh we are just getting we are kind of doing the same stuff in Python 3 but we are just bringing those data to uh CPython so uh this is something which processor seems much safer much more stable option right the only thing is if you share it kind of worldwide it might be tricky because you need need to kind of ship the python engine as well right that's tricky part but that's probably something for pirate team maybe to implement in the future that's also a challenge that once I go for kind of making it public or going to deploy it then it's going to be a challenge for me I was trying to do that but um it's going to take some time to deploy it because there you have to again build two different servers so yeah that's that's definitely a challenge with sub processor but I feel that's more easy more safe and uh gives more opportunity to the developers to work with that listen if somebody wants to kind of adapt this code that youve just showed for their own projects what are the first steps that you would recommend where should they focus more right um for this I I first first thing I would say is like having a basic understanding of python like what is function what is uh how to import libraries how to uh like use different kinds of uh inbuild function how to make function so these these kind of things is the basic thing which anyone wants needs to have and uh the second thing which I will say to everyone don't be like uh if the code is not running don't be like oh my God I have wasted my three months on learning coding and now my code is not work working that's never never a thing it it's part of the journey it's part of Journey and right now we have ai we have ch GPD we have G we have multiple things at at my point of time and I was like learning uh the error which I used to have then I have to go to stack Overflow then I have to go like like different kinds of platform to read all those and it took like it it used to take days to solve one small error but now you have these kind you just need to give the error you just need to give the code and then you can get the solution so just keep on working on the the small things just even if you even as I said that hello world makes a big difference so just keep on doing like Hello World next your name next day something else so keep on doing a little bit don't be like in a r to uh do everything in a day give it a slow uh run and I think it's it's going to be easy and for this code I I feel I'm going to uh give you the GitHub link where uh people can use that I'm going to share it with everybody yeah so uh I think that that will also help with them and also I will share you the GitHub link for the chatboard if someone wants to explore the Stream late and uh that would be great speckle thing with uh um if someone wants to build a dashboard so yeah I'm definitely going to share both of this but uh MH uh for and you are there and you also I also I think uh you must remember I gave you a gave you a question in the chat that I I'm trying to use uh Python 3 with python 2 so how can I do that so uh uh you are there if someone wants to contact me I'm definitely there I'm I'm also working with some of the people who contacted me with link with link I'm going to leave a links to you somewhere in description you can mention now or in the end it doesn't matter yeah but definitely you are there so I think your videos are much more self-explained I don't think they will need much of me but uh yeah if in future someone needs that yeah it's it's still too good to chat with you what's what was your journey and before we going to go further I also want to talk about this um what you said earlier that nowadays people learn with chbt and it's so much easier because I L remember like when I started we had no chpt and I was new to ravit API I literally spent like a couple days on a very stupid like question mistake a literally like lots of evenings I read all the forums videos finally I found it and it was maybe one line of code I was literally struggling for days for one line of code which is now I look at it I'm like oh my God now now we can even go to like different forms now people more open to sharing now it's much easier back then it was not as fun as today just want to like encourage a few people to actually kind of trust the process that's definitely a thing have you had any challenges while you were building these kind of AI chat Bots a lot all right any advice is how to avoid them uh I will say don't avoid your challenges don't avoid uh uh these challenges because these challenges will give you uh a a number of ways how you can CH how how you can like change working on that because if I give you a solution that sometime may not work but to find the solution by your own for that challenge uh you will find multiple ways uh which can be very beneficial to you and in that journey of finding the solution sometime you learn many more things of how these things can be done uh but definitely uh one advice which I would give is like uh if you're just starting with py don't go for something big start with small things start with small tools start start with the kind of uh what you see start building that by your own start uh adding your own uh logic to the code so start doing that and then slowly uh go for the next step and if you're just starting use chat GPD but don't just rely on that because you need to have the basic understanding even if you want to build something big you can use GP to build whatever you want to but that understanding needs to be there this is a really good advice and I definitely guilty of doing that myself when I started I made my like first maybe two three very simple scripts and then the next one I decided all right you know what I'm going to make something like Pro sheets I don't know anything about like how to make custom uis I don't know how to make PDFs I don't know I pretty much barely know anything about like coding in general and I was like okay I'm going to like make this crazy Big Tool I spent like I don't know so maybe like a week on doing this and then I realized what am I even doing I don't know half of what I'm just doing it because there's like there errors on all fronts like UI back backend front end like everywhere then I kind of dialed it down started also doing like you you mentioned like all the simple tools and this is what also builds up your confidence and you just keep keep doing doing then at certain point you're like okay I want to challenge myself I'm going to go next level and see if I can get there and like the next level and then over time you realize like oh the way you kind of get to here is just kind of step by step not like take like an elevator all the way up there definitely as as I just showed you uh in just one uh um this add in where I just started with the normal integration of ChatGPT and Revit like where I can just interact with ChatGPT and then in the next add in I integrated the data set so definitely go slow take take step by step like don't be in a r that's the first thing which I always say because we are not uh in kind of proper uh coding job we are not uh we have not studied um the computer science or something like that a IML so we have to kind of keep on learning and then using that thing so it will take time but uh once you start working on that once you have that uh confidence to start with it then there's a lot of things in coming for you yeah definitely even people who go and study computer science I still hear from them that the best way to can actually learn something is actually start doing it's great that you go to this kind of lesson hear how computers work code and all exercises definitely gives an edge but in the end of the day even they say like okay you need to start your own personal project you need to start your own kind of things it's like this is how you learn in general you get mistakes you solve them you move to the next ones and repeat definitely personal projects are some one of the biggest thing for learning mhm you can't just keep on doing the courses or you can't just go to UNI or something like that that's not going to give you a lot until you keep on doing small projects keep that that also challenges your thinking because uh uh actually the days when I was stuck like I I didn't had any anything to do like I was B struggling what new to do what new because I'm someone who keeps on trying to find something which I can keep on doing I can keep on doing so sometime you struggle you don't you will not you will not have a lot of things to start with give it a time give it a go then you will start you'll start getting something read some of the documentation forums and all these kind of saying slowly you will get something what you need to start with but yeah definitely give it a time don't be in a rust that's the only thing I always say to my colleagues also don't be in AUST give it a Time mhm if you get stuck leave it for some time give your yourself some time and then you will have something big oh yeah best best ideas come in shower right yeah all right no this is good and just in general where do you see this AI going like how does it influence the future of ravit and beam in general do you have any opinions on that uh about the normal AI I would say I I'm a big fan of Elon Musk so I'm definitely going to agree with his point that AI is one of the big most dangerous thing if we don't do it like if we don't take care of that it's one of the biggest uh danger to us but uh yeah if we use it properly then it is it is one of the biggest thing what we have right now and the second thing which again I I will say uh in today's generation if you are not if you're just using AI you are ahead of many people but if you start developing with AI then you are ahead of many many many peoples so start not just start using it start developing something with it so that's the most important thing right now mhm that's a good advice cuz everybody keeps hearing this quote like oh yeah he's not going to replace it but people using AI is going to replace us but now there's also the next step people who actually develop with AI they're going to replace exactly exactly yeah there's always this kind of next level where we go now this is a good thing right now you see there there I don't remember some of the website name but there are some of the website which made the work of uh the architect a lot easy where you can just add the images of uh from your Revit you can add the images uh which you want to vender and then you can give some of the examples of how you want it to be like the ver I think ver say I know made something like this I don't know I think V sayi I don't I also don't remember the name but yeah there there are some of the softwares which are there some of the webites where it takes like a minute or two to render the whole of the uh thing what you want to render and which generally take like 3 4 hours a good laptop a good uh PC to rer it yeah yeah definitely yeah it's called Vos I just quickly looked it up just to make sure so it's ver by evolve lab this was pretty cool because it just takes the general shape of what you see in the screen and it makes all this AI images based on that this is cool one I I will definitely say uh collaboration is something what we need in the construction industry right now we need a platform where we can collaborate it's not about uh where as as we have different platform for other kind of Department other kind of things but for us we definitely need that one platform where we can collaborate and then we will have we'll definitely have some big things coming up in the future all right and I have also I guess one last question what is number one advice that you would give to somebody new to coding for example to yourself right after you wrote that print hell World um I think I will say is like never let that spark go from you always keep that spark that I I never lose my control over myself that if if I've not done this that like I'm not able to develop this it's sing so much I'm I'm literally saying you I literally spent four five days to just go of one small error give it a time don't be in a r that okay I have to do this in a in a day or two don't be in a r and don't go for big things in very first month or very second month give it your time give it a time it will take some time but uh with time it will definitely give big results but don't be in a Russ and don't start with big things start small then you you will get what you want okay goes back to this kind of start small and kind of one step at a time yeah no no this is really good one all right and just for people watching us can you also tell them where they can follow you where they can find your work what you're up to just kind of share your socials where you active uh I'm mainly active on LinkedIn uh for my like work right yeah yeah yeah I'm going to write it somewhere in the screen so I'm I'm active there um if there is something which I can help with I'm definitely open for that any anytime you can come up to me and I'll try to help however I can so yeah amazing So yeah thank you very much for coming here today this was really amazing and just that you decided to come here and share all of that because in the beginning I saw your post it was like huge post like message in LinkedIn you wrote like hey Erik and then I was like I want to share this code I want to send it to you and so on and I decided a man I actually got to bring you for the podcast also didn't expect to start a podcast so you are the first guest out of nowhere so this is also new to me so thank you for pushing me to do this as well no I the main thing is I was uh I never I'm very kind of camera side person I don't want to uh speak in front of the camera so that's one thing why I was like I'll just say the code and because I feel uh mhm we just want we just need to give what we got from somewhere so I got a lot from YouTube I got a lot from creators like you so now just feel like whatever I have I can give I can pass on to people who wants to start it in future so yeah that that's is one thing which I always feel doing yeah yeah that's amazing that's pretty much why I started doing what I do I also all right not not enough people sharing it so maybe I can start sharing and one thing after another you know maybe you're going to be the next YouTuber something no but I think R Community will absolutely love this and huge thanks as well again for coming here pushing me in to this podcast thank thank you for having me here and uh thank you very much that was amazing thank you
## Code samples
### Simple pyRevit Script Template
https://learnrevitapi.com/resources/code-samples/pyrevit-template/
(free with an account)
### Filtered Element Collector
https://learnrevitapi.com/resources/code-samples/filtered-element-collector/
(free with an account)
### Revit API Parameters
https://learnrevitapi.com/resources/code-samples/parameters/
(free with an account)
### Revit API Selection
https://learnrevitapi.com/resources/code-samples/selection/
(free with an account)
### Revit API Transactions
https://learnrevitapi.com/resources/code-samples/transactions/
(free with an account)
### Translate C# to Python
https://learnrevitapi.com/resources/code-samples/translate-c-sharp/
(free with an account)
### Views & Sheets
https://learnrevitapi.com/resources/code-samples/view-sheets/
(free with an account)
### Create Elements
https://learnrevitapi.com/resources/code-samples/create-elements/
(free with an account)
### WPF Form Sample
https://learnrevitapi.com/resources/code-samples/wpf/
(free with an account)
## Guides
### pyRevit MCP Guide: Connect AI to Revit
https://learnrevitapi.com/guides/pyrevit-mcp/llms.txt
Set up the pyRevit MCP server step by step so your AI agent, Claude or Codex, can control Revit with prompts. Free guide with setup and troubleshooting.
## News
### 🚧BIM Managers: Here Are 4 Ways to Control AI Assistant Access in Revit.
https://learnrevitapi.com/newsletter/block-ai-assistant/
***Based on LinkedIn Data:***
**~75% of Revit Users would not trust AI Assistant** **on a real project.** And that's a valid concern...
But by default we can't even disable or control who can use AI Assistant. (*Thanks Autodesk for creating BIM Manager's Nighmare...)*
But don't worry, I'll share with you **how to setup custom Access control for AI Assistant** to protect with:
- Password
- Username Groups
- or Project Name Groups
Overall it's not complicated and I'll provide you all the code with explanations. So let's block AI in Revit.
[youtube HSp2DumX34Y](https://www.youtube.com/watch?v=HSp2DumX34Y)
## Overview
**So, how are we going to do it?**
1. Firstly, we could delete .addin file and AI Assistant would never load.

This is the least robust option. Addin will come back with any update and maybe some users should keep access to AI. So let's not do that...
2. Instead, we can setup **EventTrigger** and disable AI Assistant access. Users will haove to provide correct password or belong to trusted user group.
ANd to make it - pyRevit is the simplest way.
## Setup pyRevit Hooks
**EventTriggers **are called **hooks **in pyRevit. And it's already made very simple to do.
We just need to create **📁hooks folder** inside **.extension** and then create a python file with correct name so it executed on certain events. You can check [pyrevit-hooks table](https://pyrevitlabs.notion.site/Extension-Hooks-b771ecf65f6a45fe87ae12beab2a73a6).
In our case we need to create file called:
command-before-exec[ID_TOGGLE_AUTODESK_ASSISTANT].py
This will be a hook executed whenever users try to toggle Autodesk Assistant in Revit.
Inside this file, write this base:

Now you need to select one of the option on how you want to restrict AI Assistant:
1. Password protect
2. Username groups protect
3. Project Name protect
Scroll down and choose correct snippet.
*You can also mix and match if you want more control.*
## 1. Password Protect
Only users with a password can use AI.
But password can be shared...

**NB! **Make sure to hide password outside of script.py
## 2. Username Protect
Let's go a step further and ensure only allowed users can use AI based on username. This gives you more control.

## 3. Project Name Protect
Alternatively, you can lock access by Project Name.
This is a good option to block AI Assistant on real projects, while letting users to test it on demo projects.

## NB! We're not done!
So far, we're blocking AI Assistant toggle button. But AI window can open up automatically when you open first Revit project.
So we need to close to avoid users using it with another EventTrigger. But this time we have to set it up manually without hooks.
For that create a startup.py file in root folder of your extension.
📁ExtensionName.extension
∟📄**startup.py**
The code inside startup.py will execute everytime people with your extension start Revit. Inside we'll do the following:

This is actually a native way to subscribe to Revit API events because we need to do that when Revit just opens up.
**Code Breakdown:**
1. Code executed when Revit Starts
2. Works only for Revit 2027+
3. We're defining event handler to close AI Assistant window
4. We're subscribing to **DocumentOpenedEvent**
5. We're unsubscribing from event after first use.
## Now you can sleep tight
That's it. You just made your custom AI Assistant blocker that will work for anyone who has pyRevit Extension installed.
You can even push it further and add some logging, or more rules. But that's up to you.
Thanks to [**Tay Othman**](https://www.linkedin.com/in/tayothman/) for preparing the base extension.
## P.S.
If you want to learn pyRevit, I have **pyRevit Challenge #2** coming up soon.
You'll build 21 custom tools and learn everything by doing. No theory. From day one you'll start creating tools using my 7-Step process for beginners.
Here's what Sonu George shared:

I'll share more details soonaaa.
### ✨Guide on Creating Elements With Revit API - (Place Hundreds With a Click)
https://learnrevitapi.com/newsletter/guide-on-creating-elements-with-revit-api-place-hundreds-with-a-click/
It's time to talk about exciting part in Revit API: Creating Elements.
At first it might be a bit confusing because there are multiple places to look inside documentation to find the right methods and then you need to choose the right overload...
But it's a very important topic to understand to automate element placement.
So, Shall we?

## Find the Right method
As usual - let's begin with documentation.
To create elements in Revit API we can find methods in 2 places:
- Class of element itself (e.g. [Wall.Create()](https://rvtdocs.com/2024/4a42066c-bc44-0f99-566c-4e8327bc3bfa/))
- Document from Creation namespace. (e.g. [doc.Create.NewRoom()](https://rvtdocs.com/2024/28262c8c-d18a-338c-eb17-f406438949d8))
> **TIP** 💡 Notice that we need Document class from Creation namespace, not DB.
And to use methods from DB (Creation Namespace) we need to write `doc.Create.MethodName()` instead of `doc.MethodName()`. Might be confusing, but that's the design pattern developers choose to better separate methods.
In practice to find the right method: First of all go to the Class of element and look for Create method. If you can't find it, it might be inside Document and named something like [NewRoom](https://rvtdocs.com/2024/28262c8c-d18a-338c-eb17-f406438949d8), [NewFamilyInstance](https://rvtdocs.com/2024/4a037d33-8251-2a50-5470-c98320e2faff/)...
## Overload Methods
Once you find the right method, you will often see Overload list. This means that there are multiple ways of using this method by providing different arguments.
This actually makes sense. Because you might need to create Point-Based or Line-Based family, so inputs will be different.
Or you might want to create element with default values (less arguments) or provide full list of arguments. It all depends on how much control you need.

## How to Choose the Right Method?
Read descriptions to better understand the difference between various methods. It tells you in human language what it is for.
However, I tend to look at the arguments so I can quicker find methods that suit my needs.
For Example: If I'm creating a point-based family, then I look for methods with XYZ argument which represents the point location. If I'm creating a line-based family, then I'd want a method with Line argument. And so on...
Also think if it's a View Dependant or Level Dependant element and so on...

It can be tricky at first, but just know that if you provided all arguments and you still don't see new element, then maybe it's worth to try another method before giving up.
It can be confusing but you'll get better with practice.
## Example: Create Wall
Now let's practice. There are too many options, so I'll focus on the basics.
For example to create a wall go to [Wall Class](https://rvtdocs.com/2024/b5891733-c602-12df-beab-da414b58d608) and check if there is a [Create](https://rvtdocs.com/2024/3ef7e31c-b41b-c8cc-2713-8f098954613d) method. And luckily, you'll find a list of Create methods there.

Now, read descriptions and select the method that works best for you. I tend to use the one with default values(2nd from top), or where you need to provide the most arguments(last one) if I know the height and other stuff.
Now use it like any other method. Prepare arguments and create a new wall:
```python
# Wall.Create with default values
#📦 Create Wall Arguments
doc = __revit__.UIDocument.Document
level = doc.ActiveLevel
pt_start = XYZ(0,0,0)
pt_end = XYZ(10,10,0)
line = Line.CreateBound(pt_start, pt_end)
# Create New Wall (Don't forget Transaction!)
new_wall = Wall.Create(doc, line, level.Id, True)
```
in case you wanted to use another method and provide more arguments, then here's how we'd use another method:
```python
# Wall.Create with the full argument list
#📦 Create Wall Arguments
doc = __revit__.UIDocument.Document
level = doc.ActiveLevel
pt_start = XYZ(0,0,0)
pt_end = XYZ(10,10,0)
line = Line.CreateBound(pt_start, pt_end)
height = 15
offset = 3
flip = True
structural = False
# Create New Wall (Don't forget Transaction!)
new_wall = Wall.Create(doc, line, level.Id, height, offset, flip, structural)
```
In a nutshell, you need to find the right method and then it's about providing the right values in arguments.
> **TIP** 💡 If something is confusing, check Remarks section in documentation. It can be helpful on tricky elements.
## Example: NewFamilyInstance
Let's look at another example - NewFamilyInstance().
This is how you create instances of any loadable family, and the trickiest part of using it is to select the right one out of 12 options...

There are quite a few things to consider:
- Point-Based, Line-Based, Host-Based, Face-Based?
- View Dependant or 3D?
Then you can visually go over the list and filter options that do not suit your requirements. Usually this will shorten the list down.
View-Based?

Point-Based + Level-Based?

You get an idea...
> **TIP** 💡 And don't forget to read Remarks.
Then it's about using the method. I'll use [this one](https://rvtdocs.com/2024/5cc3f69b-7782-8e4c-2b4e-4fe4495217ae/) for the example to create a simple point-based family with Level.
Here's Syntax:
```csharp
# NewFamilyInstance signature, from the documentation
public FamilyInstance NewFamilyInstance(
XYZ location,
FamilySymbol symbol,
Level level,
StructuralType structuralType
)
```
> **TIP** 💡 FamilySymbol - is a class for Family Types of Loadable Families. It's a weird name, but that's because Type has different meaning in programming so they chose this instead...
Now, let's create an element!
```python
# Placing a loadable family instance
from Autodesk.Revit.DB.Structure import StructuralType
# Get Car Symbol (FamilySymbol is a Type of loadable family)
all_symbols = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
car_symbols = [symbol for symbol in all_symbols if 'Car' in symbol.Name]
symbol = car_symbols[0]
# Arguments
pt = XYZ(0,0,0)
level = doc.ActiveView.GenLevel #Works in Plan views only!
struc = StructuralType.NonStructural
# Start Transaction
t = Transaction(doc, 'Creating Element')
t.Start()
elem = doc.Create.NewFamilyInstance(pt, symbol, level, struc)
t.Commit()
```

And here's our brand new VW Auto 🚗.
## P.S.
Do you think I should create a an E-Book: Revit API Element Creation Cookbook in the future?
I could go over as many methods as possible and create a ton of examples so you can copy-paste them into your scripts.
Let me know if there's a demand for that.
### ⚠️Stop Wasting Time Creating Views Manually (Here's First Step To Automate Views)
https://learnrevitapi.com/newsletter/stop-wasting-time-creating-views-manually-here-s-first-step-to-automate-views/
Automating View Generation will bring you the most joy.
**Just imagine**: you click a button, go get some coffee, and you come back to hundreds of views generated exactly how you needed them.
On top of that, if you show that to your boss they'll see you as a Automation Wizard🧙♂️. At least that's how I felt when my bosses saw me make 465 sales plans faster than my coffee.
And the first step to thesse automations is to know how to create views in Revit APi. So let's break it down.
Ready to automate views?

**Then firstly, let's learn how to create views with Revit API.**
## How to Create Views?
Creating views in Revit API is not complicated, however keep in mind that each view type has its own class([**ViewPlan**](https://www.rvtdocs.com/2025/0520580a-74ec-ed8c-35ea-5274c42276a3), [**ViewSection**](https://www.rvtdocs.com/2025/fcc75682-bd99-a97d-5a4d-0f8eb9e92ab5), [**View3D**](https://www.rvtdocs.com/2025/d795a238-fc24-1875-e64f-a2bef56ae949)...), and we might need a little different arguments for each to create them.

But in all cases you'll notice that you need to provide **Document **and **ViewFamilyType**, so let's start with those and then go over each code example.
## Get ViewFamilyType
Firstly, let's look at how to get [**ViewFamilyType **](https://rvtdocs.com/2024/e0edeb6d-1627-3e3f-e386-be182a9dd8cb)because we need it to create any kind of view.
In general, there are 2 ways to do that:
1. Get all [**ViewFamilyType**](https://www.rvtdocs.com/2025/e0edeb6d-1627-3e3f-e386-be182a9dd8cb) with a FEC, and filter them. This way you get a list of all available **ViewFamilyTypes **and you can select the one you need.

2. Or, a much simpler approach is to get the default **ViewFamilyType** with [**doc.GetDefaultElementTypeId**](https://www.rvtdocs.com/2025/b62f6563-aca4-56dc-4697-7717932187b3). It's quick and easy and that's how I like to create my views.

**P.S.**
You'd only need to keep one line depending on what kind of view you're trying to create. I'm just providing you multiple examples so you can pick and choose what you need.
**Next, let's have a look at how to create each ViewType.**
## 1️⃣ Create ViewPlan
To create a ViewPlan we need 3 arguments:
- **document**,
- **viewFamilyTypeId**
- **levelId**
And keep in mind that the **ViewPlan** class is used for:
- **FloorPlan**
- **CeilingPlan**
- **StructuralPlan**
- **AreaPlan**
So it means that we need to provide the correct **viewFamilyTypeId **argument to create what we need.
For example:

## 2️⃣ Create View3D
When working with 3D Views, remember that we can create Isomateric or Perspective view, and there are different methods:
- [View3D.CreateIsometric(doc, viewFamilyTypeId)](https://www.rvtdocs.com/2025/a913253d-2a92-b345-2b9a-882c1b152511)
- [View3D.CreatePerspective(doc, viewFamilyTypeId)](https://www.rvtdocs.com/2025/67c282a5-7e20-7f93-ae98-9a1aa3f6e706)
They are similar to use:

## 3️⃣ Create ViewDrafting
Creating drafting views is one of the easiest examples. Just see it for yourself:

## 4️⃣ Create Legend View
Now let's get to the tricky stuff and look at **Legends**.
First of all, there is no methods in Revit API to create Legends... However, you can grab any existing legend and duplicate it, then you'll have a fresh new empty legend view.
But here's something to keep in mind. You might have projects with no Legends. And in this case you just need to make warning and tell users to create at least one blank Legend manually before you can run your automation.
So here is full code sample:

Let's break it down:
- Get All Views
- Filter out ViewTemplates and Legends
- Ensure that you have legend View
- If not, notify user and ask to create one
- Duplicate any random legend
- Now you have a new Legend View
Not so complicated, huh?
**Especially when you use my code samples!**
## P.S.
Keep an eye on your inbox, I'm going to send you even more tips and tricks on Revit API soon.
✌️See Ya.
### 🔽 Easy Guide On How to use Revit API Filters (Quick vs Slow vs Logical)
https://learnrevitapi.com/newsletter/easy-guide-on-how-to-use-revit-api-filters-quick-vs-slow-vs-logical/
If you want to get the most from **FEC **collectors then you'll need to look into **Revit API Filters**.
I'll be honest, the first time you try it, it's confusing. But once you understand the logic behind them and use a few of them, it will start to make sense.
And then you'll have no trouble getting the most from collectors with your own custom filters.
Let's look into that.
### 3 Types of Revit API Filters
There are 3 types of **Revit API Filters** for collectors. And don't confuse them with **View Filters**, that's another topic for another day...
The 3 types are:
- [**ElementQuickFilter**](https://www.rvtdocs.com/2025/ebc95d82-11fc-69f6-2df1-52331dd36443)
- [**ElementSlowFilter**](https://www.rvtdocs.com/2025/e06b1e14-dd8d-8137-74ac-8ac4929eee85)
- [**ElementLogicalFilter**](https://www.rvtdocs.com/2025/3b8d6b55-0cab-1810-1188-840800e5eaa2) (Used to combine Filters)
These are the base classes, so you'll find a list of all children filters in the inheritance hierarchy. It's great to get an overview since most of them are self explanatory.
### Quick Filters
All quick filters are based on [**ElementQuickFilter**](https://www.rvtdocs.com/2025/ebc95d82-11fc-69f6-2df1-52331dd36443) Class.
This means you can scroll down to **Inheritance Hierarchy **to see all of them.
I would recommend scrolling through the list and read their names. They are quite self-explanatory.

💡Also keep in mind that many quick filters are similar to **FilteredElementCollector **Methods (More on that in a moment...).
### Slow Filters
Just like quick filters, all slow filters are based on [**ElementSlowFilter**](https://www.rvtdocs.com/2025/e06b1e14-dd8d-8137-74ac-8ac4929eee85). So you can scroll down to **Inheritance Hierarchy** and get a list of all these filters!

💡None of the Slow Filters have shortcuts in the FEC **class.** However, there are many interesting filters to explore.
Especially [**ElementParameterFilter**](https://rvtdocs.com/2024/b0b40351-690c-eb5d-30c2-d4447a42fda1)[ ](https://rvtdocs.com/2024/b0b40351-690c-eb5d-30c2-d4447a42fda1)and [**ElementIntersectsFilter**](https://rvtdocs.com/2024/b9e3bdcb-e85a-832d-0f51-312b3fd91cff)**. **Not the simplest to use, but they are really powerful!
## Logical Filters
Lastly, there are only 2 logical filters to combine your Quick or Slow filters into a single filter:
- [**LogicalAndFilter**](https://rvtdocs.com/2024/3e334aaf-2b39-58bd-d2cc-94e9c89bac57)
- [**LogicalOrFilter**](https://rvtdocs.com/2024/a00da224-d330-452d-a45f-5abffa2e57e6)
These filters combine other filters using **AND/OR** logic.
When applied to a collector, either all filters must be true (**AND **logic) or at least one (**OR **logic) to select your elements.
### Slow vs Quick Filters?
You might be wondering why there are 'slow' and 'quick' filters?
Does 'slow' mean we shouldn't use those filters? And the answer is - Not at all!
As the name suggests, one type of filter is quicker than the other.
**Quick filters** work faster because they look at a database record instead of expanding element in the memory.
They don't need to know every detail about the elements to filter them. Therefore they are called - **QuickFilters**.

On the other hand,** slow filters** need more information about each element. That means they have to load all the details of the elements into memory to check their different properties. Therefore - **Slow Filters.**
**❗But you shouldn't even worry about this difference.**
It's very unlikely you'll even notice any difference in perfomance unless you run it inside a crazy loop with thousand iterations. And even then it will be fast enough.
💪 Focus on making them work and leave efficiency for another day.
### How To Use Revit API Filters?
There are 2 ways to apply filters to a collector.
1️⃣ Firstly, you can use **shortcut methods**.
As you remember, you can create **FilteredElementCollector **and use its methods to filter elements. And these methods are shortcuts to apply the most used quick filters.
For example when you apply [**OfClass **](https://rvtdocs.com/2025/b0a5f22c-6951-c3af-cd29-1f28f574035d)or [**OfCategory**](https://rvtdocs.com/2024/c3523c35-4a07-9723-3c28-de3cc47b2ad0)[ ](https://rvtdocs.com/2024/c3523c35-4a07-9723-3c28-de3cc47b2ad0)method to your collector, you're actually creating [**ElementClassFilter **](https://rvtdocs.com/2024/4b7fb6d7-cb9c-d556-56fc-003a0b8a51b7)or [**ElementCategoryFilter**](https://rvtdocs.com/2024/b492ddf4-3058-8f9b-dfcc-8d5c4abb3605). It's just simplified for quicker and easier use.
💡Also, not all Quick-Filters have a shortcut method

2️⃣ Or you can create your own Filter and then apply it.
To apply custom filters to a collector you need to use [**WherePasses **](https://rvtdocs.com/2024/42d4eef3-55a1-2739-0ef8-6bc1d9fc2755)method that takes filter as an argument.
And if you want to combine multiple filters, then you need to use LogicalFilte

Also, if you want to combine multiple filters, then you need to use [**LogicalAndFilter**](https://rvtdocs.com/2024/3e334aaf-2b39-58bd-d2cc-94e9c89bac57) / [**LogicalOrFilter**](https://rvtdocs.com/2024/a00da224-d330-452d-a45f-5abffa2e57e6) and provide it as an argument.
It's actually quite simple once you see an example.
## Example: Apply Custom Filter
Now how do we apply filters?
Firstly, we need to create a custom filter and provide it to a collector using WherePases method. Most of them are very easy to create.
Let's start simple and look at - [**ElementIsCurveDrivenFilter**](https://rvtdocs.com/2024/cdfd2844-094c-cf6b-8303-3f34a125668f/)
This filter requires no arguments, so you simply call it to create and apply the collector.

Other filters might have more arguments to create them.
For example - [**FamilySymbolFilter**](https://rvtdocs.com/2024/67c230d2-e446-fed9-f648-69cf5dd395f8)
This filter needs Family Id as an argument.
I will manually write the **ID of that Symbol **in this example:

## Video Tutorial
I have a video tutorial on how to use **ElementParameterFilter**. That's a tricky one to use, so I wanted to break it down step by step. You can[** watch it here.**](https://www.youtube.com/watch?v=GV1nwVtuCjA)
> **NB** 
## P.S.
As I've mentioned Filters are very simple to use once you have an example.
That's why I created in-depth lessons including detailed summaries for **every Revit API Filter**, so you can understand what they do and most importantly** Code Example** of how to use it.
You can access them inside LearnRevitAPI Course Lessons:
- [**Lesson 07.05 - Revit API - Quick Filters**](https://learnrevitapi.com/courses/advanced/m07/05-quick-filters)
- [**Lesson 07.06 - Revit API - Slow Filters**](https://learnrevitapi.com/courses/advanced/m07/06-slow-filters)
**Here is the preview:**

### 👉Your shortcut to mastering FilteredElementCollector in Revit API
https://learnrevitapi.com/newsletter/your-shortcut-to-mastering-filteredelementcollector-in-revit-api/
Getting the right elements is half the solution.
And it's not complicated. However, beginners tend to make it harder for themselves, especially if they just start.
So let me show you how simple it is to create a collector and filter the right elements
**You're about to become a Revit API Hoarder.**

## How does Collector Work?
As you've seen inside **Revit Lookup**, Revit is like a database that contains all our elements and their properties. And like any database, we can query information with filters.
And that's where [**FilteredElementCollector**](https://rvtdocs.com/2024/263cf06b-98be-6f91-c4da-fb47d01688f3)(FEC) comes in. You need to create a collector and then apply a set of filters to get the right elements from your project.
Also it can look a bit confusing seeing it work for the first time, but I promise it's one of the easiest classes to work because of how repetitive it is.
Here is the Anatomy of how it's used:

This is the most typical way of getting elements with **FEC.**
In a nutshell:
1. You create collector with your **doc ***(Project)*
2. Then filter by **Class **or **Category **(or both)
3. Then you filter **Instances **or **Types**
4. And you convert to a list of **Elements **or **Element Ids**
Now not so complicated, huh?
## Revit API is Repetitive
**FilteredElementCollector is easier than it looks!**
I know it might be confusing to see that loooong line of code for the first time. However, it's one of the most repetitive classes.
👀 Have a look at examples below:

Notice that it almost stays the same!
We just need to make minor changes to this line of code to get different category or to get types instead of instances.
And that's why it's one of the easiest classes to use. You just need to use it a few times to get used to that.
## More FEC Examples
The best way to learn about FEC class is to see a lot of examples and then copy a few yourself.
So, have a look at even more examples of using FEC and compare the code when you get different elements.

## Video Tutorial
If you want to learn more about **FilteredElementCollectors**, I recommend you** **[**watch this video**](https://www.youtube.com/watch?v=MfJTPIOo7nY) where I will break it down and provide even more code examples.

## 📙Bonus E-Book
On top of that I've written an ebook specifically about **FilteredElementCollectors **and **Revit API Filters** to help you even more. It's full of code samples.
It has thousand downloads and it helped a lot of people to start using it right away.
👉 [**You can grab it here.**](https://learnrevitapi.com/resources/ebook-fec)

## P.S.
There are 2 ways to apply filters to the collector.
- Use collector Methods (easy)
- Create custom Revit API Filters (more advanced)
At first just focus on using regular methods and filter using python. But if you want to get into **Revit API Filters**, make sure you **check the next newsletter**, where I'll talk more about them.
✌️See Ya!
### ➡️ How To Automate Shared Parameters in Revit in 3 Easy Steps.
https://learnrevitapi.com/newsletter/how-to-automate-shared-parameters-in-revit-in-3-easy-steps/
Importing Shared Parameters sucks...
It's one of really boring tasks that takes lots of clicks, time and very little brain power... We all hate it, so why not automate it?
And if you don't know how, well let me give you everything you need (just like IKEA box), so you can create your own script.
**Let's Unpack Some Code!**

## Brainstorming
Before you start automating anything in Revit, just go through the process manually and try to break down all the steps you do.

Let's write all manual steps we do:
- Click On Add Parameter
- Select Shared Parameter
- Choose Type/Instance
- Choose Parameter Group
- Choose 'Values can very by group'
- Choose Categories
I bet you do these steps so fast, that you don't even notice it. But once you know it, we just need to follow the same steps with code.
And let's start from the end and look at the documentation. You will find the following method to add parameters:

You can see we only need 3 arguments, let's get them one by one.
💡PS. There are some changes in Revit API 2025+, but it's not hard to adjust the code.
## 1. Definition
Definitions are the blueprints of your parameters. And we can get **ExternalDefinitions** from **SharedParameterFile**.

Here is a complete code snippet that will:
- Open SharedParameterFile
- Iterate through Groups and Definitions
- Sort in a Dict
- Create **pyRevit.SelectFromList** form to select

💡You can adjust the code to anything else if you want other logic on selecting parameters.
## 2. Binding
The next one is Binding. If you explore docs, you will notice that it's an abstract class and we need to use children classes:
- **InstanceBinding**
- **TypeBinding**
That's how you select if you're adding parameters as Instance/Type parameter.

To Create a binding, we also need to create a **CategorySet **to provide as an argument inside:
- [**InstanceBinding Constructor (CategorySet)**](https://rvtdocs.com/2024/b090b5a8-9229-7079-9f8f-6e7518d9b708/)
- [**TypeBinding Constructor (CategorySet)**](https://rvtdocs.com/2024/e3c23bb6-9963-6963-95d4-71eaf9e32cc9)
So in this step we are choosing categories and if it's an instance/Type paramter.
Here is the code to create a [**CategorySet**](https://rvtdocs.com/2024/43cc0dab-85d2-5e24-d6a7-2cccb6f39ad0):

💡P.S. There are 2 ways(A/B) how to do that. Choose whatever you like more.
Then we need to decide if we want **Instance **or **Type Binding.**

💡We also have 2 options to create this kind of binding. So again, choose whatever syntax you like more:
## 3. Group
Lastly, we need to choose a ParamegerGroup.

It's very easy because we will use [**BuiltInParameterGroup Enumeration**](https://rvtdocs.com/2024/9942b791-2892-0658-303e-abf99675c5a6), so it already contains all possible values same as in Revit UI. Just choose what you want

## 🚀Put it all Together
Alright, we went through all the steps briefly, now let's just combine it into a single code snippet you could actually start using to automate this boring task with some python code.
Here is full python code:

**And here is the end result in action:**

I think this little script can already save you a few hours on every project when you need to setup your shared parameters.
**So Steal It!**

### 🚀 Your First Step to Automating Parameters with Revit API
https://learnrevitapi.com/newsletter/your-first-step-to-automating-parameters-with-revit-api/
**Revit is all about parameters.**
Sometimes we spend days going through Revit model to ensure we have the right parameters so our calculations are correct. And it's really annoying task.
So it's essential to understand **How to Get, Read and Set Parameter Values with Revit API**. That's how you can create simple tools that can save you not only hours, but days...
So let's dive in.
## How to Work with Parameters in Revit API?
When you work with Revit API keep in mind that elements have a list of parameters. It can be:
**🔹Built-In Parameter**
**🔹Project Parameter**
**🔹Shared Parameter**
There are also **Global **and **Family **Parameters, but we won't cover them in this newsletter. (**Reply **if you want a separate email about them.)
To automate your parameters in Revit you need to learn:
- How To Get Parameters
- How To Read Parameter Values
- How To Write Parameter Values
Let's cover it step by step.
## 1️⃣ How to Get Parameters?
No matter what you want to do, firstly, you need to get the parameter itself from the element.
And it can be confusing to a beginner because there are lots of different methods in the Documentation:
- [**LookupParameter('p_name')**](https://rvtdocs.com/2025/4400b9f8-3787-0947-5113-2522ff5e5de2)** **Method
- **get_Parameter(BuiltInParameter) **Method
- [**GetParameter(ForgeTypeId)**](https://rvtdocs.com/2025/fc4e5245-d2e5-e31d-a6e3-177106e75e10)** **Method
- [**GetParameters('p_name')**](https://rvtdocs.com/2025/0cf342ef-c64f-b0b7-cbec-da8f3428a7dc)** **Method
- Iterate through [.](https://rvtdocs.com/2025/7af5d66f-4533-33d2-dd82-d9573eaabf15)[**Parameters**](https://rvtdocs.com/2025/7af5d66f-4533-33d2-dd82-d9573eaabf15)** **Property
Also, keep in mind that **Project/Shared **parameters always keep the same name, while **Built-In** parameters can have different names depending on the language.
Therefore I like to use:
- **get_Parameter **for **built-in** parameters
- **LookupParameter **for **project/shared** parameters.
Let's look into that.
## Get Shared/Project Parameters
These parameters always have the same name. So it's okay to use [**LookupParameter**](https://rvtdocs.com/2025/4400b9f8-3787-0947-5113-2522ff5e5de2) and provide the name. Very straight-forward.
However, when you use this method, make sure that you actually found the parameter. Because sometimes you can run your script on a new project where this parameter doesn't exist yet.
Here is a simple example:

💡PS. This will also work for **Built-In** parameters, but it's not recommended because it can get translated by Revit.
## Get Built-In Parameters
When working with built-in Parameters, it's best to use **get_Parameter **and then select the right [**BuiltInParameter **](https://rvtdocs.com/2024/fb011c91-be7e-f737-28c7-3f1e1917a0e0)**Enumaration value.**
Sometimes it might be tricky, so use Revit Lookup to find the right name (**Parameter.Definition.BuiltInParameter)**
For example for Comment or Type Comments it would be like this:

Then you can get your parameter with code like this:

In this case, it's not necessary to check if parameter exist, because it's already built-in. However, make sure you get it from the right element.
💡Especially when dealing with **Instance** vs **Type **parameters.
## 💡Instance vs Type Parameters
Beginners often get confused with that one.
To get an instance parameter you need to look inside **element instance**, however to get type parameter you need to get **ElementType **and then look inside of that.
**element.Parameters** -> List of **Instance **Parameters
**elem_type.Parameters** -> List of **Type **Paramters
This is because Element and ElementType have different classes in Revit API, and that's how parameters are stored. But it's easy to get once you know it.

## 2️⃣Read Parameter Values
Now you know how to get parameter.
To read parameter values, you need to use one of the methods depending on the **StorageType **of a parameter.
Usually, it's very clear. If you work with text parameters like Comments, Mark... you know it stores text values, therefore you'd use **AsString().**
If parameter reference another element like Level, Material... then you'd want to use **AsElementId()**...
If in doubt, you can always look inside of **RevitLookup **and see what values you get with each method.

In this case it's very clear that you need to use **AsString **to get ***'Special Wall' ***value. You can also see **StorageType = String **above.
Here is how to read it with Python:

💡 Same applies to both **Built-In or Shared **Parameters.
## 3️⃣ Set New Parameter Values
Lastly, how do you override parameter values?
For that we need to use [**.Set()**](https://rvtdocs.com/2024/906458f5-cc02-5972-1272-a59f27739c12) method to change value, and you need to provide a value with the correct type.
🔓 Also, you need to **Start **and **Commit** a Transaction when you make any changes to your project. That's like a guardian of your projects so beginners don't break anything by accident and only apply intentional changes.

💡NB! You also have to provide the value with the correct Type (Text, Integer, Float, ElementId). If you provide the wrong type, you won't get any error messages, but it also won't change parameter value. And it can confuse a lot of beginners.
## Bonus Example
Now let's put it all together and practice.
Create a pyRevit button or open RevitPythonShell and try this code yourself to get more clear on what's going on.
✅ Try to get Shared / BuiltInParameters
✅ Read their values
✅ Set New Values
✅ Bonus: We can also iterate through a list of all parameters
**Here is the code:**

💪Try it out!
It will help you get more clear on parameters in Revit APi.
## P.S.
If you want to get more in-depth explanation about Revit API parameters, you can [**check this YouTube Tutorial**](https://www.youtube.com/watch?v=YoLxucuC6Ss).

This will help you get visual on how parmaters actually work in Revit API.
### 🆎 How To Convert Units in Revit API With a Single Line Of Code.
https://learnrevitapi.com/newsletter/how-to-convert-units-in-revit-api-with-a-single-line-of-code-2/
📏** Revit API uses feet internally.**
This has caused a lot of confusion among beginners who use the metric system.
They read property or parameter values and see completely wrong numbers in Revit and Revit API. And it's the worst when you're debugging something that isn't even broken. (Trust me, 🤦♂️ I've been there too...)
So I want to share how to convert units in Revit API with a single line of code.
**🧮 Pull out your calculators.**

## Revit API uses Feet
It's so simple, but beginners tend to forget it. So let me say once more:
**🚨Revit API uses Feet As Internal Units!🚨**
Many people waste hours because of this confusion... Myself included!
Once, I was going crazy when I worked with coordinates and forgot to convert units. And nothing matched when I wanted to verify my values.
I spent hours debugging and rewriting my code multiple times, knowing that it can't be broken. My logic was on point and it should have worked. And then I realized...
**I just forgot a single line of code🤦♂️.**

## How to work with Revit API units?
Imagine you have a wall with a height 300cm.
You read the value with Revit API and you see completely different result (9.84). You start to think you doing something wrong, but your value is just in feet...
And the same goes for setting new values. If you'd want to change height to 250cm, you'd need to convert 250cm to feet before you set a new value with Revit API.
You just need to add an extra line of code to convert units correctly. Sounds annoying, but you get used to that.
Converting units with the Revit API is quite simple. There are two methods in the [**UnitUtils**](https://rvtdocs.com/2025/128dd879-fea8-5d7b-1eb2-d64f87753990)[ ](https://rvtdocs.com/2025/128dd879-fea8-5d7b-1eb2-d64f87753990)class that we can use to convert internal units:
**- **[**ConvertToInternalUnits(value, UnitTypeId)**](https://rvtdocs.com/2025/60c6aac3-8306-c56e-b62f-b7011b9ad7b6/)
**- **[**ConvertFromInternalUnits(value, UnitTypeId)**](https://rvtdocs.com/2025/b5e8d065-d274-62f8-7b5d-89722f7c44f3)
Here is the Syntax:

Also, keep in mind that there is no **ForgeTypeId **class. Instead, you need to use [**UnitTypeId **](https://rvtdocs.com/2025/bc1b6454-f10a-66dc-9268-1dccbc403f78)class which contains a list of all possible unit values to choose from.
## Convert Units Like This
Now let's try it out.
If you have a value in metric units and need to convert it into internal units, use [**ConvertToInternalUnits**](https://rvtdocs.com/2025/60c6aac3-8306-c56e-b62f-b7011b9ad7b6/)[ ](https://rvtdocs.com/2025/60c6aac3-8306-c56e-b62f-b7011b9ad7b6/)like this:

However, if you have a value in internal units (ft), then use [**ConvertFromInternalUnits**](https://rvtdocs.com/2025/b5e8d065-d274-62f8-7b5d-89722f7c44f3)[ ](https://rvtdocs.com/2025/b5e8d065-d274-62f8-7b5d-89722f7c44f3)like this:

That’s it.
Just remember that the **Revit API uses feet as its internal unit**, so always select the correct unit.
## UnitTypeId Class
[**UnitTypeId **](https://rvtdocs.com/2025/bc1b6454-f10a-66dc-9268-1dccbc403f78)is a class in Revit API that contains a list of units of measurement.
It includes a long list of units, but you’ll only need a handful, such as **Meters**, **Centimeters**, **SquareMeters**, and so on...
Here is a screenshot from the Docs:

## P.S.
Whenever you **read **or **set **values and something doesn't match up, make sure you** use the right units** before you start the whole debugging session.
This can save you a lot of time!
### 🚀Start Coding Faster By Looking Inside Your Elements First
https://learnrevitapi.com/newsletter/start-coding-faster-by-looking-inside-your-elements-first/
Don't jump straight into code.
Once you have an idea for your custom Revit tool, spend a few minutes looking inside elements to understand how to get the right data. This will speed up your coding process.
Luckily, it's very simple to do with a free **Revit Lookup** plugin, which is a must for any Revit API developer.
Here's how it works.
**Grab Your Magnifying Lens,**
**Let's Look Inside Elements!**

## The Most Used Revit API Plugin
In order to look inside elements you need to install **Revit Lookup**. It's free and you can get it on [**Revit Lookup GitHub page**](https://github.com/lookup-foundation/RevitLookup/releases).
Just scroll down to assets and download for each Revit version you're using.

Once you download, run the installer as usual.
Then you'll find **RevitLookup **under **Revit Add-Ins** Tab.

Let's breakdown how to use it.
## How To Look Inside Elements
There are multiple options on how to snoop your elements in Revit with **Revit Lookup**.The most popular options:**Snoop SelectionSnoop Active ViewSnoop Document **(Project)**Snoop Database **(Everything)

For example, select a few elements in Revit UI and then click on **Snoop Selection**. This will open up a menu where you can explore elements.

**Left side:**
On the left you'll have a list of selected elements sorted by their classes. These are the classes that you can also lookup inside RVT Docs to get better understanding of specific attributes.
**Right Side:**
On the right you can see all attribute(Properties/Methods) names, and most importantly the values they return.
You'll use the same names in your code to get the displayed values. It's great to understand the steps you'll need to code.
(e.g. **elem.LevelId** - will get you Id of associated level with the element, if it has one)
**Regular vs Red Bold attributes**

Notice that certain attributes are just plain text, while others are** bold red**.
- The plain attributes returns final values like** Text/Number/ElementId...**
- **Bold attributes **return another Element or a list of elements. You can keep exploring their attributes further.
For example if you get a **wall **and read **wall.WallType **property - it will return you a **WallType **element. Then you can explore attributes of a WallType class. It's like a chain that you follow to get the right values.
**Inheritance Hierarchy**
Also, while exploring Revit Lookup, you'll notice that all attributes are sorted by classes where they come from. Because in Revit API most classes are created with a **Base **classes to share the same attributes.

This means that if you look for attributes related to the selected class, you need to scroll down to the right section.
Overall, you'll get used to that very soon.
## Snoop Database
Sometimes you'll want to look into objects which are not possible to select in Revit UI. For example: **Material class.**
You can either select element and get to these classes by following a chain, or you can **Snooop Database** and find it there.
Revit is like a Database containing of all objects in the project. And if you snoop database it you'll get a list of everything.

This way you can scroll through classes that aren't easy to get to (like Materials for examples). This way you can quickly look inside these classes and learn how to work with them.
## How To Read Values in Python
Now, let's get a bit more practical.
Once you explore the elements it's time to dive into code and get values inside your code. And by now you know everything you need.
Now you just need to get an element and read its properties or methods using the right attribute names.
For example:

This will get very easy after you do it a few times.
## When to use Revit Lookup?
Anytime you're about to start writing code.
It will help you to map out the steps on how to read your elements to get the right data. This can save you a lot of time.
Especially as a beginner, always start with Revit Lookup to better understand the flow you need to create inside your code.
And then just follow it in python.
## Property vs Parameter
Also, do not confuse **Properties** with **Parameters**.
- **Property **is an attribute related to a class (**Id**, **Category**, **LevelId**...)
- **Parameter **is like a container related to Revit elements that can holds data. It has its own [**Parameter**](https://rvtdocs.com/2024/333ff41b-e6a7-d959-60bf-c3bfae495581)[ ](https://rvtdocs.com/2024/333ff41b-e6a7-d959-60bf-c3bfae495581)class with its own attributes you can explore. You can even get a list of all parameters with a property called **.Parameters**
And don't worry.
I'm going to explain parameters in depth in another newsletter so you learn how to Get/Read/Set values of any parameter.
For now, just focus on reading properties and methods that you can find inside of Revit Lookup.
## P.S.
You can already start creating simple tools by only reading and changing parameter values. Just give it a try and you might get surprised with the results.
👀 And keep an eye on your inbox.
I have a lot more lessons to share with you to help you on your Revit API journey.
✌️See Ya.
### 👉 How To Prevent Revit Users from Selecting the Wrong Elements
https://learnrevitapi.com/newsletter/how-to-prevent-revit-users-from-selecting-the-wrong-elements/
**Selection **is not hard in Revit API.
However, users like to break our Revit tools... And we can avoid that by limiting what can be selected. This way users can only select the right elements and ensure everything works correctly.
For that we need to use **ISelectionFilter **Interface.
So let me break it down for you.
**It's time to limit what can be selected.**

## Advanced Selection in Revit API
In the previous newsletter you've learnt the basics on how to select elements with Revit API.
That's already a great start but it can lead to situations where users select wrong elements. That can confuse users and even break your code if you didn't think of that.
So instead, we can take it to the next level by adding custom filters on what's allowed to be selected. This will provide a far better user experience.
**For example**, imagine that you need users to only select furniture. We can limit selection and then no matter how hard they try, only furniture will be selected:

**As you can see, only furniture can be selected.**
To add these custom filter rules during selection we need to use **ISelectionFilter. **It's provided as one of the arguments to selection methods.

## What is ISelectionFilter ?
[**ISelectionFilter Interface**](https://rvtdocs.com/2024/d552f44b-221c-0ecd-d001-41a5099b2f9f) provides the ability to add filtering rules during selection. This is how you limit what's allowed and what's not.
**💡Interface **in programming is a blueprint for creating your own classes with certain functionality included. It might sound confusing, but** it will get simple once you see an example.**
In short you need to:
- Create custom class based on **ISelectionFilter**
- Override **AllowElement** method
- Provide it as an argument for **Selection **methods.
So the main goal is to override [**AllowElement **](https://rvtdocs.com/2024/9c967926-c396-6e6b-97a2-b6882d71b69e/)method when you create you own filter class based on **ISelectionFilter**

**Let's dive into examples and it will get clear.**
## Example #1 - Filter by Class
Here is the first example, where we will allow only **Walls** to be selected by checking element types.

Here is what's going on:
- Import **UI.Selection** classes
- Create custom filter Class
- Inherit **ISelectionFilter**
- Override **AllowElement **method
- Apply in PickObjects method
**And here's the result:**

Notice that when we hover over all elements, only walls are being selected. That's the advanced technique in action.
The idea is to create logic in **AllowElement **method that returns True to elements which are allowed to be selected.
## Example #2 - By Category
Here is another example, but this time I want to filter based on Category. Let's limit selection to **OST_Furniture**.

Everything is the same as before.
I've only changed the logic in **AllowElement** method.

💡Keep in mind that **Category.BuiltInCategory** is only available from Revit 2022+. So it's better to use **Category.Id** to find the match.
## Example #3 - 'Beton' in type name
Let's make it more interesting.
I only want to select Walls that have 'beton' in their Type Name. So here is the code to do that:

Again, I only modified logic in **AllowElement** Method.
The rest stays the same...

## Conclusion
That's how we can improve user experience during selection.
**ISelectionFilter **might sounded confusing at first, but then you realize that you copy the same template and only modify code inside **AllowElement **Method.
This makes it **easy even for absolute beginners**.
So give it a try!
💡Remember, **Revit API is very repetitive,** and once you see how something works, it becomes very easy to reuse it again.
I try my best to provide you the most useful code examples so you can apply it in your own code ASAP. So please, use it.
## P.S.
**Code is the greatest leverage for your time!**

### 👉How Selection Really Works in Revit API (Basics for Beginners)
https://learnrevitapi.com/newsletter/how-selection-really-works-in-revit-api-basics-for-beginners/
Ready to master **Selection **with Revit API?🪄
Getting elements is often the first step in creating your tools to test your code, so it makes perfect sense to begin with that.
And luckily for you, it's very simple. Let me show you the basics.
**Time to Master Selection!**

## 👉 Revit API Selection for Beginners
Let's begin with documentation.
I know it sounds boring, but coding without docs is like sailing with wind, Not very fun...
The [**Selection **](https://rvtdocs.com/2024/31b73d46-7d67-5dbb-4dad-80aa597c9afc)**Class** which is located in **Autodesk.Revit.UI.Selection** Namespace. And to use it, we need to get an instance related to our project, so we select the right elements.
We can get it from **UIDocument **like this:

Once you have Selection, you can use methods to
- Get user selection
- Prompt **Selection** methods
- Set new selection in Revit's UI

It's easy to use these methods.
Once you have an instance of Selection, we just need to look at the methods to find if we need any arguments or not. And then we just call these methods.
For example here **Syntax **sections for [**GetElementIds**](https://rvtdocs.com/2024/4af3bdc7-e69c-8aa6-406d-865d7f036927), [**PickObjects**](https://rvtdocs.com/2024/577ac5d0-8a6d-8e73-9d0d-259ed0ac6024), [**SetElementIds**](https://rvtdocs.com/2024/cf8c11bb-f0c7-6d50-cbdf-41d0a010d9d6) from the Docs:

Now let's cover these most popular methods so you know how to work with **Selection class**.
## 1. GetElementIds()
Let's begin with the most basic one - [**GetElementIds**](https://rvtdocs.com/2024/4af3bdc7-e69c-8aa6-406d-865d7f036927)
This method returns the ids of the elements that are currently selected within the project.
Here is the code sample:

- Get **Selection** instance
- Get **List of ElementIds **with **GetElementIds**
- Convert **ElementIds **into **Elements**
- *Optionally*: Filter list of elements
**Do you see how simple it is?**
## 2. PickObjects()
Let's look at the second most used method - [**PickObjects**](https://rvtdocs.com/2024/577ac5d0-8a6d-8e73-9d0d-259ed0ac6024).
This method prompts users to select elements in Revit UI and confirm the selection.
To use it, it needs [**ObjectType**](https://rvtdocs.com/2024/2d0cbbba-d4ab-84b7-b081-36c14769d82c/) argument and it'll return you a list of References.
💡Don't worry, you can convert Reference to an Element with [**doc.GetElement(ref)**](https://rvtdocs.com/2024/4d674a3e-cd18-6b3d-b1b2-247713fe3c9f) *(similar to ****ElementIds****...)*.
Here is the code sample:

- Get **Selection** instance
- import **ObjectType**
- Get **List of References **from **PickObjects**
- Convert **References **-> **Elements**
- Print Results
**P.S.**
💡 When you use **PickObjects **you need to click on **Finish **button in the top left corner of Revit UI window.

## 3. PickElementsByRectangle()
Another way we could prompt selection is to use [**PickElementsByRectangle**](https://rvtdocs.com/2024/2be6b3b7-2cec-1d8a-76fb-afcd618fcae6/)[ ](https://rvtdocs.com/2024/2be6b3b7-2cec-1d8a-76fb-afcd618fcae6/)method.
This one is very simple, doesn't take any arguments and it returns you a list of **Elements**, so you don't even need to convert anything.
Here is how it works:

- Get **Selection** instance
- Use** PickElementsByRectangle**
- That's It!
## 4. SetElementIds()
Lastly, let me show you how to change user selection in Revit UI with the code. It has a lot of use-cases:
- Filter Selection
- Select elements with warnings
- Select elements that match certain criteria
- and many more tool ideas...
To use it you need to provide a **List[ElementId]()** as an argument. Keep in mind that regular python list won't be enough, you'll need to convert it into .NET typed **List**.
To do that, firstly import the **List **from **System **like this:

And then you can use this code snippet to set new selection in Revit UI.

- Get **List of Walls** with FEC collector
- Convert **Elements** into **ElementIds**
- Convert Python List into** List[ElementId]()**
- Then use **SetElementIds **method.
**Not so complicated either, right?**
P.S.
💡Make sure you provide a list of elements and not a single element when creating** List[ElementId](list_here)**.
That's a very common mistake beginner make with single elements.
## Summary
And that's the basics of **Selection in Revit API**.
It might've sounded hard before we began. But just a few minutes later you learnt the basics and nothing can stop you from using **Selection class **with these code examples.
Now it's your turn to open a code-editor and try them out.
You can even tweak a few things to create a useful tool to help you with selection for your work inside of Revit. That's how you'll learn the best.
💡 Also, Keep an eye on your inbox.
In the next newsletter you'll learn about **advanced selection technique** to apply custom filters. This will help you avoid a lot of errors with selection in your code.
## P.S.
Meanwhile, if you'd like to learn more about Revit API in an easy way with videos, summaries and even more code examples and real-world application, then make sure to check **LearnRevitAPI Course**.
Inside you'll get access to my proven roadmap to master Revit API which makes it easy for any beginner to start creating their custom tools from scratch.
Sounds interesting? Then [**Click Here**](https://learnrevitapi.com/) to Learn More.
### 💻 Revit API Setup for Beginners (This will save you a lot of time!)
https://learnrevitapi.com/newsletter/revit-api-setup-for-beginners-this-will-save-you-a-lot-of-time/
It's time to dive into actionable code.
However, before we begin, let's make sure that you all setup your Dev Environment correctly to follow along the upcoming newsletters.
So let's install it step by step together. **Ready?**

## Prefer Video?
In case you'd rather follow along the video, then [**Click Here**](https://learnrevitapi.com/free-lessons/1-04-setup-dev-environment)** **to watch the video tutorial on YouTube.

## Install Essential Revit API Add-ins
When working with Revit API, we need a few Add-ins:
- **pyRevit **(duh…)
- Revit Lookup
- RevitPythonShell (optional, but useful)
All of them are Free to use and open-source.
## Install Revit Lookup (MUST HAVE)
Firstly, let's install [**Revit Lookup**](https://preview.convertkit-mail2.com/click/dpheh0hzhm/aHR0cHM6Ly9naXRodWIuY29tL2plcmVteXRhbW1pay9SZXZpdExvb2t1cC9yZWxlYXNlcw==), which is by far the most used add-in for any Revit API developer.
💡 This Add-in allows you to look behind the scenes and explore your Revit elements.
You will see attributes and all available data in Revit API for selected elements. This is great because you can see names of Properties that you have to use and also see the values that will be returned.

## Install Revit Python Shell
The second plugin we can install is optional and it's [**RevitPythonShell**](https://preview.convertkit-mail2.com/click/dpheh0hzhm/aHR0cHM6Ly9naXRodWIuY29tL2FyY2hpdGVjdHVyZS1idWlsZGluZy1zeXN0ZW1zL3Jldml0cHl0aG9uc2hlbGw=).
This plugin was developed by Darren Thomas and it's also the base on which pyRevit was built. This provides you a python shell inside of Revit, which can be useful for testing and debugging small code snippets.
But keep in mind that it might not be maintained for Revit 2025+ anymore. **It works well in Revit 2023**, but I'm not even sure if it works for Revit 2024. So it's up to you if you want to install it or not.
Here is how it looks in Revit.

## Download Revit API Stubs
Next, we're going to install and setup our IDEs (Code-Editors).
But first, we need to [**download Revit API stubs from here**](https://learnrevitapi.com/resources/revit-api-stubs)**.**
You will also find a video on how to create Revit API stubs yourself, but you can just download it from under the video.
Once you download, place it somewhere safe on your PC, for example:
- C:\Users\USERNAME\AppData\Roaming\revitapi_stubs
💡 You can call the folder anything you want.
## Configure IDE (Code-Editor)
Lastly, we need to download and configure your IDE (code-editor) to enable Revit API Autocomplete, which is necessary step for any Revit API developer.
Firstly you can download both IDEs:
- [**Download VS Code**](https://preview.convertkit-mail2.com/click/dpheh0hzhm/aHR0cHM6Ly92aXN1YWxzdHVkaW8ubWljcm9zb2Z0LmNvbS9kb3dubG9hZHMv)
- [**Download pyCharm**](https://preview.convertkit-mail2.com/click/dpheh0hzhm/aHR0cHM6Ly93d3cuamV0YnJhaW5zLmNvbS9weWNoYXJtL2Rvd25sb2FkLz9zZWN0aW9uPXdpbmRvd3M=)
Secondly, you need to configure them for Revit API.
I would recommend you to 🎦 Watch Video Lesson for Step by Step Instructions.
If you prefer written format, have a look at the [**lesson summary**](https://preview.convertkit-mail2.com/click/dpheh0hzhm/aHR0cHM6Ly9sZWFybnJldml0YXBpLmNvbS9mcmVlLWxlc3NvbnMvMS0wNC1zZXR1cC1kZXYtZW52aXJvbm1lbnQ=), where I've included code snippets, GIFs and everything you might need.
## What is Venv?
Virtual Environments(venv) allows us to preconfigure python environment for different purposes with its own set of packages, references and stubs.
We will have to create 1 or multiple virtual environments in pyCharm, so we can provide Revit API stubs to multiple versions and then switch between them with a click.
Check the video to learn more about it.

## What about AI?
This is a game-changer.
I wish I had AI when I started to look over my shoulder and help me with simple stuff.
**Which one?**
To be honest, it doesn't matter which one you choose, it matters that you have it. There are free options, but paid will give you more juice🧃.
Popular options:
- GitHub CoPilot
- TabNine
- Codeium
- Cody
- Continue AI (for local LLMs with ollama)
- CodeWhisperer (Amazon)
You can also get an AI-Powered IDE like:
- Cursor IDE
- TRAE IDE
I won't go in details how to install it, there are plenty of videos and it's easy to do on your own.
In general you install extension, create an account and it works out of the box.
If not sure, grab **GitHub CoPilot** it's the default option for many.
## P.S.
And once you setup your Dev Environment you'll be ready for the next newsletter lessons where we'll dive deeper into the code starting with Selection basics.
### 🔠Learn How to Translate C# to Python (Step-By-Step Beginners Guide)
https://learnrevitapi.com/newsletter/learn-how-to-translate-c-to-python-step-by-step-beginners-guide/
You can translate any C# code into Python.
Once you understand the main differences in C# and Python Syntax, you'll be able to take any code example from documentation and turn it into python
And the best part? It's not even that complicated. You just need to know the basics.
And that's exactly what I'm going to break down today in this newsletter. Are you Ready?

## C# vs Py - Code Structure
The most obvious difference is how they define code blocks.
- Python uses indentation(4 spaces/tab)
- C# uses curly braces `{}`
This is why Python always looks much cleaner and easier to read.
You'll also notice that C# ends statements with a semi-colon (;), while Python doesn't need anything in the end.

💡 Notice that comments use different symbols. Python needs **#**, while C# uses **//**
## C# vs Py - Variables
In python we just create a variable name and assign a value. The Type is handled by python runtime.
But in C#, every time you create a variable, you have to define its type before the variable name. This is called type-hinting. IT helps IDE to analyze your code and provides better debugging.

## C# vs Py - Logical Statements
The logical statement are very similar.
Python uses colon (:) to start a code blocks, while C# just needs curly-braces ({}) and semi-colons(;).
Also in Python **elif **is same as **else if **in C#
**Example:**

P.S.
You might've also noticed that in C# they use **Console.WriteLine **instead of **print **function.
## C# vs Py - Loops
Python and C# both have for-loops and while-loops, but the syntax is a little different especially if you want to use range.
To define range in C# you need to define start/end with their types and specify that you increment **i++**, it's like using **+=** in Python.

## C# vs Py - Function
First let's have a look at functions that do not return anything.
In python we just use def keyword and write our function.
In C# we need to use **void **keyword before the function name which means that Function doesn't return anything.

When function returns something, in **C#** we declare the **Type** of returned object before the name of the function.
(e.g. **Wall CreateWallFunction() **)
Also you have to define **Types** of all parameters in your function before their names. In C# everything is always type-hinted to keep track of what types are necessary.
In Python, it's all optional. Usually we explain what we need and what's returned in the doc-string. But we also have an option to provide type-hinting of parameters and returned value. It's a great habit, but beginners often don't even know it's possible.

## C# vs Py - Class
Classes are simple. Once you know the difference in functions, the same logic applies to Class and methods.
The only difference is that there is no need to use first parameter - self in your methods. C# already includes it by default and uses word **this** to refer to itself.

## C# vs Py - Inheritance
As you know in programming we can inherit classes and build new ones based on that. That's like using Template in Revit…
The main difference is the syntax. In C# they use colon after the class name and specify class to inherit from. In python we use parenthesis to do that.

## C# vs Py - Error Handling
Next, let's have a look how to handle errors, and you will see that they are very similar. The biggest difference is that C# uses keyword catch instead of except.
The rest is pretty much the same with the usual syntax differences.

## C# vs Py - Context Managers
As you know in programming we have a concept called Context Manager.
It allows you to create a separate code block that includes additional functionality before/after the code you write.
The most common example is reading files (**with open() as f...**). It makes sure that your file is closed safely after you read/write something inside files.
Python uses - **with **keyword
C# uses - **using **keyword
Here is an example:

## C# vs Py - Error Handling
Next, let's have a look how to handle errors, and you will see that they are very similar. The biggest difference is that C# uses keyword **catch **instead of **except**.
The rest is pretty much the same with the usual syntax differences.

## C# vs Py - Conclusion
Overall once you know the key differences it's very easy to translate C# code into Python.
However, keep in mind that they do not share the same built-in functions and therefore sometimes it might be a bit trickier to translate certain functionality.
But with the help of Chat GPT it's easier than ever and takes just a few seconds.
## C# vs Py - Example
Let me show you an example of how to turn C# into python.
In many cases you just need to get rid of C# extra syntax and then it becomes python. Here is an example from RVTDocs:

I've just removed** type-hinting**, **semi-colons**, **curly-braces**, **new **keyword, made **booleans capitalized **and **added def **keyword, changed comments symbol and now it's a proper python code.
Here is another one:

Just drop a few C# examples into ChatGPT and ask it to point out the differences. It will make it so much easier to look at C# code after that.
## P.S.
**Want to learn more?**
There is a whole module on how to read and understand Revit API documentation inside LearnRevitAPI Course. This is what a lot of my students asked me to create and they enjoy it a lot.
I go really in depth and show explain in videos how to read and translate C# into Python. After this module it doesn't matter that docs do not include Python snippet, you'll be able to translate them yourself.
[**Click Here**](https://learnrevitapi.com/) to get instant access to the most comprehensive Revit API Training for python coders.
### 🔎 Revit API Documentation For Beginners. (How to Get The Most out of It?)
https://learnrevitapi.com/newsletter/revit-api-documentation-for-beginners-how-to-get-the-most-out-of-it/
Coding without Docs is like sailing with wind.
Not very fun, huh?
So let's dive into Revit API Documentation and I'll show you how to navigate to get the most out of it.
It's a really important resource if you want to create custom Add-in for Revit. So you better get good at that.
So let's check how to use [**RVTDocs.com**](https://rvtdocs.com/)
## How to Navigate?
Once you open **RVTDocs **you'll see API version for each year available on the top. Choose the one where you work the most.

Then you can either use the sidebar navigation to find classes you need, or use the search (*shortcut ****CTRL+K***) to find it quicker.
The search also includes filters to help you find what you need faster.

While searching you'll notice that all classes are part of **Namespaces**. Think of them as containers to organize classes.
Majority of classes you need will be under **Autodesk.Revit.DB Namespace**.This is also from where you'll import these classes in your code using:**from Autodesk.Revit.DB import *from Autodesk.Revit.DB.Architecture import Room**

## Where to Pay Attention?
Once you open any class you'll see a lot of information about it. At first it might be a bit too much, but over time you'll know exactly where to look to get what you need.
Here are the sections you can find.
1. **General information**

On the top you'll always find the **Name**, **Description **and **Remarks** of the selected **Class **or **Attribute**.
Often times it's self explanatory, but I highly recommend you to pay attention to **Remarks **section. It often includes very useful information on how to work with selected class.
**2. Inheritance Hierarchy**
On the right side you'll also find **Inheritance Hierarchy **this is a crucial OOP concept. It will help you understand the relations between classes.
As mentioned previously all classes in Revit API inherit similar properties from base classes like **Element**, **View**... And then they have their own specific class attributes.
This is why most of classes will have attributes like (**Id**, **Category**, **GetTypeId**() and many more...
**3. Syntax**
Then you'll find the Syntax section explaining the selected **Class/Attribute**.


In case of Classes it's not so useful... But it's the most useful section when you explore **Methods**, **Properties **or **Constructors**.
This is where you can actually see how to use it in your own code and what arguments you need to provide to make it work. This is the whole reason to open **RVTDocs **in the first place.
**4. Examples**
Next if you're lucky, you'll find a code example on how it can be used in your own code. They're often overcomplicated, but they can also be very simple and to the point.

Unfortunately, these examples are in** C#** and **VB** Syntax, but it's not hard to translate them to **Python**, especially with a help of Chat GPT.
P.S.
💡I'm also working on a special AI feature to translate these examples into **Python **right on the website. It already works but I need to refactor code to make it work well at scale. You'll hear from me when it's published.
Meanwhile, you can drop them to Chat GPT and ask to translate to Python. It does it pretty well.
**5. Parameters & Return Value**
In the next section you can find more details on the parameters and return value.

Usually the description is self explanatory, but it's very useful to reference the correct types to explore them further in Revit API documentation.
**6. Exceptions**
Next you'll find a list of common exceptions related to selected **Class/Attribute**.

Honestly, you don't need to check this section unless you start getting errors and you want to better understand what's going on. Personally, I rarely look at this section myself...
**7. Members**
Lastly, you'll find a list of all members related to a class like **Properties**, **Methods**, **Constructors **and their description.

You can also find out if these attributes are inherited from other classes, or if the field is empty it means that it comes specifically from the selected class.
Also, there is a quick search bar on the top to help you find what you need fast.
**8. Overload List**
Lastly, you can also encounter **Overload **lists.

This means that selected attribute can have various use-cases and might require different amount of arguments.
Read the description to understand the difference and find the one that suits you better.
e.g.
You can see that there are 5 **Wall.Create **methods to choose from. IT depends if you want to have default wall type, or you want to specify it yourself.
You'll get used to that.
## How to use it quick?
Normally, when you work with Revit API Docs you'd find the class/method that you need and then look straight at the **Syntax **or **Example** section. This is the quickest way to understand how to use it.
On top of that, do not ignore **Remarks**. They often contain useful information that can save you a lot of head ache later on...
This information is enough to get back into your code editor and continue writing your script.
But feel free to explore the rest if you need to, especially in the beginning.
## What's New Section
Each year we get a new version of Revit and it also affect Revit API. And it's important to be up to date to make changes to your scripts.
You can find all of this in the **What's New** Section when you select an API version from the home page.

Inside you can find:
- **What's New?**
- **What was removed?**
- **And API Changes**

If you're a beginner, you can completely ignore this for now. Just focus on the Revit version which you actually use in the office, and then update your scripts as you find errors in your code.
Also, you can check my videos where I break down these changes to help you understand what's new.
- [**What's New in Revit API 2026**](https://youtu.be/2mcKrC8rEy4)
- [**What's New in Revit API 2025**](https://youtu.be/qixF31Xa9JI)
And in case you have changes that affect your code, you can write different code for each API version to avoid any errors. Here is the code snippet for that:

## P.S.
Later, I'll make a comprehensive video tutorial on **RVTDocs **to help you understand it even better.
Meanwhile you can watch an exclusive video tutorial as a bonus. 👉[**Click Here**](https://youtu.be/zphX6y73F9g) to Watch.
It's for older docs website, but you'll get an idea.
### ⚙️Understand the Process of Creating Great Revit Add-Ins.
https://learnrevitapi.com/newsletter/understand-the-process-of-creating-great-revit-add-ins/
Think of your **Dream Tool for Revit.**
You hover over the button, 'CLICK' and then magic happens that makes your life so much easier.
- But how do we make that happen?
- Is there a process that can help you?
And you bet there is!
Let's look into my 4-step process of creating great Revit Add-Ins.
## 0. Understand the Process
Let's start with a 30,000-foot overview of steps involved. This will help you see a bigger picture and analyze where you need to pay more attention.
For example when I create new Revit Add-Ins, I have 4 stage:
- **Brainstorm the Idea**
- **Research**
- **Code Dirty**
- **Refactor Code**
Each of these steps helps me prepare for the next one and sometimes it can save me a lot of hours of hard work.
Other times I jump straight into coding, and then I might regret not doing the research... Or I might already know enough from previous coding sessions.
But let's cover all these stages one by one.
## 1. Brainstorm an Idea
**It all begins with an idea,** **or a problem...**
Firstly, we need to brainstorm what we are trying to achieve and how are we going to do it?
As a rule of thumb, think of all the steps you do manually to get the same result. And pay attention to the little details that you might do automatically without even thinking.
This is where **abstraction** comes into play.
In code, **abstraction **allows us to break down a big problem into smaller, manageable pieces. Each piece handles a specific task, so you don't have to worry about other steps while you make it. This makes your tools easier to build, understand, and maintain.
For example, if I want to automate hundreds of apartment plans, I might come up with a plan like this:
- Get all rooms in project
- Sort rooms by apartment number
- Create View for each apartment
- Change CropBox to only see one apartment
- Create Sheet
- Place View on Sheet
- Write Sheet Parameters
That's a good start.
There are more small steps involved in between, and you are welcome to add them in, but they will also become more obvious as you code.
But once you have a general idea it's time to research the solution
## 2. Research
"**Give me six hours to chop down a tree and I will spend the first four sharpening the axe.**" - Lincoln
We have an idea or even a simple plan in our head. Now, it's a great idea to see if something similar was already done before.
You don't want to spend couple of days creating a tool, and then find a blog post or a video that provides 80% of a solution you needed... That happens!
So have a look around if something similar was done, or if there are answers to tricky parts of your plan.
- Search on Google
- Search on YouTube
- Check on Forums
- Ask ChatGPT
- Ask the community (👀 that one feels like cheating)
Even if you can't find similar tool, try to find solutions to specifci steps in your plan, especially if you don't know yet how to do them.
For example, you might be curious about changing CropBox to only see one apartment. So, you might explore this step in more detail. And you might find a few solutions across many blog articles (save those for later).
The goal of research is to get clarity and even find solutions to parts of your code that you are about to write.
And then the fun begins:
## 3. Code Dirty
Finally we are opening a code-editor, and I want you to have this mantra spinning in your head on repeat:
**"Build it fast, fix it later."**

This is a step where I try to get to a** proof of concept **as fast as I can. I don't care how my code looks, if my variables are named well, or if I handle errors...
I just want to see a quick result, even if it's not perfect. I need proof of concept before I commit more time to this idea.
You can't even imagine how much** time developers waste **trying to perfect first first steps** **and they can't even achieve the final result. Or they change the logic of the whole tool in the process...
For example, I vividly remember how I spent many days trying to make my UI form look pretty, way before I knew if I could make the rest of the code work.
Spoiler alert: I never finished that tool... But i learnt a lot of new things, so it wasn't waste of time either.
So let me repeat one more time: **"Build it fast, fix it later."**
## 4. Refactor Code
Alright, by this point you should have a proof of concept.
You should click on a button and get some result. It might not be perfect or exact, but you can see a potential. Now it's time to refactor your code and make it better.
**Refactoring is **the process of rewriting and restructuring your code to improve its readability, maintainability, and efficiency, without changing its functionality.
Now you can focus on all the little details and make sure that everything works, users won't get errors and your forms look pretty.
But also, don't over do it. As you know, programmers are never happy with their code. You will always think "Damn, I should have done it differently, or I should improve this part..."
But guess what?
After you refactor, you might get the same though again "I should have made this better...".
Don't get into a trap of perfecting how your code looks. Just make sure it works, doesn't break and move to the next one.
And step by step you'll create a lot of amazing tools for Revit to help you and your team on daily basis.
## Summary
So whenever you get an idea for a tool, do this:
- Brainstorm and break big problem into smaller steps
- Research for similar solutions
- Code fast and dirty to get proof of concept
- Refactor in the end to make it work well
And then you can repeat the same process on the next tool.
### 💌Why Did LearnRevitAPI Newsletter Stop?
https://learnrevitapi.com/newsletter/why-did-learnrevitapi-newsletter-stop/
It's been a while since the last newsletter...
To be honest, I was overworked and took too many projects at the same time. So I thought I share what's going on and why it's 100% worth waiting for.
You'll love this!
## My Most Ambitious Project
I had this idea in my head for over 3 years, and finally the time has come. I'm working on a **Free Python Course for YouTube**.
I started with a plan for a 3-hr course, but I got too exciting teaching Python so I started adding more lessons I wish I watched when I started...
I already spent many months and created 7 hours of fully edited content for the course (it's nuts). I have another 7 lessons on the way before I publish it.
So, very soon you'll see a new ~10-hr Python Course on YouTube for absolute beginners and people who already code. I go really deep into python.
This was my little dream to make a proper python course.
And before I finish the course, you have a chance to contribute to it. *"****What is the #1 thing you'd want to see in a Python Course?"***
**Hit Reply, I might add your idea to the course!**
## What about Revit API Newsletter?
Good News: I'm about to start newsletter again!
Great News: I'm thinking to write it like a mini Revit API Email Course. So I'm going to start with the basics and teach you Revit API from the beginning one step at the time.
So keep an eye on the inbox, it can help you a lot.
## P.S.
If you're an active newsletter reader, I'd appreciate if you would reply and let me know what do you enjoy the most in my newsletters.
**Because if you do, you might get more of that in your inbox.**
Hit Reply!
### 🗺️Here’s How I’d learn Revit API if I had to start all over again
https://learnrevitapi.com/newsletter/here-s-how-i-d-learn-revit-api-if-i-had-to-start-all-over-again/
I just saw an alien crime👽.
Men in Black are after me. What if they get me and also erase all my Revit API knowledge...
I have to leave notes, or a roadmap on how to get it back. So, this is exactly the newsletter I'm going to send myself if they flash my memory.
They got me. Boom💥

Wake up.
Follow this to Learn Revit API,
this will change your career!
## #1: Start with the boring stuff
Most Revit users jump straight into Revit API without understanding programming fundamentals (*myself included...*).
This leads to bad code, a lot of frustration and even giving up thinking Revit API is too hard, when they actually struggle with Python basics...
To avoid this, invest a few weeks in Python basics.
Understand the core concepts like data-types, loops, functions, classes, error handling and others.
**This foundation will make everything else 10x easier.**
Don't know where to start?
I'm working on a full FREE YouTube python course for Revit Users. It'll help you focus on what really matters and finally learn python for Revit.
*Meanwhile, you can start with other free python courses.*
## #2: Steal Like an Artist
Once you become better friends with Python, it's time to get into Revit API, right? **Wrong!**
There are thousands of working code samples for pyRevit and it would be stupid to ignore them. Do not reinvent the wheel, instead - **Steal Like An Artist**.

Go through code samples in pyRevit and GitHub and copy tools you find useful for your work. It's a great way to quickly build a prototype toolbar and show it to your team.
And don't worry if Revit API is still confusing, at this stage you're creating a library of working code samples that you'll study and reuse code for your new tools.
Use Chat GPT to:
- Understand Code
- Identify core API concepts
- Learn from examples you actually need
**Here is the best prompt to help you:**
> **NB** I want you to act as a seasoned Python software engineer with extensive expertise in Revit API and pyRevit. I will provide a piece of existing pyRevit code, and I need you to:Provide a short and clear code overview outlining all the steps.Describe all Revit API concepts used in the code, offering beginner-friendly examples where necessary.Write a step-by-step tutorial tailored for a beginner pyRevit user, explaining each section of the code in simple terms.Here is the code:{PASTE CODE HERE}
Why it works?
1. It explains code in plain English (no bs)
2. It identifies core Revit API concepts you need to know
3. It generates a tutorial for beginners based on the code.
💡*The secret sauce is to ask it to make a tutorial from the code.*
## #3: Focus on Core API Concepts
Alright, by this point you already making a progress.
✅ Python Basics
✅ Custom Toolbar with tools
✅ Starting to learn about Revit API
Now it's time to double down on Revit API core concepts.
Keep in mind that Revit API is huge, that's why it's so powerful. But there is no way to know everything and you don't have to. Focus on understanding the core classes like:
- **Element**
- **Parameter**
- **Selection**
- **Transaction**
- **FilteredElementCollector**
- And a few others...
These core concepts will be enough to start creating a lot of simple tools and begin saving time.
**Here is the proven roadmap from LearnRevitAPI.**

This roadmap will teach you the core basics one at the time. No need to be overwhelmed trying to learn all at once.
Each concept is built on the previous one so you keep adding them together and see how everything fits together.
And if you miss any of these steps, you will be limited in what you can achieve. So it's worth following it step by step and not jumping too much ahead of yourself.
Just make sure you practice as you learn these concepts. Theory alone isn't worth much, you need to put it to use.
And if you want to take a shortcut, consider joining training programs that will guide you through all the basics and provide plenty of practical examples.
## #4: Code Fast and Dirty
And finally, it's time to create lots of tools.
Avoid a common trap. When new devs start creating tools, they often want to create 'Revit Killers' with every new add-in. That doesn't work.
If you only focus on large tools, you're more likely to get stuck, waste a lot of hours and get disappointed. Some even quit...
Instead, focus on small wins. That's how you build a great foundation and keep your confidence high. And as you create lots of tools you'll learn a lot of about Revit API.
Apply MVP when you create your tools, which stands for **Minimum Viable Product**.
The idea is to focus on the absolute basics and essential functionality of your tool and develop it as fast as possible. That means you need to code quick and dirty until it "kind-of works".
And once you know you can get to the end, then we can focus on optimization and making it prettier.
Overtime you'll create plenty of small tools and you'll begin joining them together to create much bigger and more powerful automations.
**Code Fast and Dirty and create lots of little tools to learn.**
## What about AI?
A lot of people think AI is great at writing code. And that's true - and false (at the same time).
AI is amazing at coding, IF you can provide the right context and ask good questions. And the more context and explanation you provide, the higher the quality of the code output AI generates for you.
Which means... if you don't understand how to code on your own, and how to think as a programmer, you'll never be able to figure out how to leverage AI the best to automate Revit.
SO make sure you have a good understanding of Python and Revit API basics. This will help you write good prompts.
AI is great at writing first 60-80% of the code, but at certain point you have to take the lead. Do not blindly copy-paste AI code without understanding what's going on. That's a recipe for disaster.
**Always stay in control of your code.**
## P.S.
**Let me know your #1 challenge with Revit API**.
I'd love to hear from you so I can help you go to the next level sooner. **Hit Reply.**

### 💡What if I told you that there are thousands of code examples to learn from?
https://learnrevitapi.com/newsletter/what-if-i-told-you-that-there-are-thousands-of-code-examples-to-learn-from/
**⚠️WARNING!**
We're about to open a pandora box for pyRevit developers. I have to warn you that there is no way back.
I'm about to do the unthinkable, and show you where you can find** thousands of working code samples.**
Copy, Paste, Learn, Steal, Improve, Optimize.
You can do anything with them!
Ready to open the **Py**ndora box?

## What's the trick?
**pyRevit is Open-Source.**
It means that you have access to every single line of code behind this marvel.
Use a simple **[ALT + CLICK] **shortcut to open source folder.
- Hover over any pyRevit button
- ALT + CLICK
- Check out the source code

And it works for all additional extensions like **EF-Tools **and many others.
## But There Is More🚀!
What if I told you that you can find hundreds more extensions? You'd think I'm crazy, but I'll prove you wrong.
Here is the trick:
- Open GitHub
- [Search for 'pyRevit'](https://github.com/search?q=pyRevit&type=repositories)
- And Explore 320+ open-source repositories
Copy, Paste, Learn, Steal, Improve, Optimize.
You can do it all!

Even if only 10% are worth copying, you're still going to find 32 pyRevit extensions. That's a lot of code examples.
In 2 words - Beginner's Dream 🤯.
## P.S.
That's a lot to take in, but it's real.
Stop pinching you arm trying to wake up. It's time to explore working code samples. Go!

See ya✌️!
### 🙋♂️Why One Revit User Became Senior BIM Specialist While The Other Stayed Behind
https://learnrevitapi.com/newsletter/why-one-revit-user-became-senior-bim-specialist-while-the-other-stayed-behind/
Five years ago two Revit Users started their career in AEC firm. They were very much alike.
Both had been better than average with Revit and their understanding of construction, both were dedicated and wanted to advance their careers.
**But there was a difference. **One of them had become a Senior BIM Specialist leading the team. The other was still doing the same manual work as five years ago...
## What Made The Difference
Have you ever wondered, what makes this kind of difference in people's careers? It isnt't native intelligence or talent or dedication. It isn't that one person wants success and the other doesn't.
The difference lies in how each person look at a problem and how they decide to solve it. It's the knowledge on how to solve problems at scale that sets them apart.
And that's exactly why I write my Revit API newsletters, share my educational content and why I created **LearnRevitAPI platform**.
To give Revit professionals the **knowledge on how to automate **their work **and break through Revit limitations**.
## A Training Platform Unlike Any Other
You see,** LearnRevitAPI Academy **is a unique training program. I can confidently say that it's the most comprehensive Revit API training for people who want to use pyRevit.
Why? Well, I doubt that any other person would spend more than 3000 hours on creating a training platform for Revit API.
And the best part? It's still not finish. I keep adding modules, updating lessons and I even added 2 extra bonus courses for free to address the common concerns my students had to provide better experience.
That's why when you join you get multiple courses:
- **LearnRevitAPI Basics Course**
This course is for absolute beginners to give a solid foundation of pyRevit, Python and Revit API Basics.
- **LearnRevitAPI Advanced Course**
This is the flagship course that goes really deep into Revit API. Each module starts with the theory and then I always make sure to back it up with practice. So you will learn a lot by creating custom tools with me.
- **LearnRevitAPI Modern UI Course**
Lastly, you also get a bonus courset to learn how to create custom UI forms with WPF to provide the best user experience and create unique workflows.
Each course is made for Revit users at different stage of their programming journey.
So, no matter where you are right now, even if you are just starting, or you already created a few tools, you will all benefit from this training a lot.
## What if I get Stuck?
I hear this a lot.
This is something that stops many people from joining a program. They think the training is good, but they have doubts in themselves and afraid of getting stuck
And that's exactly why you will also be a part of a **LearnRevitAPI Community. **This is a place where you **get direct access to me and hundreds of other developers**.
Whenever you feel confused or stuck, just ask a question and we will help you progress along the course.
Many found the community the most valuable part of the training, because it provides a fun and supportive environment and makes sure nobody is left behind.

If you have never experienced comprehensive Revit API training, you cannot imagine how transformative it can be for your career.
## P.S.
About these two Revit users I mention at the beginning.
They graduated from the same uiversity and together they started their careers in architectural office. So what made their lives so different in AEC world?
**Knowledge. Useful Knowledge. And it's application.**
### 📢LearnRevitAPI 2.0 Update: New Lessons and Platform Upgrade
https://learnrevitapi.com/newsletter/learnrevitapi-2-0-update-new-lessons-and-platform-upgrade/
Hi everyone,
I'm currently working on LearnRevitAPI 2.0 update and I want to let you know what's coming:
- New Lessons
- Updated Modules
- Improved Platform
- Certificates
- And something special many were asking!
Let me explain
## Platform Upgrade
Firstly, you will notice that navigation in **LearnRevitAPI Advanced **Course has been updated. Unfortunately, you'll lose the track of your previous progress because I changed the backend logic.
Now each module is a card with a progress bar on the bottom to make it more motivating to keep learning.

P.S.
There are a few bugs and time delays with tracking but it works. I'll fix JS code that handles it when I have more time. Let me know if it's a dealbreaker.
## New Lessons + Modules
Also I've just uploaded ~3 hours of new content on the platform.
- **Module 03 - Selection **(Updated)
This module was completely re-recorded to make it better and include a few more tips and tricks.
- **Module 04 - Look Inside (New)**
This is a new module where I focus on Revit Lookup and how to read properties and methods from elements. There will be a few more lesson in this module soon.
- **Module 06 + 07 (Combined)**
I've also merged 2 modules together (**FilteredElementCollector **and Filters). It makes more sense to keep them together.
I'm going to update many other modules and then focus on creating new ones.
**Let me know what I should focus on first.**
## Why updating?
I've had a few people reach out to let me know that some of my content is too fast-paced and hard to follow. So **I slowed down **and I want to update the lessons.
Also I want to use n**ewer Revit version** (2025) and **I learnt a few tips and tricks since first videos**, so I want to share them as well.
In general, I want to make your learning experience better.
P.S.
New lessons that have the same topic as the old ones will include both New and Old videos in case you want to watch it twice or prefer older format.
## Certificates of Completion
This has been ready for a while but I was postponing the announcement. So now is the time.
Here is how it looks:

You can [**Request Certificates Here**](https://learnrevitapi.com/certificate-request)
## ✨The biggest feature
Lastly, I'm starting to translate audio of my new content into multiple languages:
- English (Original)
- German
- French
- Spanish
- Portuguese
This is not a cheap feature in terms of time and money, so I'll only translate the new content at first. Starting with [**Module 03**](https://learnrevitapi.com/courses/advanced/m03)[ ](https://learnrevitapi.com/courses/advanced/m03)and [**Module 04**](https://learnrevitapi.com/courses/advanced/m04). You can already check them out!

If you are a native speaker, please let me know the quality of translations please.
## P.S.
Quite many changes and even more to come. I'd appreciate to hear your feedback about the platform and courses overall.
### 💡Pro Tip: How to Easily Get CropBox to Rotate Views with Revit API
https://learnrevitapi.com/newsletter/pro-tip-how-to-easily-get-cropbox-to-rotate-views-with-revit-api/
I want to share a quick tip on how to rotate views using Revit API.
As you know, we need to grab a **CropBox **to rotate the view orientation. And if you tried it with Revit API then you realized that [**view.CropBox**](https://rvtdocs.com/2025/d6246051-ecfb-7388-0429-6ed65de72638) just gives you the **BoundingBoxXYZ **and not the actual **CropBox **Element...
In the past I used an overcomplicated workaround, but recently I tried a simpler approach and it worked like a charm.
Let me share how to rotate views with API.
## #1 Get CropBox
When you create a **View **in Revit it also creates CropBoxes as separate objects. And it means that **CropBox Id **relates to **View Id **and it always has the same difference.
So, here is the trick:
**Get Id of a view and then increment it by 2 to get ElementId of a CropBox. **That's it.
*e.g.*
*view.Id = 13642*
*cropbox.Id = 13642 + 2*
Here is a simple code snippet to test:
💡P.S.
This works well for **ViewPlan**.
**ViewSection **might have different offset. I haven't tested, but someone mentioned it's view.Id -1 instead of +2.
## #2 Rotate View
Now you have the **CropBox **element, now it's same as Revit UI, we just need to rotate it with the desired angle (in radians!)
For that we need to use [**ElementTransformUtils. RotateElement**](https://rvtdocs.com/2025/3968f4e8-759c-f975-6c1f-7de42be633ed).

It needs 4 arguments:
- Document
- CropBox_id
- Rotation Axis (vertical line)
- Angle in Radians
Here is a code where I take the **BoundingBox **of a **CropBox **and calculate a **Centroid**. Then we need to create a simple line that will represent the axis.
After that we just use all arguments to rotate.
Here is the code:

P.S.
If rotation looks off:
- Ensure angle is in **Radians**
- Try rotating in opposite direction (**negative angle**).
## Why not use View.CropBox?
Some people might try to use [**View.CropBox**](https://rvtdocs.com/2025/d6246051-ecfb-7388-0429-6ed65de72638) property, but you will instantly realize that it returns a [**BoundingBoxXYZ**](https://rvtdocs.com/2025/3c452286-57b1-40e2-2795-c90bff1fcec2)** **and not the actual **CropBox** Element.
So, you won't be able to use that to rotate your view.
But don't worry. When I tried to rotate view for the first time, that's exactly what I tried to do as well. And I learnt really quick that's not the way to do it.
But luckily, now you know how to do it 👻.
## P.S.
I used this workflow in the new tutorial where I show you how to Automate Sales Plans in Revit.
[**Click here**](https://youtu.be/6zRY7yPktR0)[ ](https://youtu.be/6zRY7yPktR0)to watch. (This workflow is used at 54:40 timestamp
### 🚀Master Sales Plan Automation in Revit (Beginner-Friendly)
https://learnrevitapi.com/newsletter/master-sales-plan-automation-in-revit-beginner-friendly/
I want to help you save hundreds of hours like it saved me when I worked on a high-rise project with nearly 500 apartments.
It might be the **Best One Click Tool** you use inside of Revit.
[**Click Here**](https://youtu.be/6zRY7yPktR0) to Automate your Sales Plans in Revit.

## Automate Sales plans in Revit
Overall it's an advanced workflow but I made sure to simplify it so anyone can follow along with absolute basic understanding of pyRevit and Revit API.
During the tutorial I will teach you how to:
- Collect and sort rooms by apartments #
- Merge BoundingBoxes into a new CropBox
- Generate new FloorPlans
- Apply the correct View Rotation
And as a result will you generate hundreds of sales plans in one click.
### Are you making any progress with Revit API?
https://learnrevitapi.com/newsletter/are-you-making-any-progress-with-revit-api/
How long have you been trying to learn Revit API?
A year? Two years? Five months? One month?
Just got started?
A lot of people read documentation, watch YouTube tutorials, and copy-paste code snippets over and over only to see no real progress with custom Revit tools.
(And they have no idea they're doing things the hard way.)
## Why They Fail?
The reason this approach leaves people feeling frustrated is because it lacks structure and progression.
You end up with fragments of knowledge but no clear understanding of how everything fits together. It's like trying to assemble a puzzle without knowing what the finished picture looks like.
That's why in I teach AEC professionals a step-by-step approach so they learn the basics they need, but everything builds on top of each other and fits together.
Instead of jumping around randomly between unrelated concepts, you follow a carefully designed learning path that builds your skills in the right order:
1. First, You can't skip Python basics (This one is too common)
2. Then, you need core Revit API concepts that you reuse in 90% of all your scripts.
3. Finally, you need to see how it's all used in practice. Revit is full of workarounds, and so does Revit API. And once you see it, it's like you finally found the missing puzzle piece.
Of course, there is an learning curve to learning programming for Revit. Otherwise, everyone would do it and get results immediately. **But with AI, this barrier of entry is reduced by a mile.**
There are many people who start creating custom tools with AI. But you also see them hitting the wall the moment they try to create something unique or advanced or when AI starts to hallucinate (which happens more often than you think).
A lot of people copy complex examples or even AI nonsense without understanding how it works to have full control over it. And sometimes they even mess a lot of things because in real projects because of lack of understanding.
## How to learn instead?
The key is actually learning through small, complete projects that gradually increase in complexity.
Each project should teach you just ONE new concept while reinforcing what you already know. This "stacking" approach ensures you're never overwhelmed and can see immediate results from day one.
That's what you need to learn in order to be successful.
- Is your approach to learning Revit API not working?
- Are you tried seeing no results after all this time?
- Do you feel like something is missing?
- Or maybe you are just starting, and you want to make it right and avoid mistakes that hold beginners back?
If this sounds familiar, you're not alone.
I've helped more than 500 people inside LearnRevitAPI by simplifying the core concept and teaching everything in a structured and easy to follow roadmap with a lot of practical examples. And I'd love to help you do the same.
[**Click Here to follow the proven roadmap to LearnRevitAPI.**](https://learnrevitapi.com/)
See you inside.
### 🎯Revit API Starter Kit: 7 Code Samples Beginners Need to Know
https://learnrevitapi.com/newsletter/revit-api-starter-kit-7-code-samples-beginners-need-to-know/
Hey there!
Today, I want to share Revit API code samples for beginners to get started quick. We're about to get into nitty-gritty stuff.
Why?
Because I know from personal experience how overwhelming it can be to start working with Revit API and I don't want you to get discouraged.
These code samples will make it at least 10X easier to begin on the right path. I wish I had them when I first started banging my head against the Revit API docs.
So, here you go:
## #1 Selection Basics
Let's start with the **Selection **class so you know how to get elements with code. This is a great first step into API. Afterall, we need to get some elements with code to test all other concepts.
So, here is how to do it:
In the Docs you will find **Selection** **methods **to get user selection or prompt certain selection method. But we need a Selection instance related to a project. And we can get it from **uidoc** variable.
Here is a code sample:

Let me break down what's included:
- Example on getting **Selection **instance.
- Get User Selection (with optional Filter)
- Pick Single Object
- Pick Multiple Objects
⌨️ Copy one part at the time and test them in your own code.
## #2 Master Getting Element
In case you want to get all elements of certain categories (like walls, rooms...) then you would need to use **collectors **in Revit API.
Here is how it works:

FilteredElementCollector might look and sound intimidating, but it's one of the most repetitive classes in Revit API. So it's easy to remember.
In general there are 4 steps:
- **Create** **collector **by connecting to your project (**doc**)
- Filter with **OfCategory** or **OfClass**
- Optionally filter **Instances/Types**
- Lastly, convert to list of **Elements **or **Element Ids**.
That's it. Now you can apply this principle to get any elements in the project.
Here are many examples

💡Notice how repetitive it is. I specifically marked the parts you need to change to get different results. Now it's not so complicated, isn't it?
P.S. You can [check this free tutorial](https://www.youtube.com/watch?v=MfJTPIOo7nY) to learn more.
## #3 Look inside Elements
Once you get elements you can look inside of them. But before you pull up your code-editor, make sure you look inside with **Revit Lookup.**
**💡Revit Lookup - **is a free Add-In that let's you look inside your elements to understand Revit API names and the values you can get. **(Must have for any Revit API Dev)**
It's simple to use.
- **Select **elements in Revit UI
- Go to **Add-Ins** tab
- Select **Snoop Selection** in RevitLookup

And then you will see this UI menu with all the information about selected elements. This is a life saver.

Inside you can navigate and explore your elements:
- Properties
- Methods
- Parameters
- Most importantly - Returned Values
**💡I always use it before I open my code-editor.** It will help you get a better understanding on how to get the right values with API.
## #4 Read Values with Code
After I found what I need in **RevitLookup** I can get the same values using code. And for that you need to understand how to read **Properties** and **Methods **in OOP.
Here is an example:

Let's breakdown:
- We need basic imports and variables
- Then we will prompt user to Pick an object
- And we will read various properties.
💡In RevitAPI we often work with **ElementId **to be memory efficient. Therefore, we need to convert into an actual **Element **to access all the values it holds. And then it's the basic OOP workkflow.
New to OOP? Don't worry, check [**this tutorial**](https://www.youtube.com/watch?v=Qi4yo86piec)[ ](https://www.youtube.com/watch?v=Qi4yo86piec)for Revit API beginners.
## #5 Parameters in Revit API
Next, you need to keep in mind that Parameters and Properties aren't the same. There is a property called **Parameters, **which contains a list of element parameters.
**Property** - Is an attribute associated with a class/instance that can hold data. We can access it like: **element.ParamName**
**Parameter **- is similar for Revit users, but for developers it's a completely different object associated with your elements. First you need to get the right parameter and then use Parameter class methods to read its values.
💡Also, keep in mind that **Instance **and **Type **parameters are located in different objects *(e.g. Wall.Parameters -> Instance / WalLType.Parameters -> Type).*** **This means you can't get TypeParameter from instance and vice-versa. You need to get the right object first.
Here is a code snippet of the basics:

*Breakdown:*
- *Regular Imports and Variables*
- *1. PickObject to test code*
- *2. How-To Get Built-In Parameters*
- *3. How to get Shared Parameters*
- *4. How to Read Values*
- *5. How to Set New Values*
## #6 Changes with Revit API
Next you need to understand that to make any changes in Revit API you have to use **Transaction **Class. It's like a gate keeping for Revit to avoid any accidental changes with code.
It means that beginners can safely explore Revit API without a fear of breaking or changing anything. And even if you try to change something, you will get an error message saying "Attempt to modify project without using **Transaction**".
And it's also easy to use.

Typically there are 2 ways to use it:
- Regular use
- Context-Manager (using **with **keyword)
## #7 pyRevit UI Forms
Lastly, I want you to be aware that pyRevit comes with a lot of dev features beginners can start using with a few lines of code.
And pyRevit's UI forms is one of those features. It's the best and very beginner friendly.
You can check this page in [**pyRevit Docs: Effective Inputs**](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056)** **that provides you short actionable code-snippets and screenshots of the forms you get. (**Bookmark it**, you will use it a lot)

To test it, just head over to the link I mentioned, find a form you find interesting and copy the code snippet into your own script. And now you have a custom UI Form for your tool.
Isn't it amazing?
## Want help (actually) putting these tips into action?
I hope you found this helpful.
And I want to remind you the most important part: Reading Revit API tips along will NOT help you automate revit like a Pro. You need to actually put them into practice.
And of course, that’s easier said than done.
So, if you’d like some help implementing all of these tips (and plenty of other proven frameworks), then I’d love to invite you inside** LearnRevitAPI Academy.**
[**Click Here**](https://learnrevitapi.com/) to join the training that will explain you every single step I mentioned in this email in more depth and with practical examples.
Join today to become 10X more productive in Revit using python.
**See you inside!**
### 🧠 3 Mental Blocks Keeping You From Mastering Revit API
https://learnrevitapi.com/newsletter/3-mental-blocks-keeping-you-from-mastering-revit-api/
Hey there!
If you're reading this right now, that means you are probably looking to automate your Revit workflows with Python.
❌ Maybe you've started learning some basic scripting, but haven't been able to create anything useful yet?
❌ Maybe you've been thinking about diving into Revit API, but don't know where to start?
❌ Or maybe you thought automating Revit would be easier, but it's taking WAY longer than you expected?
The question is: **why?**
Why haven't you seen the progress you've wanted to see?
## This holds many people back
After helping thousands people online and teaching 500+ inside my LearnRevitAPI platform, I've learned that 99% of the time what holds people back the most are certain faulty beliefs.
- It's not that they don't have enough technical ability.
- It's not that they don't have enough time to learn programming.
- And it's not that they need some "secret" Revit API trick that only experts know.
**The real reason is that they internalize faulty beliefs that stop them from going forward.**
These are the 3 big ones I see over and over again:
## Faulty Belief #1: "I need to be a 'real programmer' to use Revit API effectively."
Let's stress-test this.
Do you need to be a mechanical engineer to drive a car? NO!
Do you need to be a licensed electrician to change a light bulb? Of course not.
Similarly, you don't need a computer science degree or years of coding experience to automate Revit tasks. You just need to learn the specific skills that apply to your needs.
I've seen architects and engineers with zero programming background create powerful Revit tools within weeks of starting. Heck, I was one of them!
The truth is, most Revit API automation requires only basic programming concepts that anyone can learn. And I like to say *"you don't need to be an expert to begin coding, but you need to begin coding to become an expert." - EF*
See, it doesn't make any sense to think you need to be a "real programmer" first. **This is a faulty belief.**
## Faulty Belief #2: "My first tool needs to be perfect and comprehensive."
This is another "myth" I hear ALL the time.
But after doing this for 6 years, I can assure you this is just another faulty belief.
Most successful Revit API developers started with incredibly simple tools - things that just automated one tiny piece of their workflow. They didn't try to build the perfect all-in-one solution right away. And they still saved a lot of time with their first tools.
The developers who make the most progress are those who focus on small wins first. They create a tool that saves them 5 minutes per day, then another that saves them 10 minutes, and before they know it, they're saving hours every week.
There's no such thing as a perfect first tool. The best first tool is the one you actually finish and use on your real projects. **That's a win you need to begin with.**
## Faulty Belief #3: "The Revit API is too complicated and constantly changing."
This one actually makes me MAD.
Yes, the Revit API is extensive - that's what makes it powerful. But 95% of what you'll do uses the same core concepts and classes that haven't fundamentally changed in years.
The truth is, once you understand **Selection**, **Parameter**, **FilteredElementCollector**, **Transactions**, and a few other core concepts, you can build a lot of custom tools. And contrary to popular belief, Autodesk doesn't completely rewrite the API with each release, they introduce minor changes and add more features.
Remember my Roadmap?

And trust me - every day I see complete beginners mastering these core concepts within weeks, not years.
I can assure you - this is just another faulty belief!
## Here is the thing...
You will never overcome these faulty beliefs by reading more documentation or watching more YouTube tutorials alone.
Because if you could, you would have already.
Which means, if you want to see different results, you have to take different ACTIONS. **And this means opening a code editors and writing code using Revit API. **Learn by Doing!
And I'd love to help you and provide you everything you need and give you shortcuts so you can save yourself years of learning everything the hard way.
[**Click Here**](https://learnrevitapi.com/)** **to join **LearnRevitAPI** and begin your Revit Automation Journey to become x10 more productive.
### ✅ The 5 Skills That Top Revit Performers Are Learning Now
https://learnrevitapi.com/newsletter/the-5-skills-that-top-revit-performers-are-learning-now/
Hey!
There are Revit Users who are going to struggle A LOT over the next 5 years.
Who?
The "Manual Revit Warriors" who don't stop...
- Spending hours on repetitive tasks they could automate
- Relying solely on out-of-the-box Revit functionality
- Rejecting programming as "too complex" or "not for them"
- Making the same frustrating workflow mistakes over and over again
Things are changing fast in the AEC industry.
Which means you now have to choose...
## Old Way vs New Way
Do you want to stick to your old ways and struggle? Or are you open to learning Revit API and thrive?
Yes, it's going to be that black-and-white.
All the Revit users who pretend things are the same way they were 5 years ago are going to spend a lot of time complaining about how tedious and time-consuming Revit is and that Autodesk need to develop more features.
As a result many end up burning out or settling down for mediocre workflows.
And all the Revit users that decide to finally change and embrace automation are going to be so overwhelmed with the opportunities that come their way, they won't even have time to think about the way things used to be because they will end up as the highest-valued team member as a result.
The question is:
**Which camp are you going to be in?**
If it's the latter, **here are 5 skills you should start learning NOW** to start putting yourself on the right path:
## Skill #1: AI is not replacement
A lot of people think AI is great at writing code.
And that's true - and false (at the same time).
AI is amazing at coding IF you can provide the right context and ask good questions. And the more context and explanation you provide, the higher the quality of the code output AI generates for you.
Which means... if you don't understand how to code on your own, and how to think as a programmer, you'll never be able to figure out how to leverage AI the best to automate Revit.
For example, check this out:

This is a roadmap from** LearnRevitAPI Advanced course**. It's build in a way to teach you the most important concepts of Revit API so you understand how to use it to automate your work.
If you miss any of these steps, you will be limited in what you can achieve. But it also means that you won't be able to communicate with AI correctly, because you won't know how to structure your question and you will blindly copy the code and have no idea how it works.
But once you know it, **AI will be your best friend for the first 80% of your script.** And you will know more than enough to complete the last 20% of the code.
## #Skill 2: The Basics you can't skip
Most Revit users jump straight into API tutorials without understanding programming fundamentals.
This leads to bad code, a lot of frustration and some even give up thinkign Revit API is too hard, when they actually struggle with python basics.
Instead, invest a few weeks in Python basics - understand data-types, loops, functions, classes, and error handling. **This foundation will make everything else 10x easier.**
I teach python to Revit Users - giving you just what you need without overwhelming you with other computer science and not so useful concepts. This way you learn fast and focus on what really matters.
## Skill #3: Computation Thinking
**Programmers are not just coders, they are problem solvers.**
Most people think of programmers as hackers who sit in front of screens and hit keyboard like crazy non stop.

**This is WRONG.**
It's like thinking of architects and engineers as drafter. Sure, we all draft on plans, but that's the simplest step after all the hard work is done. Same with programmers.
**One of the most important skills for a programmer is problem solving.**
It requires them to recognize patterns, break big problems into smaller steps, abstract the solution and then creating a plan on how the automation will work. Coding is the last step after lots of thinking that spins the gears of your automations.
Luckily for you, this skill comes naturally as you start to code more often and solve more problems. Many people don't even notice how their thinking changes to computational thinking when they are faced with a problem. But it happens to every programmer. And it's a great skill to have.
## Skill #4: Code Fast and Dirty
When new developers create new tools, they often want to create a Revit Killer with every add-in they write. So they spend weeks on a single tool trying to write each step perfect from the start and then realize that they are over their heads. (Don't worry I did it too... It's natural once you get this power)
Instead, you need to understand the **MVP concept**, which stands for **Minimum Viable Product**.
The idea is to focus on the absolute basics and essential functionality and develop it as fast as possible. That means you need to code quick and dirty until it "kind-of works".
And once you know you can get to the end, then we can focus on optimization and making it prettier.
This is the best way to create new tools, because often times once you get to the end, you will decide to do it differently anyway. So, why waste hours optimizing something you are going to delete anyway.
**Create MVP, then make it pretty and optimized.**
## Skill #5: Stop Fearing Errors
Some people panic when they see an error message and often abandon their automation attempts altogether.
This fear keeps them trapped in tedious manual workflows forever.
Instead, embrace errors and learn how to handle them. We need to always anticipate issues, add useful user messages and debug then in case they happen.
When I code, I often encounter errors, and that's part of the process. We need to understand how to read errors and solve them for good.
And while in the beginning it might be confusing, over time you get used to them so much that you instantly know what's the problem with the code the moment you see red text in the console.
## How to Learn Faster and Easier?
When you join LearnRevitAPI, you will pick up these skills as you progress through the course instead of wasting days on figuring thins out on your own.
My goal with Learn Revit API is to give you everything you need to become the automation expert at your firm.
Which is why I've made sure to include:
- **LearnRevitAPI Basics - **Best Course for beginners
- **LearnRevitAPI Advanced - **Deep Dive into Revit API with more in-depth lessons with practical approach.
- **LearnRevitAPI - Modern UI - **Course that teaches you how to create custom UI forms to provide better user experience
- **LearnRevitAPI Community **- A place where you get direct access to me, connect with hundreds of other developers and you can ask for help when you need it the most.
So, are you ready to finally stop wasting time on repetitive Revit tasks? [**Click Here**](https://learnrevitapi.com/) to Join.
### 📅 Where you could be one year from now…
https://learnrevitapi.com/newsletter/where-you-could-be-one-year-from-now/
Let's fast forward.
**It has been a year since you started automating Revit using Python.**
You've become more productive and your career is growing faster as a result.
Not because you moved away from AEC industry where everyone is underpaid and underappreciated. But because you dedicated 30-60 minutes to coding every day.
Little by little, day by day, week by week, month by month - until all of a sudden, you've created a massive toolbar of custom tools that can **Automate Revit at will.**
And your entire life has changed as a result.
## Change #1: You're the go-to Revit Expert in the office
You've forgotten what it feels like to spend days on repetitive tasks clicking your life away like a zombie.
You don't waste time manually updating parameters, creating hundreds of views , looking for issues in your models and lots more.
Instead, you follow a systematic approach to identify patterns in your work and automate them. You custom tools can save you and your team countless hours every week.
(Your team have even started asking YOU to automate some of their boring work they hate)
## Change #2: Your coding skills have transformed beyond Revit
Learning to code hasn't just made you better at work.
It has also helped you develop skills that extend to other areas of your personal life.
Programming isn't just writing code - **it's a new way of thinking**. It's about recognizing patterns, breaking down complex problems, and finding efficient solutions that scale. This mindset naturally spreads into all parts of your life.
You now look at all problems differently. You notice inefficiencies in your routines, finances, and even vacation planning. You develop systems to optimize everything. Your digital life is organized with the same mindset you use in your code.
When friends share their challenges you look for patterns and problems, then break it into smaller managable steps, and think in logical "*if-this-then-that*" terms.
And this has slowly become one of your new superpowers both at work and home.
## Change #3: New opportunities are finding you
Since implementing your Revit API skills, your career trajectory has started to accelerate.
And now, things won't slow down.
Every week you:
- Save your team dozens of hours with custom tools that handle tedious tasks
- Get recognized by management for innovative solutions that improve project delivery
- Collaborate with other departments to solve workflow bottlenecks they didn't even realize could be fixed
- Provide unique tools that unlock new workflows specifically made for your office
- Connect and receive messages from other experts who automate Revit like you
- In general, you work smarter, not harder.
In fact, when you look back at where you were a year ago, you can hardly believe it.
You've covered so much ground, all because you learned Revit API and Python the right way and took consistent action.
## Does this story seem too good to be true?
It shouldn't.
Because all of these things can happen if you put your focus on learning this one skill that will allow you to go beyond Revit limitations and open a new way of thinking.
Many of my students have started creating custom tools after first few modules and they raised their productivity from that point on. This helped them negotiate better promotions based on their new skill. And now they are much better at solving any problems they encounter.
So I know it works and **LearnRevitAPI Academy **can help you get there.
The question is:
**Are you going to let me help you?**
**👉**[**Click Here**](https://learnrevitapi.com/) to **Join LearnRevitAPI **and learn this one skill that can change everything for you.
### ⛔Avoid these 9 most common Revit API mistakes beginners make
https://learnrevitapi.com/newsletter/avoid-these-9-most-common-revit-api-mistakes-beginners-make/
Hi There,
Probably there is something on your mind that keeps you from getting started with Revit API or Python.
The thing is - I keep hearing about the same mistakes over and over. And that's okay**. I've also made the same mistakes**, and I want to point them out so you:
✅ Become aware of them
✅ And implement solutions quicker
So, let's make sure you avoid these mistakes.
## Mistake #1: Ignoring The Basics
Majority (myself included) jump straight into creating Add-Ins before understanding Python basics. This leads to messy, inefficient code and a lot of frustration learning API because lack of basics hold you back.
However, once you learn the basics, **Revit API will go much easier**.
> **TIP** **✅ Solution:**Focus on one thing at the time. Start with Python basics until you feel comfortable with loops, functions and other core concepts.There are plenty of free courses, so make sure you find something you enjoy to better learn the concepts.*P.S.*
> *I'm going to release a ****full Python Course on YouTube ****soon which will go really in depth. I will let you know*
## #2: Overlook Documentation
Revit API documentation can be overwhelming at first glance with thousands of classes, methods, and properties. However, understanding how to navigate and read it is essential for your Revit API journey.
> **TIP** **✅ Solution:**Check [**this lesson**](https://www.youtube.com/watch?v=zphX6y73F9g) from LearnRevitAPI Course. I'll take you through the Docs and explain what do you actually need to pay attention to.Learn how to find what you needAnd how to use it in the code
## Mistake #3: Not Reusing Your Code Early
Remember:** *****"Good programmers code, but great programmers reuse code!"***
Once you start copy-pasting your code multiple times - you commited the greatest sin of programming. The goal of programming is to be efficient, and that also applies to how you write your code.
> **TIP** **✅ Solution:**Start Reusing your code as soon as possible.And if you don't know how, then check** **[**this video**](https://www.youtube.com/watch?t=33s&v=TPYIfysyyB8) where I will show you how to organize and reuse your code with pyRevit.
## Mistake #4: Ignoring Code Samples
Why reinvent the wheel🛞?
**pyRevit is open-source **with thousand code sample (if you know where to look). And it's always worth spending 5-10 minutes looking for similar code to what you're about to do, instead of starting from scratch.
> **TIP** **✅ Solution:**Find existing codeUnderstand how it worksAdjust to your own needs.💡 Use **ALT + CLICK** on any pyRevit tools to open the source folder, including additional extensions like EF-Tools.Want thousands of examples? [**Search for pyRevit on GitHub**](https://github.com/search?q=pyrevit&type=repositories)
## Mistake #5: Ignoring Backups
We all know we should back up our work, but many postpone it until it's too late. One mistake and you can lose hundreds of hours worth of code. *(it even happened to me...)*
It's not Fun to lose code!
> **TIP** **✅ Solution:**Establish a backup routine for your code.You can use services like DropBox, but as a developer you should learn how to use GitHub. Git is the best way to save and share your code.**New to Git?**
> [**Check This GitHub Training**](https://www.youtube.com/watch?t=355s&v=t9PKLbhLHqw) for absolute beginners.
## Mistake #6: Ignoring API Changes
Each year brings a new Revit version with new API features, but also potential breaking changes. Tools that work perfectly in one version might fail in another.
And while it's not often, we need to address any changes in our code so tools work in multiple versions.
> **TIP** **✅ Solution:**Test your tools across multiple Revit versions and once you find the difference, make sure you address it in your code.*P.S.*
> *I cover this topic in more depth in the second module of my course.*
## Mistake #7: Not Handling Errors
It's okay to code dirty during development, but once it works, you better implement error handling.
You don't want anyone in your office to click a button and get a huge wall of red text. That's embarassing, especially when your boss is near.
> **TIP** **✅ Solution:**✔️ Test various scenarios
> ✔️ Test multiple Revit versions
> ✔️ Use **try/except** to catch errors
> ✔️ Alert your users without scaring themThe least you can do: display a message 'Something went wrong, ask the developer.' It will be way better than crashing Revit.
## Mistake #8: Using Wrong Units
Don't forget that **Revit API uses feet internally**. So whenever you read or write values with units, ensure that you convert feet to metric or vice-versa.
A lot of people waste hours on trying to solve an issue with parameter values or coordinates, when there isn't even an issue. They just compare wrong units, good luck debugging that....
> **TIP** **✅ Solution:**🧠 Remember that you work with **feet** in Revit API.
> 🧠 Learn how to convert units.
>
> **Code sample** to convert units:
>
> 
## Mistake #9 - Not Asking For Help
Lastly, **Ask for help when you need it the most.**
Many try to do everything on their own and waste hundreds of hours and pick bad habits in the process. Personally, I spent countless evenings looking for very simple answers online.
If only there was a program back then that could save me all this time...
> **TIP** **✅ Solution:**✔️ Ask for help
> ✔️ Use forums
> ✔️ Join Community
> ✔️ Follow proven courses
## ✨The Ultimate Solution
I've shown you the top 9 mistakes beginners make. But there are many more and you can avoid all these mistakes.
How? Get the right training from the start and join a private community for help when you need it the most.
That's exactly what **LearnRevitAPI Academy** gives you.
**I made this platform with everything you need to become a Revit Automation Expert using Revit API + Python.**
This step-by-step training works for both:
- Absolute beginners
- Intermediate developers
You will learn everything without feeling lost and get quick results to wow your boss with your new custom tools for Revit.
This is not just a course. It's a library of tutorials you can use again and again. Plus, you get a community with hundreds of developer where you can get help.
[**Click Here**](https://learnrevitapi.com/) to join hundreds of other developers!
See you inside!

### 🙋♂️LearnRevitAPI was made for 3 types of people. Are you one of them?
https://learnrevitapi.com/newsletter/learnrevitapi-was-made-for-3-types-of-people-are-you-one-of-them/
Hey Revit Experts,
As you think about your Revit Automation journey, here are 10 questions that will help you decide if **LearnRevitAPI Academy** is right for you.
## ⚡Rapid Quiz:
- Do you waste time doing **the same Revit tasks over and over** again?
- Is Revit Automation on your to-do list, but you **never seem to find the time for it**?
- Do you **get stuck by Revit limitations** and only find workarounds that don't even work well?
- Are you tired fixing **the same errors** across hundreds of plans or elements in your models?
- Do you watch coding tutorials **but never actually learn **how to apply them to Revit?
- Do you find **human-errors on repetitive** tasks in Revit that could be avoided with automation?
- Do you feel like you're the only one in your office who wants to go **beyond basic Revit skills**?
- Do you finish projects thinking **"there must be a better way to do this"**?
- Do you promise yourself to prepare everything in advance for the next deadline, **but then doing everything the same**?
- Are you** afraid coding is too hard**, but frustrated by Revit's limitations?
If you answered "**Yes**" to any of these questions, **you're in luck.**
**Because 516 people who has joined LearnRevitAPI Academy faced exactly the same problems.**
So you will get the training specifically to solve these headaches and help you get started in no time.
## 3 Types of People who benefit the most
And in case you’re not quite sure yet if** LearnRevitAPI Academy** is right for you, here’s 3 most common types who join the program.
- You want to start but you never coded before and aren't sure which step to take first and how.
- You tried coding, and even created a few tools, but feel stuck and need more help.
- You're frustrated with Revit limitations and repetitive work gives you no other choice but to learn Revit Automation Quick.
If you can recognize yourself, then LearnRevitAPI was made for you.
I'd love to help you stop fighting with Revit Limitations and get full control of your workflows and automations for the office.
## 👉[Click here](https://learnrevitapi.com/) to join 517 others inside LearnRevitAPI Academy.
See you inside!
### This System Makes Revit Users 10X More Productive
https://learnrevitapi.com/newsletter/this-system-makes-revit-users-10x-more-productive/
Hey there!
Today, I have a very special announcement for you (as you can probably tell).
🚀The** **[**LearnRevitAPI Academy**](https://learnrevitapi.com/) is launched and you can join it right now.

### What is LearnRevitAPI?
Over the past 6 years, I’ve created hundreds of custom tools for Revit and automated many workflows. It saved hundreds of hours not just for me, but also for people I worked with on multiple projects.
And I want to share everything I know so you can:
- Be **x10 More Productive in Revit**
- **Automate Repetitive Work**
- And **Advance Your Career **with Revit Automation.
I know that I can help you because I've already helped thousands of Revit Epxerts get started with Revit API and Python. Also, I had more than 500+ students go through LearnRevitAPI training and majority has said it exceeded all their expectations and they started creating tools after first modules.
Here is what a fellow educator - **Aussie BIM Guru** have to say:

### Can LearnRevitAPI help you?
Once you join the Academy you get access to:
- **LearnRevitAPI Basics Course **(Best for beginners to learn the basics of Python, pyRevit and Revit API and begin their programming journey)
- **LearnRevitAPI Advanced Course **(Dive deeper into Revit API with more in-depth lessons and a huge focus on practical examples to learn by doing)
- **LearnRevitAPI - Modern UI Course **(Learn how to create custom UI forms to provide better user experience and achieve more unique workflows in Revit. This makes custom UI accessible for any pyRevit developer)
***That's right, the Academy isn't just a single course.***
You get access to 3 separate courses designed for different stages of your programming journey. No matter if you are an absolute beginner or already know how to create simple Revit API tools, you will all find value in LearnRevitAPI Academy.
And to make things go smoother, you will also be invited to my **LearnRevitAPI Community**, where:
- Get **Direct Access** to me
- **Connect with hundreds** of other developers
- **Discuss **Revit API
- **Share** your progress
- **Ask for Help **when you need it the most
**All of this is included for LearnRevitAPI Members.**
### Why Automate Revit?
Autodesk Revit is a very big and powerful application. But it's also very slow to react to our needs. It's an open joke in AEC that Revit would rather add a feature nobody wants than fix what annoyed many of us for years,
But Autodesk team has also done something amazing. They left the back doors to Revit open. And this makes power users like myself x10 times more productive with code. It's like a superpower to get unbelievable results.
Code is the greatest leverage and if you use it right, your career will skyrocket and your collegues will beg you to help them.
### Can you actually do it?
I've released the first version of the course back in October 2023 and my students loved it. Many joined without any prior knowledge of code and they learnt how to automate from scratch.
However, I wanted to make it better, so **TO THIS DAY, **I still update course materials to simplify and provide the best experience to Learn Revit API. And as you follow you can become 10X more productive with Revit.
**How?**
You will follow my roadmap that was tried and tested by hundreds who achieved great results. You will learn one concept at the time without feeling lost. And each concept is built on the previous one so you learn how it all works together.
But the reason it works well is the amount of practice you get. You won't become Revit automation expert by watching a few videos and talking to AI.
Instead you need to:
- Learn the Basics
- Understand the theory behind it
- Practice on how to use it
- And Apply it on Real-Projects
And you will learn all of it inside LearnRevitAPI Academy.
### This is ONLY for people who are serious about Revit Automation
That’s right.
LearnRevitAPI Academy will give you everything you need to:
- Create custom tools
- Automate Repetitive tasks
- Create unique workflows
- And be x10 more productive
But you need to put in the work to learn this skill. I can show you the path, but you need to walk it with me.
If that sounds interesting, [**Click Here**](https://learnrevitapi.com/) to join the program and create your first tool in just a few lessons.
## P.S.
And just so you know…
Over the next days, I am going to send you a FREE masterclass of everything that is included inside this product, as well as tons of free education around Revit Automation with Python.
Chat soon.
### 📦OOP in Revit API for Beginners
https://learnrevitapi.com/newsletter/oop-in-revit-api-for-beginners/
Revit API is a huge collection of classes.
And if you want to get comfortable using them, you better understand the basics of OOP, which stands for **Object-Oriented Programming.**
It's a big concept in programming, but you only need the absolute basics so you know how to work with Revit API Classes.
And that's exactly what I want to simplify for you. Once you get the basics it will help you read the docs and understand how to use it.
[**Watch Video Tutorial**](https://youtu.be/Qi4yo86piec)

## What is OOP?
**Object Oriented Programming (OOP) **is a specific way to structure your code with **Classes **that provide more features to reuse and abstract your code.
**💡Think of it as a workflow to structure your code where everything is an object based on a template.**
You can define classes like **Wall**, **Floor**, **View **(Templates)** **then add functionality with **Properties **and **Methods **and then create multiple instances based on these classes.
**Definitions**:
**Property **- is like a variable associated with a class. *Think of parameters associated with objects.*
**Method **- is like a function associated with a class. *Think of actions that objects can perform.*
**Constructor **- is a function that creates an instance of a class. Think of classes as blueprints that create instances.
I won't go deep on how to write classes, but I want to explain the main concepts behind them so it's easier to deal with Revit API.
## 4 Pillars of OOP
When talking about **OOP**, you will often hear about 4 Pillars which refer to 4 main concepts:
- **Encapsulation**
- **Inheritance**
- **Polymorphism**
- **Abstraction**
Let's break them down one by one so you understand the benefits of Object Oriented Programming.
## 1. Encapsulation (Keep it inside one Box)
Encapsulation means keeping related data and functions together in a single unit (a class).
**Think of a Coffeemaker as a Class🍵.**
It need to store values like amount of beans, water, wattage... In a class we could store this data under **Properties.**
It can also create different kind of coffee using different settings. So we could write different functions and store them as **Methods**.
This would create a template for our CoffeeMaker.
Here is an example:

Now here is a kicker.
There can be many coffee makers(instances) based on the same blueprint(class).
And while they all can hold different data, and produce a bit different results, they are all based on the same blueprint that comes with the same functionality.
That's exactly what classes are for. You define a blueprint for your object, you specify properties and methods, and then you can create many instances of that class that has access to same functionality.
And here is a simplified graphics of how it would look in code:

Revit API is full of classes like **Wall**, **Floor**... And then all instances in the project are based on these classes so they share the same functionality because it's all **Encapsulated **in a Class.
## 2.Inheritance (Reuse like a Pro)
Inheritance is very important OOP concept that you need to understand for Revit API. It's used to create new classes based on other classes.
**Example #1:**
For example, In Revit API many classes are based on the **Element Class** so they can inherit the base attributes like:
- .**Id**
- .**Category**
- .**Parameters**
- .**GetTypeId**()
- And so on...
And then, they have extra attributes on top for the class itself. So, **Wall Class **will have all **Element **attributes, and extra **Wall **attributes on top of that.
**Example #2: **Think of views in Revit.
There are classes like **ViewPlan, ViewSection... **and all of them are based on the **View **class to get the main **View **functionality.
On top of that, the **View Class **is based on the **Element Class. **So, each layer in this chain will inherit properties from the previous classes.

This is the ultimate workflow to reuse your code. However, you don't need to create this complex relations in your code.
I want you to understand the concept so you find it easier to explore Revit API. You will notice that many classes share the same properties and methods **inherited **from the base classes.
## 3.Abstraction (Hide Internals)
**Abstraction **concept means showing only the necessary features while hiding the complex implementation.
For example if you would call **wall.Flip() **method you don't need to know all the complex geometry calculations happening behind the scenes.
You only need to know how to use it and what kind of results you get. The rest is handled by the class itself.
## 4.Poly-Morphism (One to Many)
Lastly a fancy word - **polymorphism**. To put it simply, this concepts allows us to use the same attribute name in classes but get different behavior.
For example in Revit API you can use **Location Property** for many elements. However, you might get different results.
- **Wall.Location** - Will get you a **LocationCurve**
- **Door.Location **- Will get you a **LocationPoint**
In this case, we can use the same property name (**Location**), and get different results(LocationCurve/ LocationPoint) because elements have diffrent logic.
- Wall - Line-Based
- Door - Point-Based
In code it will look something like that:

This concept is more about working with multiple classes and preparing for the future.
In terms of Revit API, just keep in mind that sometimes there are differences to the output across classes even when you use the same Property/Method name.
But it's not so often and usually it makes a lot of sense logically.
## Why OOP for Revit API?
OOP is an advanced concept that is more useful on larger code bases. Also, certain languages require you to code only using OOP structure, **but in Python it's optional**.
You don't need to become OOP expert and code using classes. It's much simpler to use existing classes than creating them.
Understand the basics of OOP so you can:
- Read Revit API Documentation
- Use Revit API Classes
And don't worry if it's a bit hard. You will learn it over time as you get more comfortable with programming in general.
It took me a while to understand why OOP can be useful. Just give it some time and it will come to you.
## P.S.
Now that you understand the basics of **Object-Oriented Programming**, we are ready to dive into Revit API documentation and learn how to get the most out of it.
**👀 Keep an eye on the next email** where I will explain you everything you need to know about Revit API Documentation, especially if you are a beginner.
👋See you soon.
## P.S.S
Want to dive deeper into Revit API to Automate Revit?
**Click Here** to learn more.
### 📄What's New in Revit API 2026? Here are the biggest changes...
https://learnrevitapi.com/newsletter/what-s-new-in-revit-api-2026-here-are-the-biggest-changes/
You can't ignore changes in Revit API 2026.
Every year Revit API gets an update, and it's important to know the changes so you can update your scripts and avoid any errors.
Let's go through the changes in API and find:
- What's Changed?
- What's Removed?
- What's New?
👉 [Click Here](https://youtu.be/2mcKrC8rEy4) to watch the video.

## Revit API Documentation
If you prefer to go through the changes yourself, you can open this [What's New Page](https://rvtdocs.com/2026/whatsnew) in Revit API 2026.

### ✅ Revit 2026 Python Support: Testing pyRevit & RevitPythonShell
https://learnrevitapi.com/newsletter/revit-2026-python-support-testing-pyrevit-revitpythonshell/
**Revit 2026** is here, and it already has the Python support we need.
The **pyRevit** team was very quick to react and publish changes to provide support for **Revit 2026**. And to my surprise, **RevitPythonShell** has gotten a second breath and now supports Revit 2025 and 2026.
I thought I'd share the installation steps with you and show that it works well.
[**Click Here**](https://youtu.be/2r_dlb5AWLU) to watch the tutorial.

## Links from Video
Here are the links to download installers:
- [**pyRevitLabs**](https://pyrevitlabs.io)
- [**RevitPythonShell**](https://github.com/architecture-building-systems/revitpythonshell)
- [**RevitLookup**](https://github.com/lookup-foundation/RevitLookup/releases)
💡Watch Tutorial to see the installation process and changes.
## P.S.
It's great to see that this year everything we need to continue developing tools with python and Revit API is already updated and ready for use.
I'm going to create another video showing** Revit API 2026 changes** in the next week, so stay tuned.
### ⌨️The Programming Journey of Aussie BIM Guru (Gavin Crump)
https://learnrevitapi.com/newsletter/the-programming-journey-of-aussie-bim-guru-gavin-crump/
**Gavin Crump** (known as **Aussie BIM Guru**) has come on the show to talk about:
- - His Programming Journey from Hacking Nintendo to Automating Revit
- - The Progression from Dynamo -> pyRevit -> C#
- - His opinion on C# vs Python
- - The workflow he uses for creating new tools
- - The Deployment strategy for hundreds of employees
- - His thoughts on AI in AEC
- - And a lot more topics in between.
👉[**Click Here**](https://youtu.be/1uaz6DdDBLo)[ ](https://youtu.be/1uaz6DdDBLo)to watch full episode.

## P.S.
Help me spread the word 🙏.
### LearnRevitAPI is Back Online 🚀!
https://learnrevitapi.com/newsletter/learnrevitapi-is-back-online/
Life is unpredictable and for the past week I've been completely dormant💤.
- No YouTube Videos
- No Newsletter Updates
- No Code
- ⚠️Website Was in Maintenance...
It felt unusual to be offline for so long, but I had a very good reason - I'm a dad now🐣. And with more sleepless nights ahead it's time to get back to what I love: Teaching Revit API, pyRevit and Python.
***P.S.**** It's not April's Fool joke, just bad timing.*
## ✨The First Big Change
A few people reached out in the past week asking what happened to the website and if **LearnRevitAPI **is closing 😱.
**The good news **- It's back online and enrollments are open again. You can [**check it here**](https://learnrevitapi.com) to learn more about:
- How it can help you Automate Revit
- How to get most out of it
**Here is the new look:**
> **NB** 
## P.S.
I'm getting back on track and it means you can expect a lot more content on YouTube, Newsletter and my Course Platform.
Stay Tuned, I have exciting things coming to all of them.
### ✨The New Modern Revit API Documentation for 2025
https://learnrevitapi.com/newsletter/the-new-modern-revit-api-documentation-for-2025/
✨Big News Today!
I was hiding it for a while, and finally I would like to introduce the new modern Revit API Documentation - [**www.RVTdocs.com**](https://rvtdocs.com)
✔️ Revit API for 2021 - 2025
✔️ Fast & Advanced Search
✔️ Dark Mode (Finally!)
✔️ New Modern Layout
✔️ Bookmarks
✔️ No Ads
This is just the beginning, I will be adding more features, and you are welcome to suggest me more ideas.
[**Watch This**](https://youtu.be/UYz0Ity2ERA) to check new features on **RVTDocs**.

## P.S.
**Could you help me spread the word?**
I've spent over a month working on this project, and I'm just getting started. I will push this website to its limits.
I would appreciate if you could share it with a friend or like and comment to help video reach more people.** It really does help a lot.**
Thanks🙏.
### The Programming Journey of pyRevit Dad
https://learnrevitapi.com/newsletter/the-programming-journey-of-pyrevit-dad/
✨Just posted new Podcast Episode.
**Ehsan Iran-Nejad** (known as pyRevit Dad) has come on the show to talk about:
- His programming journey
- pyRevit Story
- How programmers think
- His day to day at McNeel
- Coding in general
[**Click Here**](https://youtu.be/javbkdxwg_Q)[ ](https://youtu.be/javbkdxwg_Q)to watch full episode.
## ⚠️Spoiler Alert
The next podcast is already recorded and it's with **Gavin Crump **(aka AussieBIM Guru)! We had a lot to talk about.
You can expect the next episode in ~2-3 weeks.

## P.S.
**🤔Let me know what you think about the podcast.**
Your feedback helps me improve my content and find interesting next guests to talk about pyRevit.
### ⚡How to use pyRevit Hooks to create Event Triggers in Revit API?
https://learnrevitapi.com/newsletter/how-to-use-pyrevit-hooks-to-create-event-triggers-in-revit-api/
**Event **is a very powerful feature in Revit API.
It allows us to take a piece of code and subscribe to certain actions in Revit and whenever they are triggered, our piece of code will be used as an event handler.
It's a more advanced feature and shouldn't be used by beginners without caution. Luckily, pyRevit has a simplified way of using them called **pyRevit hooks**.
Let me explain.
[**Click Here**](https://www.youtube.com/watch?v=tfEQAv36EaM)** **to watch video tutorial.
## What are Events and Event Triggers?
**Event **is an action, which can be detected by the software. It's like a notification mechanism that can tell us that something has happened.
**Event Trigger **is what actually causes the event. For instance if user would click on **"Import CAD", **it can trigger an event of clicking this button.
**Event Handler - **is a piece of code that will be executed once event is triggered.
For example:
- User click on Import CAD button (Event Trigger)
- Software detect the action (Event)
- Our code is triggered (Event Handler)
In this example, event can help us monitor when users click on the **"Import CAD"** button and give them a warning message saying that we don't like when they use it. We can even set a password so users can't use it without it.
> **TIP** 💡 P.S.You can't make changes in Project with regular Events. They are used for monitoring, telemetry, stopping execution and so on...If you want to make changes with events, you would need to use [**IUpdater Interface**](https://rvtdocs.com/2025/4cdaf502-fc25-8f18-7618-8448cce33d11)** **to dynamically update your model.*That's a topic for another day!*
## How to work with Events?
Events in Revit API can be tricky. You have to **subscribe **and **unsubscribe **manually and it becomes tedious task to manage because events will be remembered in your projects.
Here is an example for reference: (No need to execute!)

## Events in pyRevit (hooks).
However, **pyRevit** has a very unique approach to events.
You can create **hooks **folder in your **.extension **and then place scripts for the events, and pyRevit will subscribe and unsubscribe to them for you.
The key here is to use the correct naming for you files, as pyRevit will use the name of the file to subscribe to the correct event.
Here is a folder structure example:

You can read more about the hook file naming here in [pyRevit Docs](https://pyrevitlabs.notion.site/Extension-Hooks-b771ecf65f6a45fe87ae12beab2a73a6). Here is an example of the table:

💡 pyRevit also has a short guide on [**How To Create Your First Hook**](https://pyrevitlabs.notion.site/Create-Your-First-Hook-0214eee855fc43cead1e6f30f586a04e)**.**
## pyRevit Hook Example
[**Click Here**](https://www.youtube.com/watch?v=tfEQAv36EaM) to watch a tutorial about pyRevit Hooks.
In this video I will show you how to prevent users from using **Import CAD **command in Revit and how you can set a password to this command in Revit.

### ✨ New Tutorial: Copy View Filters Across Views in Revit API
https://learnrevitapi.com/newsletter/new-tutorial-copy-view-filters-across-views-in-revit-api/
📢 **New Video Alert!**
Learn step by step how to **copy View Filters across views using Revit API.** I often get questions about this, so I’ve broken it down to make it easy to follow.
Watch now to automate your view filters.
[**Click Here**](https://youtu.be/F8QFU8WgcWA)[ ](https://youtu.be/F8QFU8WgcWA)to watch:
**How to Copy View Filters in Revit with Python.**

## P.S.
Have an idea for the next video?
👉 **Hit Reply**, let me know.
### 💻I ignored pyRevit CLI for too long... Here's how to get started fast.
https://learnrevitapi.com/newsletter/i-ignored-pyrevit-cli-for-too-long-here-s-how-to-get-started-fast/
I'm lazy 🤷♂️.
And like many of you, I avoided **pyRevit CLI** because I didn't want to dive into all of that. But it turns out it's not as scary or complicated as I thought.
Huge thanks to **Jean-Marc** for coming on the show and showing us how it works. Once you see him use **pyRevit CLI**, you realize it's much simpler than you think and it can help you control pyRevit across all machines in the office.
Let me summarize it.

## 🤔What is pyRevit CLI?
The **pyRevit CLI** (Command Line Interface) is a powerful tool that helps you manage **pyRevit**, its extensions, clones, and configurations, all from a **cmd terminal**.
Think of it as a 🎮remote control that you can use without opening Revit. It can help you save a lot of time and get more control over pyRevit deployment.
- Click on Window's Search
- Type: **'cmd'**
- Click on **Command Prompt**

Once you are in the terminal you can start using various commands available on your machine including **pyRevit.**
If you have pyRevit tab in Revit, then you also have **pyrevit cli**. To verify, open the cmd terminal and type ***'pyrevit'*** (all lower-case)
✅If installed: you will get overview of ***pyrevit cli commands:***

❌If not, then you will see a message:
*['pyrevit' is not recognized as an internal or external command...]*

🧑🚒As you can see, nothing is on fire🔥 nor broken.
Don't be afraid to try it out right now.
## cmd Commands
Before we dive into **pyrevit cli** I want to mention a few commands in **cmd terminal**.
> **NB** '***cls***' or '**clear**' - Clear the terminal.
> '⬆️⬇️' - Use arrow keys to see history of previous commands
There are a lot more commands, but you will find these really useful right away.
## pyRevit CLI commands
So, you have a list of all **pyrevit cli commands**, but you have no idea how to use them... Don't worry, you can easily learn it right in the terminal with options.

**Options are extra settings** that allow you to control how a command runs. They typically start with single(-) or double(--) dashes. It works like this:
> **NB** pyrevit
For example, let's say that you want to learn more on how to use '**clone' **command. Then you would type this to get more help:
> **NB** pyrevit clone --h

Now you have an example on how to use it and explanation about required **Arguments **and **Options**. And now you can try it out.
💡If still in doubt: copy-paste Terminal output into ChatGPT and ask it for help. It can help you navigate and provide correct arguments.
## P.S.
I highly recommend you to check [the podcast](https://youtu.be/8-zd7F79gR8?si=iJ8fL8nPJ5Bm1HAv&t=2961) to see how Jean-Marc uses it, it will make it x10 times easier for you to begin.
During the pod, we talk about :
- pyRevit News
- pyRevit PreFlight Checks
- Jean-Marc's Programming Journey
- And of course pyRevit CLI
There are more topics, but these are the big ones. The conversation about CLI starts at **49:25**

**🎙️Enjoy the Show!**
### ⚙️How to modify Shared Parameters with Revit API and Python?
https://learnrevitapi.com/newsletter/how-to-modify-shared-parameters-with-revit-api-and-python/
Managing Shared Parameters is Slow and Boring...
But as pyRevit developers we can define the logic for managing parameters once, and then reuse it across all projects. And the more parameters you have, the more you need to automate how you manage them.
And that leads me to today's question I got:
"How to modify Categories in existing SharedParameters"?
Let me share the answer:
## #1 - Define Categories
Firstly, let's create a list of **BuiltInCategories **that we want to include in Shared Parameters.

P.S.
We could also override or use different logic for setting categories. I just keep it simple to follow along.
## #2 - Get Shared Parameters
Now, we need to get existing parameters from Revit project. Manually you would normally open Project Parameters menu:

But, in Revit API it's called **BindingsMap**, and we can get it with **doc.ParameterBindings** property.
Then we can iterate through the list, but it will be a little tricky because we need to use **ForwardIterator. **It's a weird concept to grasp, because it doesn't allow to iterate with a for-loop, but instead, requires you to use: .**MoveNext**() and .**Current...**
Here is a code snippet to iterate through BindingsMap and save all definitions in a dictionary as ***{definition:binding}***.

## #3 - Modify CategorySet and ReInsert
Lastly, we can iterate through parameter definitions, and modify their current binding settings. During this step we also need to make sure that we have some logic on selecting parameters, so we don't modify all of them.
Let me provide you a code snippet and then I explain what's going on:

**⌨️Code Breakdown:**
- **Start Transaction **to allow changes with RevitAPI
- Iterate through **dict_parameters ***{def : binding}*
- Ensure Definition.Name includes **'EF_'**
- Get current **CategorySet**
- Iterate through **extra_categories **and **add **if necessary
- If new category was added, then update parameter using **BindingsMap.ReInsert **method.
- Report on changes
💡And that's how you modify **CategorySet **of your parameters.
P.S. **Definition **- is like a template for your parameters. It's where all the settings and controls are located.
## Final Code
Finally, let's put it all together into a single snippet you can take and adjust to your own needs.
Here is the code:

## P.S.
If you want to learn more about Shared Parameters and many other Revit API Topics, then [**Click Here **](https://learnrevitapi.com)to learn more.
### ⏹️How-To Convert Internal/Survey/Project Coordinates with Revit API?
https://learnrevitapi.com/newsletter/how-to-convert-internal-survey-project-coordinates-with-revit-api/
Coordinates are confusing, especially in the Revit API.
You probably think that there is a simple method in API to convert coordinates from one system to another. At least that's what I expected until I realized there isn't one... I checked 10+ times before going down this rabbit hole🐇.
But don’t worry, I’ve already created a solution. So, there is no need for you to spend countless evenings trying to make it work.
✅ Let me share my solution with you.
**You can watch **[**Video Tutorial Here**](https://www.youtube.com/watch?v=82oKVTaN3-o)

## ⏺️ Coordinate Systems
Firstly, let me remind you the coordinate systems in Revit.
- **Internal** (Used in Internally and in Revit API)
- **Project** (Based on Project Base Point)
- **Survey** (Based on Survey Point)

If you are new to coordinates, then I suggest create multiple tags to track each system and tag multiple points like this:

This will help you understand very quick what's going on with your coordinates when you move certain anchor points or rotate True north. (check the video above)
### ✅Solution: PointConverter
Back to Revit API.
I won't go into details of the code, but instead, I will provide you a Class that you can copy-paste and explain how to use it.
**Class Remarks:**
*Notice: you provide x,y,z coordinates in meters and specify the coordinate system. It will calculate the same point across all coordinate systems.*
*If you want to provide values in internal units (ft), then you can remove 3 lines of code where I define X,Y,Z with convert_internal_units function.*
Here is the **PointConverter** Class.

You will also need this function to convert units. You already know how it works from previous email, right?

P.S. Copy Snippets from [**here.**](https://learnrevitapi.com/blog/convert-coordinate-systems-in-revit-api-draft)
### 💪How to use it?
The Class is very simple to use. But please, **pay attention to units **used in your Revit Project and inside your Code! That's where majority of confusion will come from.
This is why I created **print_coord_in_m **function to keep myself sane. Otherwise you might think that you are doing something wrong.

### P.S.
It might look like a lot of code, but it's actually very simple to use.
Just copy-paste the code and see how I use it in [this video](https://www.youtube.com/watch?v=82oKVTaN3-o). Then, you will be able to do the same and finally convert your values across all coordinate systems.
I hope you find it useful.
### 📢 pyRevit News + pyRevit CLI for Teams with Jean-Marc Couffin | pyRevit Hacker Podcast #2
https://learnrevitapi.com/newsletter/podcast-2-pyrevit-cli-for-teams-with-jean-marc-couffin/
New pyRevit Podcast Episode is Live!
I had a great chat with Jean-Marc Couffin. Not only does he have multiple decades of experience in the AEC field, but he is also the most active member of the pyRevit community. pyRevit wouldn't be where it is today without him, and that's why I like to call him pyRevit Uncle.
During podcast we talked about the recent pyRevit update, Pre-Flight Checks, his programming journey, and the pyRevit CLI for deploying pyRevit to teams.
[**Click here**](https://youtu.be/8-zd7F79gR8) to watch the episode.

## Next Podcast in Progress
Here's a little spoiler for the next podcast episode:
I've already chatted with Ehsan Iran-Nejad (pyRevit Dad), and it's now in editing.

## P.S.
I’ve got the next three guests lined up, but I’m curious:
- Who would you like to see on the podcast?
- What pyRevit topics should we dive into?
**Hit reply** and let me know. Thanks!
### 🧮 How to convert units in Revit API with a single line of code.
https://learnrevitapi.com/newsletter/how-to-convert-units-in-revit-api-with-a-single-line-of-code/
📏** Revit API uses feet internally.**
This has caused a lot of confusion among beginners who use the metric system. They read parameter values and see completely wrong numbers, and it's the worst when you're debugging something that isn't broken...
So, I want to share a quick snippet with you. Let’s convert units in the Revit API.

🧮 Pull out your calculators.
## Methods in Documentation
Converting units with the Revit API is quite simple. There are two methods in the **UnitUtils** class that we can use to convert TO/FROM internal units:
**- UnitUtils.ConvertToInternalUnits****(value, UnitTypeId)**
**- UnitUtils.ConvertFromInternalUnits****(value, UnitTypeId)**
Here is a screenshot of the Syntax:

As you can see, you need to provide a value and select the appropriate unit from the **UnitTypeId** class.
## Convert Units
If you have a value in metric units and need to convert it into internal units, use **ConvertToInternalUnits** like this:

However, if you have a value in internal units (ft), then use **ConvertFromInternalUnits** like this:

That’s it. Just remember that the **Revit API uses feet as its internal unit**, so always select the correct unit.
## UnitTypeId Class
**UnitTypeId** is a class in Revit APi that contains identifying units of measurement. It includes a long list of units, but you’ll only need a handful, such as **Meters**, **Centimeters**, **SquareMeters**, and so on...
Here is a screenshot from the Docs:

## P.S.
If you get incorrect values in the Revit API, make sure you have the right units before you start debugging.
When I started, I fell into this trap and spent hours fixing code that didn't need fixing. I just had to use the correct units.
So, watch out.
### 🔥New Step by Step Tutorial for Revit API Beginners
https://learnrevitapi.com/newsletter/new-step-by-step-tutorial-for-revit-api-beginners/
👋 Hey pyRevit Hacker!
I've just released a new video on YouTube that you might find useful. I'll show you how to find missing tags in Revit and explain all the steps along the way. It’s a great exercise to practice Revit API with Python.
[**Click Here**](https://www.youtube.com/watch?v=6GaGdN0hoD8) to Watch Video Tutorial.
**How To Find Missing Tags in Revit Using Python + Revit API**

## Bonus Sneak Peak
Recently I had a pyRevit Hackers Podcast #2 with Jean-Marc Couffin (pyRevit Uncle).
We discussed many pyRevit topics and then he showed how to use pyRevit CLI to deploy pyRevit to teams. Very excited for releasing this episode.

I had some issues with a render for many days, but I've finally solved it. And the episode is almost ready to be released. I can't wait to share it.
Stay Tuned!
### ⛔The reason why many fail with Revit API... (don't fall into the trap)
https://learnrevitapi.com/newsletter/the-reason-why-many-fail-with-revit-api/
**"Don't learn coding, AI can do it for you."**
👆 Have you ever heard this advice?
Many in AEC create a simple pyRevit tool with AI and conclude that they don't need to learn programming basics. Why bother with code?
**But here's what they're missing:**
- It only works for very simple tools that are already explained well on YouTube and Blogs.
- They ignore the fact that AI can hallucinate and get stuck on simple steps.
- They won't have full control over custom tools.
Isn't that the whole point of creating them?
That's why this advice is actually NOT helpful at all.
Instead, follow these three advices for beginners:

*🤖****AI****: *Be-Boop* I see the problem too… it’s Erik.*
## Advice #1 - Start With The Boring Stuff
Yes, I'm talking about the basics. You can't get around them.
In fact, this is actually the easy route. I tried skipping the basics when I started, and it simple doesn't work that way. You will suffer and waste more time in the end if you skip them.
It's not only me saying this, many expert and other students pointed out the same thing. Once they nailed the fundamentals of coding, the Revit API came naturally.
The good news is - you don't need a lot. For example, here are the key concepts you need to understand in Python:
🔹Syntax
🔹Data types
🔹If-statements
🔹For-loops
🔹Functions
🔹A little bit of OOP (Object-Oriented-Programming)
Once you grasp these Python basics, you'll begin creating cool scripts with logical flow. Also, that means you are ready to dive into Revit API.
And don't worry about learning everything about the API right away. Start with these basics:
🔸RVT-Docs
🔸Selection
🔸Read/Set Properties
🔸Parameters
🔸Transactions
🔸FilteredElementCollector
These basics alone will open up many doors in Revit for you.
You'll start saving a lot of time by creating custom tools tailored to your workflows. More importantly, you will improve your programming skills and be ready to build more advanced tools.
Just imagine clicking a button and having your script execute on hundreds of elements in Revit.
**Isn't that a dream🪄?**
## Advice #2 - Don't Reinvent the Wheel
Once you know the basics, it's time to practice.
There's no need to start with a blank canvas either. It's boring and daunting, especially for beginners. Instead, explore all available code examples and adjust them to your own needs.
Why reinvent the wheel? Find an existing solution and customize it for your workflow. This will give you a head start and allow you to create a toolbar packed with custom tools in no time.
**⚠️Pay Attention Now.** I'm about to share something really ground-breaking for beginners. Ready?
## 🔓pyRevit is Open-Source
This means that you can get access to every single line of code in pyRevit and all its additional extensions. There are already hundreds of cool Revit add-ins you can look into and copy for your own needs.
And it's very simple to read. Find a tool that interests you, then simply:
- 👉 Hover over the tool
- ⌨️ **[ALT] + [Click] **to open source folder
- 📄 Open **script.py** file
- 🔎 Explore/Copy python Code

**Feels like cheating, isn't it?**

## Advice #3 - Challenge Yourself
Lastly, don't fall into the trap of watching tutorials without ever applying what you learn. You must practice and challenge yourself.
Trust me, you will learn ten times more by doing it. And don't be afraid to encounter errors. Think of them as opportunities to learn something new about programming. Errors are the best teachers.
**Don't know where to start?**
Find a problem in your daily job and make it easier for future-you. Think of the most repetitive and annoying tasks on your to-do list, and then ask yourself:
***"How can I make it easier with code?"***
Then, try to solve it. In the beginning, focus on smaller steps so it's easier to achieve. Later, you will combine multiple steps together into larger tools.
That's how the majority of us started. We wanted to solve one problem with code, but then we got more problems to solve...
In short: Practice, Practice, Practice...
## 🤖 Should you avoid AI?
Absolutely not.
That's not what I meant. You should implement AI into your coding journey to learn and code faster. But you can't rely 100% on it.
Once you understand the basics, you will be able to ask better questions and guide AI to provide you the best answers. Remember, it's a tool to help you, not to replace you. Use it accordingly.
Learn the basics, explore existing code, and find challenges suited to you. Use AI throughout these steps. It will be indispensable in helping you progress, but you'll still be in control.
*We will talk more about AI some other day.*

*🤖****AI****: *Be-Boop* I will see you around too.*
## P.S.
If you want to take a shortcut to learn the basics faster and see how to apply them in Revit - then 👉[**Click here to learn more**](https://learnrevitapi.com/all-courses/pyrevit-bundle).
This is by far the easiest route you can take.
### #️⃣The art of writing clean python code with comprehensions.
https://learnrevitapi.com/newsletter/the-art-of-writing-clean-python-code-with-comprehensions/
**Writing clean and minimalist code is an Art.**
There are many ways to reduce unnecessary fluff, but **comprehensions **are by far the simplest and most effective.
They’re like a secret superpower for Python: easy to learn, elegant to use, and incredibly useful for transforming your data in just one line.
Plus, they make your scripts easier to read, so you can spend more time on the fun stuff and less time debugging messy loops!
Let me share the secret of how to use them.

Get Ready, it's about to get hot!
## What Are Comprehensions?
**Comprehensions **let you write shorter, cleaner, and faster code.
Whether you're dealing with **lists, dictionaries, sets**, or even **variables **- comprehensions will save you a lot time and effort.
Plus, they make for some pretty impressive one-liners!
## If Comprehensions
Let's begin with simple **if/else Statement** comprehensions.
They let you combine simple logical statements into a single line. They are great to use when you need to check something and assign one of 2 available values.
I'm going to provide you 2 code examples with the same result, and I want you to tell me which one is easier to read.
Example #1:

Example #2:

I hope we can agree that Example #2 is more pythonic 🐍.
Also, it's very self-explanatory. You can literally read it as English and it makes sense.
## Simple List Comprehensions
Now it's time to focus on the most used comprehensions in python - **List Comprehensions**.
They are a great way to transform, filter or create new lists in a more pythonic way. They allow you to create a loop and generate a new list of data from a single line of code.
Here is the **List Comprehension Anatomy:**

As you can see you can put your for-loop inside of square brackets, and the first expression is what will be added to the new list.
Let's have a look at 2 code examples again, and you tell me which one you prefer more.
Both examples will take items from an existing list and create a new list with UPPERCASE items (The same principle can be applied for anything else.)
Example #1:

Example #2:

*Would you rather write Example #1 or Example #2?*
***👉I bet it's #2!***
## List Comprehensions with Logic
I hope you already see how powerful comprehensions can be in your scripts.
However, some of you probably start wondering: 'But what if you want to add logic with if-statements'? Well, that's also possible.
Here is an extended anatomy of list comprehensions:

As you can see, we can create a **for-loop** in the middle, then specify **expression **of what will be returned on the left, and then **conditions** on the right.
This way you will only get items in your new list if they pass the condition. Otherwise they will be ignored. This is a huge time saver to filter your lists.
I will use the same example and add a simple filtering to ensure it contains* 'item_'* keyword.

## P.S.
If you found this useful and you want to dive deeper with python for Revit API, then you will love **pyRevit Basics course.**
It's made specifically for Revit Users, so I can relate python and Revit API concepts to something you already understand inside of Revit. [**Click here**](https://learnrevitapi.com/all-courses/pyrevit-basics) to learn more.
### ⛔ My 5 Biggest Mistakes with Revit API (You Can Avoid Them)
https://learnrevitapi.com/newsletter/my-5-biggest-mistakes-with-revit-api-you-can-avoid-them/
It's been quite a journey.
I started with Revit API about 6 years ago. Like many of you, I had absolutely no clue what I was doing. I didn’t know Python. I didn’t understand Revit API. But I did have one thing: repetitive problems that I really wanted to solve.
So, I jumped right in, made a ton of mistakes, and learned the hard way.
Today, I want to share my biggest mistakes so you can avoid them.

Ready? Set. ⌨️Code!
## 🔥Mistake #1 - Skipping The Basics
This is a classic one. I was so eager to automate everything that I didn't bother learning the fundamentals of Python or Revit API.
I just wanted to see results, and I wanted them fast. But skipping the basics is like skipping important steps when laying a solid foundation - you always pay for it later.
✅ Lesson Learned:
Take your time with the basics.
Learn the syntax, understand the logic, and practice writing clean, simple code. Trust me, it's worth it. Revit API becomes so much easier when you first master the basics.
## 🔥Mistake #2 - Over-Optimizing Too Early
Do you spend too much time optimizing your code before you even have a proof of concept?
I did. I wasted days improving specific steps, only to find out later that the overall approach wouldn’t work. It’s a classic rookie mistake, trying to make scripts "perfect" before they even work.
**✅ Lesson Learned:**
Make it work first.
Then, you can optimize or polish it.
## 🔥Mistake #3 - Not Testing Enough
*"If it worked once, it doesn't mean it will work every time." -EF*
I was so excited to share my new tools, only to receive messages like, "What should I do with this huge red error message?"
I was like:

That's because I tested my scripts on one Revit model and call it a day. Oops...
***Every project is unique, and we need to keep that in mind.***
**✅Lesson Learned:**
Test your scripts on multiple models across multiple Revit versions.
Also, it's great to pick up a habit of trying to break all your scripts while you write them. That's how you can fix it before your users break them. That's a good habit to have.
## 🔥Mistake #4 - Reinventing the Wheel
Why? I don't know... pride, maybe? Or I'm just too lazy to research a few minutes to realize that this feature already exists in Revit itself... That happened too.
I often jumped into coding too early. I spent hours creating tools that already existed.
Why? I’m not sure... maybe pride? Or maybe I was just too lazy to spend a few minutes researching to find out that Revit already had that feature(Yep, that happened) or there is a solution on GitHub.
**✅Lesson Learned:**
Check if someone else has solved the problem first. Reuse existing code and build on top of other tools. There is no shame in reusing code.
## 🔥Mistake #5 - Not Asking for Help
I was a stubborn learner.
I didn't want to bother anyone, and I certainly didn't want to look like a newbie. So, I struggled a lot instead... (Not recommended).
If only I had asked for help, I would've saved countless hours and learnt better tricks.
**✅Lesson Learned:**
Don’t be afraid to ask questions, join communities, and learn from other developers. Nobody expects you to know everything. I still have a lot of things to learn myself, and that's normal.
## P.S.
I've built a community for my course students and it's getting more active.
I see a lot of new coders asking for help and many others jump in to help them. People are very excited to talk about coding in Revit and share what they've learnt so far or even help brainstorm together.
I often find how others already provided code solution before I even could read the question myself. Communities are awesome.
[**Click Here**](https://learnrevitapi.com/all-courses/pyrevit-bundle) to learn more about **LearnRevitAPI Community.**
## ✨Bonus Mistake: Giving Up Too Soon
I've noticed a pattern in programming.
Everyone encounters issues. You’ve probably had moments where you tried everything, and nothing worked. NOTHING.
But then you return to the same code a few days later and solve it in five minutes. I’m sure this has happened to you before, and it will happen again.
**✅Lesson Learned:**
Don't quit too early.
Take a break and come back to the code later. You never know what your subconscious has been working on.
Don’t worry, making mistakes is a normal part of the journey.
It’s how we learn and grow as developers.
Keep experimenting, keep learning, and most importantly, keep making mistakes that you learn from.
### 🧐 Check if All Your Doors are tagged with Revit API
https://learnrevitapi.com/newsletter/check-if-all-your-doors-are-tagged-with-revit-api/
I've got another Revit API question: **❓How to ensure all doors are tagged on our plans?**
That's a good one. I had the same question when I was working on a high-rise project with 35 levels. It wasn't fun to look for missing tags manually, so I had to find a better approach. And that's what I'm about to share with you.
So pull out your magnifying glass, let's look for missing tags.

## 1. Proof Of Concept
We are going to do this a little different.
Firstly, I want to create a proof of concept by working on the active view. Once it works, we will turn it into a function and use across many views.
That's how I usually code. In the 1st stage I code fast and dirty to get results. It won't be perfect or look good, it just have to do the job. And then we can try to make it better and prettier, no the other was around.
So here is the plan:
- Get All Doors in View
- Get all Tags in View
- Find Tagged Doors
- Find Untagged Doors
Pretty straight-forward, let's dive into code.
## 1.1. Find Untagged Doors in Active View
Firstly, we are going to get all doors and tags from the active view. For that we will use **FilteredElementCollector **to get elements visible in a view. ([**Watch This**](https://www.youtube.com/watch?v=MfJTPIOo7nY) if you are new to FEC)
Here is the code:

Now we can iterate through tags and use **GetTaggedLocalEleements **to produce a list of tagged doors.
Then, we can get a list of untagged doors by checking door ids in the list of tagged doors.
Here is code:

Lastly, to make it easier to see results, we will change user's selection in Revit UI.
Here is code:

## 1.2. Final Code - Proof Of Concept
And that's our proof of concept. If you run this full script it will select doors in your view that don't have any visible tags.
Here is full code:

And here is my result. As you can see I have a door without tag selected, so I know it works correctly.

Now let's make it work across multiple views.
## 2.1 Create a function
Let's begin by creating a function to find untagged doors so we can use it across many views.
Let's wrap out existing code into a function and call it **find_untagged_doors(view)**

## 2.2. Select Views
Next, we need to select views where to check doors for missing tags. Luckily, there is an amazing reusable function in **pyRevit.forms** that makes this step super easy.
Here is the snippet

## 2.3. Find Doors with Missing Tags
Finally we can iterate through all views and find our missing tags.
I also want to style it nicer, so I will use **output.print_md **which allow you to print **Markdown **syntax. This will allow you to print headings, bold text, horizontal lines and so on by using simple symbols. (you can google for examples)
Here is the code for final step:

- Get Output
- Iterate Through views
- Create clickable linkify button for View
- Create clickable linkify button for Missing Doors
- Add extra print statements.
This step takes more lines of code because we are making a lot of print statements. But overall, it's a very simple code.
What's linkify? Well, it's a super nice feature in pyRevit that allow you to print clickable button that will select provided elements. (You can [learn more here](https://learnrevitapi.com/blog/create-interactive-revit-reports-with-pyrevit-linkify))
## 2.4. Final Code:
Here is the final tool that will save you a lot of time looking for missing door tags.

Now you can adjust very little and create similar tools for other categories. Let me know if you would like a video tutorial for that.
## P.S.
If you find it exciting, but you find it a little confusing, that's okay. It probably means that you missed a few basic steps on your programming journey.
If that's the case, I would like to help you cover these basics in no time. [**Click here **](https://learnrevitapi.com/all-courses/pyrevit-basics)to learn more.
### 🔽 How to Copy View Filters with Revit API in Just 3 Steps...
https://learnrevitapi.com/newsletter/how-to-copy-view-filters-with-revit-api-in-just-3-steps/
I just got a question: "How to copy view filters between views?"
It's actually very easy to copy filters. You need to get a view, read its filters, get overrides and you are ready to create the same filters. However, the simplest step can also be the trickiest of them all if you don't pay attention.
So, let me show you how to do it right.
And if you have other API questions,
you know where the ➡️**Reply Button** is.

**Now, are you ready to copy views?**
## 1 - Get Views
Firstly, let's get some views.
I will keep it simple and get views by name from a collection. However, keep in mind that you might need to filter a few things out to get the right views. I will do the following:
- **Filter Views by ViewType** (because we can have same view names across different types)
- **Filter ViewTemplates** out.
- *** Filter Views without Filters **(Optionally if you want users to select **view_from**, I will skip this.)
So here is the simple snippet to get views by name:

💡You can make it more efficient by keeping collector outside, but I keep it simple for tutorial.
## 2 - Get View Filters
Once we have the view, we need to select some filters.

I don't always want to copy all available filters, so we will use a simple **pyrevit.form - SelectFromList**, so user can decide what they want to copy.
Here is the code snippet:

- GetOrderedFilters()
- Convert ElementIds to Filters
- Create SelectFromList form
- Ensure Filters selected
## 3 - Copy View Filters
Alright, it's time to do the magic.
To copy filters from view A to B we will need to read a few settings so we can set the same overrides and visibility controls.
Here is the code snippets for that:

- 🔓 Use **Transaction** to make changes
- For Each Filter:
- Get Filter Overrides
- Set Filter Overrides (it will also create it)
- Get Filter Visibility
- Get IsFilterEnabled
- Set these settings to new filter
And that should copy your view filters.
## Result
Here is the proof that it works:

Now you can take this snippet and extend it to copy many filters from many views in your project.
Just think of logical steps you need for your unique workflow.
**Happy Coding.**
## P.S.
I love when python code looks just like English.
Scroll through code snippets again and just read them as English, and it might surprise some of you, but python and API can be very easy to read too.
Sometimes we just need to know the right words, and then coding becomes easy. If you need help to learn these right words: 👉[**Click Here**](https://learnrevitapi.com/all-courses/pyrevit-basics)** to learn more.**
### ⌛Stop Rushing. Learning to Code Takes Time.
https://learnrevitapi.com/newsletter/learning-to-code-takes-time/
Have you tried learning to code in one day?
Let me guess. You found long video or even a course. You rushed through the whole thing and then you got even more confused. Well, at least that's what I did when I started.
And that planted a seed in my brain.

## It's always unique.
Programming is an individual journey.
There are many new terms, a lot of logic and too many abstract concepts in programming. But it's not 🚀 rocket science. Some learn it sooner, and some need more time. But eventually everyone can get there.
So, I thought I could share a short story on how I learnt OOP in python. Because, I also learnt something really cool about how our 🧠brain really works. And you should definitely take advantage of that.
## It made sense once I stopped.
When I started with OOP in python I was very lost.
I followed many tutorials, wrote some code, but I couldn't understand why would I need it. And I couldn't even find any reason when I would use it in the real world.
I spent days on it and then I just gave up.
I thought OOP is not for me. And I didn't even try to learn anything about it. But then, suddenly, something clicked in my brain.
Out of nowhere, OOP finally made sense to me.

I know it sounds weird, but I still remember that moment really well. I wasn't even coding or trying to understand OOP. I was just going about my day and it popped into my head. I finally knew where and how I could use it and most importantly why.
It's funny that I learnt what I needed when I stopped trying.
## Should you just stop?
No, that's not the point.
What I'm trying to say is that our brain can work in multiple ways. Sometimes you can learn something new and it instantly clicks. But other times - nothing makes sense. More you try - more confused you end up.
That's usually where subconscious comes into play. **Our subconscious works all the time.**
If you are going to think about something long enough, your subconscious will take notice and might even start looking for solutions. And you won't even know it's happening.

But eventually you will start getting your answers.
Usually it's subtle and you don't even notice it. But sometimes it might struck you and you just get it instantly. That's what happened to me with OOP, and that's why I still remember this moment.
💡 If you feel stuck with programming, just** give your brain some time and space to think it through**.
## P.S.
Have you experienced something similar?
Did you ever notice how you subconcious gave you an answer to something that didn't make sense to you before?
If not, pay attention. Because it's happening all the time.
### 📊 Control Toggle Parameters in Revit with a Custom WPF Form
https://learnrevitapi.com/newsletter/control-toggle-parameters-in-revit-with-a-custom-wpf-form-and-pyrevit/
One of course students asked me: *'How to create a Form to control parameter toggle state with pyRevit?'*
And the answer is WPF. Whenever you need to create a UI form with custom functionality, WPF is often the best choice. I know it sounds scary and it might even look intimidating, but it's not so complicated once you understand the basics.
And the best part? AI knows WPF pretty damn well, so you can get even more help from our robot friends 🤖.
But let me show you a quick solution to create a form to control toggle parameter of sheets.

P.S.
WPF is an advanced way to create UI forms. It's not for beginners, unless you are ready to learn a lot at once.
## How WPF works in pyRevit (1 min guide)
Let's have a quick overview to understand how to create WPF forms with pyRevit. I will keep it very brief as I have more videos on this topic if you are interested on YouTube.
In general we need 2 scripts for a WPF form:
- XAML Script - UI Design of our Form
- Python Script - Regular pyRevit tool that loads XAML
**XAML **- Is a Extensible Application Markup Language. It's like HTML but for Window forms.
**WPF **- is a framework to create custom modern UI forms.
SO, we will create two files, put it in the same folder and then reference xaml inside our py file.
## XAML Code
Firstly, let's look at the XAML code. As I've mentioned it's very similar to HTML structure, but it uses names from WPF framework.
To write XAML you would need to install Visual Studio IDE and set it up for WPF development.
I have a step by step [video on YouTube](https://www.youtube.com/watch?index=2&list=PLJHSZmHJLILGN2AodlpuRYv_Oi3DuLlRI&v=NxgBInJSixg) for that.
Once you have it, here is the code we need to write. And notice that each piece of code represents an UI element in the preview window.

💡*If you are a course member, you can access all code snippets in the ****pyRevit Code library**** that comes with the bundle.*
So, we copy all that code and create a 📄**UI.xaml **file inside your pyRevit pushbutton folder.
✅ **UI Design is done.**
## Python Code
Alright, now the tricky part.
We need to create a class that will represent our form and connect XAML code as the base. And then we need to add methods for additional functionality.
Firstly, we need to create a python class for the form.
Let's begin with a starter code with all methods listed, and then we will go and fill them in.

We will need a few methods inside this class:
- **__init__ **<- Class Constructor that will create the form itself. That's where we load XAML file, trigger populate_listbox method and show the form to a user
- **populate_listbox** <- This will get all sheets in the project and add them to the ListBox
- **create_listbox_item **<- This is a helper function to create WPF Control that will be added to the ListBox
- **UIe_search_text_changed **<- Event handler for a search bar to filter shown items in the list.
- **UIe_toggle_visibility **<- Change the parameter value when you click on CheckBoxes
- **UIe_btn_run **<- Close the form with submit button
## Final Code:
I will provide you the complete code and explain the basics.
- Import .NET Classes for WPF form
- Create a class that represents WPF Form
**0️⃣✨ Define the constructor method (init)**
Load XAML FIle
Trigger Populate Items Method
Show Form to the user
**1️⃣➕Populate Listbox**
Get all Sheets
Format the name you want to see in the list
Add listbox items using create_listbox_item method
2️⃣**➕ Add List box items using behind-code. **
- Create TextBlock
- Create CheckBox
- Create ListBoxItem
- Combine everything like matryoshka doll 🪆
- Add ListBoxItem to ListBox
**3️⃣⚡Event Handler for SearchBox.**
- Get value from search box
- Check ListBoxItems
- Hide/Show Items if it matches the search term
**4️⃣⚡ Event Handler for CheckBox**
- Get Sheet
- Set opposite Toggle Value
5️⃣⚡** Event Handler for Submit Button**
- Close the form

## P.S.
That's quite a long script, but that's because we need to control many thing in the UI form and I decided to add a search filtering as well.
WPF has a steep learning curve, but you can learn absolute basics to start creating cool custom forms for pyRevit to provide better experience and achieve more unique workflows.
If you need help, check my YouTube tutorials or you can start with my [**pyRevit Modern UI course here**](https://learnrevitapi.com/all-courses/all-courses/pyrevit-modern-ui).
### 📊How to Create Custom pyRevit Form with Multiple Buttons?
https://learnrevitapi.com/newsletter/how-to-create-custom-pyrevit-form-with-multiple-buttons/
Creating custom UI is quite an advanced topic.
But there is a easy way to with pyRevit. We can use **FlexForms **from **rpw **module, and it's already included in pyRevit by default. it's the easiest way to create custom UI forms.
Also I just got a question:** "How to create multiple buttons in FlexForm"**, so I will share the answer to this one as well with you.
## rpw FlexForm
**FlexForm **is a custom class that can create UI forms.
The best way to learn about **FlexForm **is to try it out yourself. So I will provide you 2 examples and you can try them on your own.
And to be honest, the code is quite self explanatory. You can Copy-Paste the code and then compare how your UI form looks to the code. And it will make a lot of sense.
I will provide you 2 examples.
## Simple FlexForm
Here is the first code example to create a very simple UI form.

This is how it will look like:

In genral you can see that we import a bunch of classes **from rpw.ui.forms.**
Then, we create **components **that will be stacked on top of each other, and we can use it to create our **FlexForm**.
Once you are done you can get values from your form with **form.values** property that will return you a dictionary.
When you create your components you will notice that we provide 2 arguments where user needs to make some input. The first one is the key that will be used for dictionary, so you can get this data out.
## FlexForm with multiple Buttons
Alright, how about creating multiple buttons for different purposes? That's also possible, but might be tricky first time.
You just need to understand how **Events **work in programming. In short, you can execute code when an event occurs. In this case button click.
So we can create another button and in **rpw.ui.Button** there is a parameter called **on_click **which can assign python function to the button click.

It's fairly simple to use, however there are a few things to keep in mind about events.
**Function Arguments:** Whenever you subscribe to an event, you'll need to have 2 arguments in a function: (**sender**, **event_args**).
- **Sender** - Refers to the UI object itself (button in this case).
- **EventArgs** - Refers to the event that was triggered (click in our case).
⌨️ Below is an example code snippet:

💡Make sure you **don't use parenthese**s when you assign a function to the **on_click** argument!
And then you get this form, where you will trigger functions with simple print statements on Button 1/2 and Submit will close the form as usual.

## Need more control?
**FlexForms **are great, but they are also limited. You can stack any number of simple inputs, however you won't be able to create more advanced UI forms with custom layouts.
If that's something you want to learn, you need to learn about **WPF Framework**. It has a steep learning curve, but it's absolutely the best way to create a custom UI forms that looks and functions exactly how you want. You literally can create anything with it.
Here is my latest UI Form with drag and drop functionality:

## How to learn WPF for pyRevit?
There are not many resources about WPF for python, so it makes it a challenge to get started.
However, since that's what I use in many of my forms people asked me many times to share how I do that. And that's what I did a few months ago.
I've created a full in-depth course about **WPF for pyRevit users** . I will show you step by step how to create custom good-looking forms for pyRevit tools.

You can learn more about it [**here**](https://learnrevitapi.com/wpf)
At the moment it's available only as a bonus to all my course members. They all got it for FREE. And if you join LearnRevitAPI you will also get it as a bonus.
However, I will make it for sale as a separate course in the future. Let me know if that's something you would want to see sooner.
### 📄The Unusual Henry Ford Policy That Can Transform AEC Projects
https://learnrevitapi.com/newsletter/the-unusual-henry-ford-policy-that-can-transform-aec-projects/
Henry Ford has innovated in the automobile industry, and there are a few lessons we could extract from that.
Back in the day, **Henry Ford** noticed some of his workers were standing around, doing nothing.
Instead of firing them, he gave them raises.
Wait, what? WHY?
## The Unusual Ford Policy
Henry Ford implemented an unusual policy in his factory: he paid workers for the time spent not working. And it worked better than anything.
Workers responsible for the production line could sit in a room, do nothing and get paid.
However, if something on the assembly line would break, then a red light would come on, and it meant:
**No Pay until Repaired**.
## Ford Policy Results
This unusual policy pushed workers to ensure that production line works without breaking.
They quickly came to conclusion - if they do their work with quality, they won't need to come back to the same problem again.
They really liked being paid for not working, so they had to get creative in how to prevent issues on assembly line. That meant they had to get creative:
- Pay more attention to details
- Inspect things on time
- Ensure quality work
- Use better quality parts
- Innovate how they worked
This empowered workers to take ownership of their work. They did everything to ensure assembly line runs without any disruption. And it meant they could get paid more for doing less.
They could sit and do nothing, but they knew that the red light would come sooner. So instead, they focused on making sure **Red Light **never comes on.
As the saying goes:
**"An ounce of prevention is worth a pound of cure." **
- Benjamin Franklin
## How does it relate to you?
Well, think of it, the process in AEC is like an assembly line with a lot of repetitive work.
If you could spend some time now and create a solution to your repetitive problems - you could prevent costly issues on-site. You need to take some ownership of your work and its consequences.
Think of all past issues on real projects and why they happened:
- Unnoticed clashes
- Miscommunication
- Bad Modelling Practices
- Rushed Delivery
- Human-error on repetitive tasks (inevitable)
Many could have been avoided with a little more attention or communication. But others could be automated and you could reuse this solution in your current and future projects.
**It's all about thinking long-term and innovating.**
Oftentimes, if you spend a few more minutes today, you can save a lot of hours in the future.
And what is a better way to do that, than programming?
You can write code today with a step by step instructions for a computer, and it will be executed on every project without any human-errors and in an instant.
## The Goal
Just imagine the day where you come to work, click on the button and you finish that annoying repetitive task you do on every project (Especially, if you hate it).
And now you have a full day to focus on more creative tasks where you actually need to use your hard-earned skill of an Architect, Engineer, BIM Specialist or any other profession within AEC you might have.
Would that be an amazing day?
[**Click here to learn more**](https://learnrevitapi.com)
### How to Be Lazy and Still Get More Done in Revit.
https://learnrevitapi.com/newsletter/how-to-be-lazy-and-still-get-more-done-in-revit/
You’ve probably heard that famous story about Bill Gates.
When faced with a tough problem, he’d hire a lazy person to solve it. Why? Because lazy people find *the easiest way* to get things done and get back to being lazy.
And you know what? He’s not wrong. Finally we can turn our laziness into a benefit.

## How to be Lazy the right way?
**Programming is made for us lazy folks.**
Instead of repeating the same tedious tasks in Revit over and over, why not teach your computer to do it for you?
- Hate spending hours renaming hundreds of views?
- Hate making simple change on hundreds of plans?
- Hate other repetitive tasks?
Well, you can spend time once and do it with a click. And not just these tasks, it can apply to many tasks in Revit.
And you will get more time back as a reward, so you can focus on more important things.
## But what if you're new to programming?
Let’s break another myth: **You don’t need to be a Python expert to create custom tools.**
A very basic understanding of **python **and **Revit API** is enough. And thanks to tools like ChatGPT, you can create your first scripts way before you fully understand how to code.
**Isn't it a great time to be alive?**
Obviously, you still might need to interrogate AI to get the right solution... But it still reduces the barrier of entry into programming world, especially for busy AEC experts like you.
**And here is the secret:** Understand the process and start creating very simple tools and improve as you go. You will be surprised what you can achieve in a few months since starting.
## Ready to Try?
You can follow [**this guide**](https://learnrevitapi.com/pyrevit-starter-kit) to create your own Revit Toolbar in just a few minutes.
This is the first step to create your Dream Tools for Revit.
### 👀 Your First Look at the pyRevit Hacker Basics Course
https://learnrevitapi.com/newsletter/your-first-look-at-the-pyrevit-hacker-basics-course/
Waiting for **pyRevit Hackers Basics **Course?
It's getting closer to the finish line, and I can't wait to release it! And I know many of you can't wait for that either.
So, I wanted to share a little sneak peak from one of the python lessons, so you get an idea what kind of content is coming to you soon.
[youtube 7Zr97izQo1o](https://www.youtube.com/watch?v=7Zr97izQo1o)
**👆Click here to Watch Short Preview**
## 🔎Course Changes
Initially, I wanted to include only pyRevit and Revit API Basics, but I had some last minute changes, and I've decided to include a **Python Mini-Course** for absolute beginners to help them learn python or refresh their memory.
So, it means that **pyRevit Hacker Basics Course** will include:
🔹**pyRevit Basics**
**🔹python Basics**
**🔹Revit API Basics**
You get everything you need to get started creating your own Revit Tools with Python.
It's a perfect course to get your hands dirty with code and finally create your own dream tools for Revit in a few days.
My goal was to create a quick and easy course to help you get started as soon as possible. And I think it will do a great job once it out.
## 📅 When?
The course is planned to come **within the next 2 weeks.**
That should give me enough time to finish editing and upload everything on my platform.
As usually, all lessons will include **Video **and detailed **Written Summaries.** So, it needs some time to finish everything.
## P.S.
**Stay Tuned For More!**
Or feel free to ask any questions by Replying.
### 🔍Get Existing Types Before Duplicating Them
https://learnrevitapi.com/newsletter/get-existing-types-before-duplicating-them/
I was helping one of the students inside the course to finish a cool tool - Split Wall into Material Layers. (Might share the full code later)
And for one of the steps - we needed to get existing WallType with a name, or create a new one if it doesn't exist. Simple step, but might be a bit tricky for beginners.
So, let me share how I do that and I think many of you will find it useful for your own code.
## Get Existing Type by Name
Firstly, let's try to get WalLType with a name in case it already exists. Very important step to avoid duplicates and errors.
There are many ways to do that, but one of the most efficient one would be to use **ElementParameterFilter**.
Filters might look complicated in Revit API, but it's very similar how we use them inside of Revit. And you need to use them a few times with code to get a hang of it.
In this case we will create a filter to check if TypeName parameter has exactly the value that we need. So we need to specify:
- Parameter
- Evaluator
- Value
- And apply it on **FilteredElementCollector**.
Same logic in Revit:

How do we do that with with Code? We follow the same steps as manually.
Here is the code:

If you are confused, you can use [this YouTube tutorial](https://www.youtube.com/watch?t=7s&v=GV1nwVtuCjA) to help you understand this filter.
## What if it doesn't exist?
Well, then we go to plan B - **Release the Dragon 🐉**
Oh wait, that's the wrong plan B...
Here is how to create a new **WallType **in case it doesn't exist:

I know it looks like a lot, but these are the same steps that you would do manually, aren't they?
- Select WallType
- Duplicate
- Adjust Type name
- Adjust Structure Layers:
- Functions
- Material
- Width
That's exactly what's happening inside this code.
Same steps as manually but with code.
💡Also, don't forget to use **Transaction **since we make changes to our projects.
And here is the result:
**EF Super-Duper Concrete Wall 3000**

Would you name it differently?
### ⌨️ What’s The Real Reason Behind Your Programming Journey?
https://learnrevitapi.com/newsletter/what-s-the-real-reason-behind-your-programming-journey/
I don't think that many of us thought that we would become coders. That's not how it usually starts.
In 90% of cases, it starts with a Problem. And it can be anything. Sometimes it's impossible to solve it manually, other times it's just a waste of time.
But sooner or later, we come to the realization that we are either stuck doing the same thing over and over, or we look for alternatives.
And programming is often a way out of that cycle. But how did you get interested in programming?
**Did you start programming because of a Problem?**
## Revit is not perfect...
Revit is a massive software targeted at all disciplines. So, as the saying goes** "Jack of all trades - Master of none"**. As a result - we all have a lot of problems working in Revit.
Probably, that's the reason why you are reading this newsletter about programming in Revit, am I right?
If that's the case, I would love to hear more about it. What kind of problems pushed you to start coding? Where did your programming journey begin?
I would appreciate it if you **hit reply and shared it** in a few words.
*I bet it was because of endless repetitive tasks.*
*But I might be wrong...*
## My Problem
Let me begin.
My programming journey started many years ago when I worked on a high-rise project. As you know, large projects tend to get repetitive really quickly.
I was working on a 34 stories building with 465 apartments.
So, even if I had a task that took me 5 minutes on each level, it wouldn’t take 3 hours (34×5 min). Instead, it would take far more. Every time I changed the level, I had to wait for a view to load up, and I lost focus every time. And this waste of time compounds a lot...
I had days where I felt like I did nothing for the whole day because of all that time wasted between tasks.
The final straw was the need for parametric modeling in Revit. There was no way to achieve what bosses wanted manually, so I had to dive into code. And that's how I started.
**But how did you get started?**
## Extra: Testimonial Highlight
I love getting testimonials from real students in my course. Here is the latest from **Regis**.
He just finished his 6th lesson and already developed a solution to a problem he had for a long time.
Probably that's only one of the problems that brought him to programming in search of a solution.
👀 I wonder what he will achieve by the end of the course.

### LearnRevitAPI May Disappear: What Should We Call It Next?
https://learnrevitapi.com/newsletter/learnrevitapi-may-disappear-what-should-we-call-it-next/
👋 Hi pyRevit Hackers,
The year has just started, but there are already some big things happening in Revit Community.
Yesterday, Nicolas from **RevitPure **has received an unusual gift from Autodesk - a **Cease and Decease Letter**, asking to delete his website...
And it's not just him. I've heard from other creators the same. Autodesk Lawyers has opened a hunting season, and it's more like friendly-fire. So, Nobody is safe (even **LearnRevitAPI**...).
I hope I won't need to delete my website any time soon, but we need to come up with a new name to be safe.
**Would you like to participate?**

## My opinion
Imagine promoting software and then receiving a letter from the company, asking you to delete your efforts...
A simple 'Thanks' would be enough I think.
Obviously, I'm biased since I own a **'LearnRevitAPI'** domain (at least for now...). However, I think they are making a huge mistake for their branding and marketing.
Anyone who owns a software should be excited that there are people who dedicate a lot of their time and energy to create educational content around that software. Both Free and Paid.
It makes community much better, stronger, and most importantly, it helps user to navigate the software and become better.
Imagine Revit without all amazing courses, blogs, forums and resources out there? Yikes...
I hope they realize it too.
## So, What's the New Name?
No idea yet...
To be honest, I wanted to change **LearnRevitAPI **for a while now, and I've even purchased another domain (pyRevitHackers.com). But that one isn't safe either...
So, we need something better and more secure.
At the moment the **BIMHackers and BIMCoders **are my favorite options, so I've already bought these domains.
But maybe, there is something better hiding in the plain sight?
My Alternatives were:
- BIMHackersHub
- BIM-Code
- BIMCodeLab
But there are not as exciting...
What do you think? And more importantly:
**Do you have a better suggestion?**
Hit **Reply **and share what's on your mind.
It's 0% expected and 100% appreciated. Thanks.
### 🔥The #1 Mistake New Revit API Programmers Make.
https://learnrevitapi.com/newsletter/the-number-one-mistake-new-revit-api-programmers-make/
Let's be honest - it's tempting to dive into the deep waters without learning to swim first.
PS. I've actually done it as a kid and I almost drowned. I thought I will learn how to swim after I jump, and turns out that's not how it works... Luckily, someone has pulled me out unconscious. Thanks!
Later in life, I did the same mistake again with programming. I thought why learn python basics and jumped straight into Revit API with python. It was brutal in beginning.
I had to learn 2 things that were dependent on each other. It made the whole experience much harder and way less fun.
So this time, let ME pull you out of the deep waters and give you an advice: **"Focus on Python Basics first".**
## Also, it's not just me!
I've seen so many messages from my students in the community and on LinkedIn who realized the same thing.

**Many start with Revit API without nailing python basics. And you pay for it with a lot of frustrations and confusion later on...**
So do yourself a favor, focus on Python basics.
Make sure you understand:
- Variables
- Data Types
- If Statements
- For Loops
- Functions
- Main Built-In Methods
- Main Built-In Functions
It is not so much, but this is essential for any pyRevit Hacker. This will allow you to take a problem and create your own solution with code.
## Where to Learn?
There are plenty of free online courses on python on YouTube, edx, coursera and many other places... Just choose what you enjoy watching the most.
But also, I want to tease something.
Would you like a **Python Course specifically made for Revit Users? **Does it sound exciting to you? Of course it does!
But wait, it's not here yet.
It's still something in progress. But you can help me refine it.
## What is your current python skill?
As a Chinese proverb says:
'**A Journey of a thousand lines of code begins with a single "Hello World**'. (Well, I might have changed it a little, but you get an idea).
It doesn't matter where you are in your python journey. But, could you share with me **what is your current python skill**?
It will only take a few seconds to select one of the options below. (And yes, it's a poll in an email. I was also shocked)
**POLL: 🐍What is Your Python Skill?**
[Absolute Beginner(Never Coded)](https://polls.kit.com/14367?option_id=50368&token=token)
[Beginner(Just Starting with Basics)](https://polls.kit.com/14367?option_id=50369&token=token)
[Intermediate(Basics like Loops, Functions...)](https://polls.kit.com/14367?option_id=50370&token=token)
[Advanced(I know how to use OOP and more advanced topics...)](https://polls.kit.com/14367?option_id=50371&token=token)
[Expert(Seasoned Developer)](https://polls.kit.com/14367?option_id=50372&token=token)
By voting with this poll, you will help me understand the python skill you have, so I can help you get to the next level faster.
**So please, select one of the options above.**
### AI Claims 80% of Your Code, But Here’s the Real Story
https://learnrevitapi.com/newsletter/ai-claims-80-of-your-code-but-here-is-the-real-story/
The robots are here! They are typing, and apparently, they want to take credit for everything you do in your code editor.
But wait, before you smash your PC to stop the robots, let me explain whether you should get an AI Assistant and how big companies mislead developers.
## Does AI write most of the code?
You might have seen articles like:
- GitHub Copilot is already writing 46% of code
- 88.5% Accenture of the code written by Copilot
- Google CEO: over 25% of new code is generated by AI
😨Damn, it makes you feel that programming is almost obsolete and that you are staying behind. That's FOMO tactics they use to get your attention.
Many accept these headlines as facts, but I want you to look at it from the other side.
**Imagine This:**
💻 You are sitting at your desk and coding the next amazing tool. You are about to print some value, so you type 'pr' and then AI-Assistant suggests 'print(item)'. That's exactly what you wanted, so you accept the suggestion.
And then **AI claims 80% of the code**. Wait what? How?
Well, you've typed 2 letters, while AI suggested 9 characters. So, AI wrote 80%+ of the code...
It doesn't matter that you would write exactly the same line of code. Forget about it, this line is made by AI now.
That's how big companies misleading people with these click bait headlines, saying that majority of code is written by AI.
It is like getting directions after you have already parked your car at the destination. Thanks, but I'm already here...
## Should you use AI?
No, if you want to stay behind. But in all seriousness, you had to set it all up yesterday. That's how much you need it.
AI is not your replacement. It's a tool to make you code faster and get better results. it can be incredibly useful, especially on something new. And it can claim a lot of the code sometimes, but who cares if your code works.
So, start using AI in your development.
## What AI Assistant should to grab?
In short - it doesn't matter.
There are so many options that you can spend weeks choosing the right one. You just need to start using anything, and then change to something else that suits you better or gives you less bugs.
Here is a list of the most popular options:
**Chatbots:**
- Chat GPT
- Claude
- LLMs with Ollama (self-hosted option)
**IDE Integrations:**
- TabNine
- GitHub CoPilot
- Continue AI
- Codium
- Codeium
- Cody
- TabbyML
**AI IDE:**
- Cursor IDE
**Online IDE with AI integration:**
- Replit
- CodeSandbox
- GitPod
Keep in mind that I barely scratch the surface with this list. There are too many options. So, I recommend start with anything and then jump to another one if you don't like it.
Right now I use **TabNine**, and it works well. But I might experiment with others soon.
Also, all these options come with a free plan with older and dumber AI models. Honestly, you will be better off paying a little to use the latest and fastest AI models. And it won't cost you a kidney.
Alternatively, you can also use free trial version of as many AI assistants as you want. You can do this for more than a year and compare all of them to find what works best for you. This is a great option if you don't mind changing AI every month.
Just start and then adjust.
## P.S.
I would love to hear what AI-Assistant you use and how it helps you. I will report back if I get enough replies to share what majority of you use and how it helps you.
**Reply to ErikFrits@LearnRevitAPI.com **and let me know about AI-Assistant you use.
### The Most Important Skill for Programmers (Hint: It's Not Coding)
https://learnrevitapi.com/newsletter/the-most-important-skill-for-programmers/
I think there is a misunderstanding about programmers.
Programmers are NOT people who just write code. It's like saying Revit is BIM...
Programmers are problem solvers first. Code is just a tool they use to solve problems at scale. It's like a wrench for a plumber or a hammer for a carpenter.
What makes us special is the ability to take a big, messy, chaotic problems and break them down into simple to follow instructions with logical steps written as a code.
That's what programmer's job is all about.
## Why is it important?
You need to understand that by becoming a programmer you become a better problem solver. Not just with code, but in general. It will help you look at any problem differently.
You pick up what's called a **computational thinking**. What's that?
**Computational thinking** is a way of solving problems that’s all about breaking big problem into smaller, manageable steps, spotting patterns and creating a step by step solution plan.
This is a very simple, but incredibly important concept.
## Meaning of Exact Instructions
Computers won't work for you by themselves.
Instead, they follow an exact written instruction plan. And programmer's job is to think about all the possible problems, and create an exact instruction plan for computer to follow.
Otherwise, errors, bugs, crashes or even worse things can happen...
And when I talk about **Exact instructions**, I really mean it.
There is an amazing example where a dad decided to make an **Exact Instructions Challenge** with his kids. It's hilarious and it is the best way to understand why it's important and what can happen when your code is not exact enough.
[**Watch it here**](https://www.youtube.com/watch?v=cDA3_5982h8), you won't regret it:

Imagine that dad is a computer, and you are being a kid who is writing instructions to solve a simple problem - **Make a Peanut Butter Sandwich🥪.**
Do you think you can do it?
## Can you write Exact Instructions?
Do you think that you can make an exact plan for **Making a Peanut Butter Sandwich **(or any other sandwich)**?**
It sounds simple, but **I bet that 90+% of you will fail on the first try. **And yes, I understand that you have a fancy diploma behind you on the wall. That's not the point.
**Try it now as an experiment, it takes less than a minute.**
**Come up with an exact instruction plan for creating a peanut butter sandwich.**
No code. Just think logically what steps you need to do to solve this 'big' problem. Write them on a paper if you want to.
**Got it?**
Alright, now watch the [**video **](https://www.youtube.com/watch?v=cDA3_5982h8)mentioned above and compare your plan to plans written by kids.
I guarantee that you will have an "aha-moment" that will stay with you for your whole life.
## P.S.
Did you manage to write an Exact Instruction plan on your first try?
**Hit 'Reply**' and let me know how helpful this exercise was.
### 🪟 How to Automate Sections with Revit API
https://learnrevitapi.com/newsletter/how-to-automate-window-sections-with-revit-api/
Creating sections in Revit is boring, and adjusting them to see only the right element is even worse.
So, I want to show you how to automate section creation with the Revit API, and I will try to break it down as simply as I can.
💡 You can see [Full Video Tutorial](https://youtu.be/SBEy55iLPAg) on YouTube!
### How to create Sections in Revit?
Let's start with the basics, How do we create a Section?
To create a [ViewSection ](https://www.revitapidocs.com/2023/fcc75682-bd99-a97d-5a4d-0f8eb9e92ab5.htm)we need to use [CreateSection ](https://www.revitapidocs.com/2023/d6228f68-3643-8aaf-72bb-f9a0b4125886.htm)method.

It takes 3 arguments that you see in the screenshot 👆
First 2 are not an issue, but the 3rd one will involve multiple steps to address the position and rotation of our elements.
### 🧠What do we need?
🧠 Let's brainstorm before we start looking at the code.
1️⃣ Firstly, we need to get Windows of each Type
2️⃣ Then Get Window Origin Point for Location
3️⃣ Create Vector to follow the wall's direction
4️⃣ Get Window Sizes
5️⃣ Prepare Transform (Location + XYZ Vectors)
6️⃣ Create SectionBox
7️⃣ Create Section!
💡 There will be a few minor additional steps like naming views and transactions, but overall these are the main steps.
Let's begin.
### 1️⃣ Get and Sort Windows
First of all, we need some elements to create sections for.
I will be working with windows, but you will be able to apply the same logic to other elements, as long as you understand the concept.
There are different ways to get a single window of each type. However, I decided to iterate through all the windows and combine their Family and Type Names to use as a key in a dictionary.

💡 I also filter out windows that are hosted only in walls!
### 2️⃣ Window Origin / 3️⃣Wall Vector
Then we can start iterating through all the windows and begin obtaining the Origin and Vector.
The Origin is simple - just use the **Window.Location.Point.**
For the **Vector**, we need to create a vector with the same direction as the wall where the window is hosted.
It's fairly simple; we need to get the curve and then we can create a vector from its Start and End points, as shown in the snippet.

### 4️⃣ Window Sizes
Now, let's get the sizes of our windows so we can create a matching section area. This will depend on the families that you are using.
In my case, I use the German Library from Autodesk, and there are two parameters used:
- Regular **Height **(Type, Built-In)
- Shared '**Hohe ab FBOK**' (Type, Shared
💡** In your case, make sure to adjust to your families!**

### 5️⃣Prepare Transform
So far, everything has been relatively straightforward. Now, we need to flex our brain muscle a bit, especially if you've never worked with vectors and the Transform class.
First, it's essential to understand the [**Transform **](https://www.revitapidocs.com/2023/58dd01c8-b3fc-7142-e4f3-c524079a282d.htm)class. This object holds information about location and rotation with XYZ vectors and is used to move and rotate objects in space.
We can already create a [**BoundingBox **](https://www.revitapidocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2.htm)with the correct size of a window, but we need to ensure it's placed where our window is located and rotate it to match its direction.
Additionally, to create a [**Transform **](https://www.revitapidocs.com/2023/58dd01c8-b3fc-7142-e4f3-c524079a282d.htm)instance, we need to use the [**Identity **](https://www.revitapidocs.com/2023/2eb2a180-c7ef-a0c0-0fa4-baef2901c351.htm)property. As I understand, this is a common design pattern in 3D software for Transforms, therefore it's not a constructor or method.

A few notes:
💡 [**Normalize**](https://www.revitapidocs.com/2023/6228ceb8-100b-daf8-78cf-0b7f514a1338.htm)[ ](https://www.revitapidocs.com/2023/6228ceb8-100b-daf8-78cf-0b7f514a1338.htm)a vector means we adjust its length to a single unit. This is necessary during calculations when scale is not important.
Setting .[Origin](https://www.revitapidocs.com/2023/9c67a7e5-c869-bfb9-c6fa-e5ac356868f0.htm)[ ](https://www.revitapidocs.com/2023/9c67a7e5-c869-bfb9-c6fa-e5ac356868f0.htm)is straightforward; it takes a single XYZ point.
Then, consider the Vectors. Here, the approach will depend on how you want to rotate your section. For instance, we will have to change these values depending on whether we want an Elevation, CrossSection, or Plan view.
I'll explain using the Elevation example:
- [**BasisX **](https://www.revitapidocs.com/2023/ac4f8d40-cd21-a6ed-0366-61cb86edb757.htm)- This is the vector we created along the hosted Wall.
- [**BasisY**](https://www.revitapidocs.com/2023/dfae1c2b-d0fd-0b56-3610-b7055f4169d3.htm)- That's just a vertical vector (BasisZ).
- [**BasisZ**](https://www.revitapidocs.com/2023/f0a5bbf5-41f2-ec36-80c4-207e9bae36d9.htm)- Here, we calculate the [**CrossProduct **](https://www.revitapidocs.com/2023/c5c099ad-e9f5-976b-94ee-d96af1c677f3.htm)between the first two vectors.
💡[**CrossProduct **](https://www.revitapidocs.com/2023/c5c099ad-e9f5-976b-94ee-d96af1c677f3.htm)- This calculates a new vector, which is perpendicular to the first two vectors. However, it will only work if they are also perpendicular to each other.
Think of the Transform Gizmo👇.

### 6️⃣Create SectionBox
Creating a [**BoundingBoxXYZ **](https://www.revitapidocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2.htm)is relatively straightforward. It has a constructor that requires no arguments, which returns a box with dimensions Min(-100,-100,-100) and Max(100,100,100).
For those who have never worked with bounding boxes, they are cubes defined by two opposite points (Min/Max).
Since the default origin is placed at (0,0,0), we need to create a box using positive values to move right and negative values to move left. The same principle applies for moving forwards/backwards and up/down.
Once you create a [**BoundingBoxXYZ **](https://www.revitapidocs.com/2023/3c452286-57b1-40e2-2795-c90bff1fcec2.htm)with the correct size and offset, the next step is to apply the transformation that was defined earlier. It's just a [**Transform **](https://www.revitapidocs.com/2023/297887ab-69bb-548e-cfb6-a3a23f410604.htm)property, so assign our transformation we made earlier.

### 7️⃣Create ViewSection
Now we are almost finished!
We've created our SectionBox argument, and the only thing left is to obtain the ViewSection TypeId.
For this, we can use the [**GetDefaultElementTypeId**](https://www.revitapidocs.com/2023/b62f6563-aca4-56dc-4697-7717932187b3.htm)[ ](https://www.revitapidocs.com/2023/b62f6563-aca4-56dc-4697-7717932187b3.htm)method, which takes the [**ElementTypeGroup **](https://www.revitapidocs.com/2023/f5b57d98-c551-9693-9009-8eb17fef8a14.htm)enumeration. Within this enumeration, there is an option - ViewTypeSection.

## ✨Final Code
So, we've covered all the steps, and now it's time to put everything together.
The final code will be available on my LearnRevitAPI blog in a few days. Sorry, it's a big lesson, so I need some time to write it out completely.
### 🎦 Follow Tutorial
Meanwhile, it's best if you follow my[ tutorial on YouTube.](https://youtu.be/SBEy55iLPAg)
It's a bit long, but there is a reason why it's 30 minutes long...
I wanted to explain certain concepts in more depth so that you don't just blindly copy my code, but actually understand every step that I wrote and apply it to other elements.
This will enable you to automate your sections across different categories!
So, I hope you will enjoy the video!

### Learn How to Convert C# Code to Python (for Beginners)
https://learnrevitapi.com/newsletter/how-to-translate-c-sharp-revit-api-code-to-python/
As pyRevit Hacker, it's important to understand C# Syntax. This can help you find a lot more code examples for Revit API.
And don't worry, you don't need to become C# devleoper for that. You just need to understand and recognize the main differences, so you can turn C# code into python. And it can be simpler than you would expect.
Let me show you the difference.
## Biggest Difference
There are multiple differences between C# and python syntax. However, one of the biggest one is - **Type Hinting.**
📦 **Type hinting** is a way for a programmer to specify Types of your objects in code. This helps IDE recognize classes and provide you better auto-suggestion and debugging results.
Type-Hinting is mandatory in C#, as it requires you to specify types of everything in your code. In python on the other hand, it's optional. It's still possible to do, but not everyone is even aware of that.
## Python vs C#
Python and C# have many differences in syntax, built-in functions and available modules. However, most of programming concepts and patterns stay the same, and can easily be translated between each other.
And when you deal with Revit API classes, then all properties, methods and how you use them stay the same. So it makes translating even simpler.
## Syntax Comparison
I could write about differences all day, but it's best to show you a few examples to **compare C# and python** syntax. This way you can understand it right away.
Are you ready?
Then, let's compare C# and python examples.
## Syntax Difference
Firstly, keep in mind that C# and Python have different syntax rules to define the scope of code.
**C#** uses curly braces **{}** to define code blocks and semi colon **;** to finish statements.
**Python **uses indentation (spaces or tabs) to define logical code blocks and doesn't need anything to finish statements.
For example, whenever you create a function in python; all related code will be shifted to the right to define a code block.
In C#, curly braces (**{}**) will be used to define scope of the function and semi-colons (**;**) to end statements.
👇 Check Example below.


💡 This example contains a lot, so let's start from the beginning.
## Variables
As you know, **Variables - **are used to create a container to store data that can be reused.
In **C#, **you need to specify the type of all variables. Even if it's as simple as int, string or anything else... There is also an option to use '**var' **for undefined data-type that can change..

**In python **we just assign data to a variable and that's enough.
However, there is an option to add type-hinting if you want. It helps pyCharm (or other IDE) to recognize classes and provide you better auto-suggestions.
We can use **#type: ClassName** syntax in python in the end of a variable line like a comment.

**Key Takeaways:**
💡 In C# we specify **Type **before the variable name. And each statement is closed with a semicolon (**;**).
## Variables - FEC Example
Here is an example for creating an instance of **FilteredElementCollector **with Revit API.
Python is very clear:

But in C#:
- Specify **FilteredElementCollector **type before variable name
- Use '**new**' keyword when we use constructors
- The line ends with a semi colon **;** 🤮

💡In this case, "if you remove all these extra things that C# needs, it will actually become python syntax. Did you know that?
## Conditional Statements
Next, let's compare conditional statements. Let's define a number and create a few print statements.
Here is the python snippet:

Now, have a look at the same code snippet but in C#. You will notice that it has a lot more symbols and uses different function to print (**Console.WriteLine**)

**Main Difference:**
- Type Hinting
- Curly-Braces (**{}**) define scope of if statements
- Renamed **elif **-> **else if**
- Semi-Colons (**;**) at the end of statements 🤮
But overall, it's very similar.
## Loops
Next, let's look at loops in C# vs python.
Firstly, here is our loops in python:

Now, let's write similar code in C#.
You will notice right away that the **range **function looks very foreign in C#, because it uses special syntax. But the rest is very similar.

**Main Difference:**
- Range Syntax **(int i=0, i<10; i++)**
- Curly-braces (**{}**) define code blocks.
- Semi-Colons (**;**) end statements
- Decreasing count (**-=**) is done differently in C# (**--**)
## Function
Ready for the next level?
Let's compare functions. You will see 2 functions in the screenshots.
- First one doesn't return anything
- Second one returns some data
In python type-hinting isn't necessary. However, it's possible to add it if you want to. Pay attention to **#type: (View, bool) -> View** syntax. If you are a beginner, you can ignore it.

In C#, you will notice right away that it doesn't use special keyword like '**def'**.
Instead it needs to use the **Type **of returned element before the function name. And if nothing is returned, then you need to use '**void' **keyword .
💡If a function returns an element with a type of **View**, then you write **View **class name before function name.

**P.S**. Type-Hinting in py2 vs py3
💡 There are multiple ways to define type hinting in python especially in newer version of python. I prefer to use the method that works both in python2 and python3.
You need to create special a comment under your function name and specify **types **in the same order as your arguments.
**#type: (arg1, arg2) -> return_elem**
## Conclusion
Sorry, this newsletter got out of control and became really long.
I hope you enjoyed comparing C# and Python code snippets and you realized that it's not so different after all.
Always look for patterns and you will be able to translate C# to Python yourself. You will learn it over time with practice.
Lastly, I want to provide you an example from Revit API Documentation. You can check [Wall.Create](https://www.revitapidocs.com/2023/4a42066c-bc44-0f99-566c-4e8327bc3bfa.htm) method and then compare these 2 examples:


Do you recognize the differences?
## P.S.
Some python users might start thinking that C# is stupid because of all curly braces and other stuff. But in reality it's just a different language, with different rules and it requires you to be more precise when you code.
Both languages have their own strengths and weaknesses, and both are widely used by developers. Everyone has their own preference depending on the goal.
However, as a pyRevit Hacker I have to share this with you, that's how many of us feel when we encounter C# code, don't we😄?

### AI Assistant for Revit with Python | pyRevit Hacker Podcast #1
https://learnrevitapi.com/newsletter/add-ai-assistant-for-revit-with-python-pyrevit-hacker-podcast-episode-01/
So, here's a plot twist I didn’t see coming: I’ve started a podcast🎙️!
Yep, the pyRevit Hackers Podcast is officially live. The first episode will show you how to Add AI Assistant for Revit with Python.
Why a podcast, you ask? Well, let me tell you a little story how it happened.
## 📩Surprise Email
A few months ago, I was going through my emails and then suddenly, 2 messages caught my eye.
The first one was from Nigerian Prince offering me untold riches, but the second one is what really got me excited. It was from **Ashish Ranjan.**
Unlike Nigerian prince, Ashish had something far cooler and it was for real - a Python script that brings AI-Assistant to Revit.
I thought, what's the catch but he was actually very nice. He wanted to share his code and suggested to make a tutorial for everyone.
That's the spirit of a pyRevit Hacker right there!
So, I thought I have to bring him on my channel and make an interview so he can share with us:
- His Programming Journey.
- How did he add AI-Assistant to Revit?
- What were the challenges?
- Go through the code.
- And explain how beginners can do the same?
That's how **pyRevit Hacker's Podcast** has started with the first episode:
[**Create AI Assistant for Revit with Python:**](https://youtu.be/zYJ1SA_Rpq0)

👆Click on the heading or the image to watch the podcast.
## P.S.
Don't forget to leave some feedback in YouTube Comments about the podcast.
- What did you like/dislike?
- Who Should I bring next?
I've never expected to start a podcast, so I'm improvising and have no idea where it's going.
### 😥Hate Subscriptions? The Lifetime Deal is back!
https://learnrevitapi.com/newsletter/the-lifetime-deal-is-back/
It took a while, but I understand how much you hate subscriptions (who doesn't). So, I've decided to listen and make the necessary change.
**🎉 The lifetime deal for LearnRevitAPI is back!**
No subscriptions. No renewals.
**Just a one-time payment to unlock EVERYTHING.**
## Access All my Courses
Once you join LearnRevitAPI you get lifetime access to:
- **LearnRevitAPI Course **- An In-Depth course that teaches you Revit API basics, and how to apply it in the real-world.
- **Modern GUI for pyRevit Course **- Learn how to improve user experience with your own custom good-looking UI forms.
- **pyRevit Hacker's Community** - A place to connect with other hackers and ask for help in case you ever get stuck.
- **pyRevit Hacker's Library** - Library of my code snippets from Courses, Tutorials and other tools I create.
- **[Coming Soon] pyRevit Hacker - Basics **( the course for absolute beginners, to help you get started with pyRevit, python and Revit API)
- There are a few more courses, but let's not get ahead of outselves
**LearnRevitAPI **isn't just a regular course. This is a platform that provides everything you need to automate Revit and create custom Revit Add-ins.
**You are one step away from creating your dream tools for Revit.**
[**Join LearnRevitAPI**](https://learnrevitapi.com/)
## What's Coming Next
I'm currently working on the **pyRevit Hacker Basics Course**, designed specifically for beginners. It will provide you a good understanding of:
- **pyRevit Basics**
- **Python Basics**
- **Revit API Basics**
By the end of the course you have a solid understanding of everything you need to start creating your first Revit tools.
And yes, I planned for a short course, but you know me: I can’t stop adding value! So, expect more lessons and even better results.
Stay Tuned it's coming very soon!
👀 Here is a sneak peak:

Now you have to wonder why I wear robber's mark and steal my own icons. 😂
## P.S.
Are you ready to make a change in your career this year?
**Reply with 'I want to be a pyRevit Hacker' **to get the best deal on **pyRevit Hacker Basics **course launch.
*Action-takers always get rewarded!*

### 📁 Steal Like an Artist: pyRevit Secrets for a Quick Start
https://learnrevitapi.com/newsletter/steal-like-an-artist-pyrevit-secrets-for-quick-start/
In the programming world, the phrase "Steal Like an Artist" isn’t about plagiarism, it’s about learning, borrowing ideas, and building upon the knowledge of others.
You've probably heard the joke about programmers being better at google and copy-pasting code. It's true, but copying code is never enought. You need to know how to adapt it to your own needs.

## pyRevit Folder Structure
As you know, **pyRevit **extensions are made of a simple folder structure. There is a folder for every button or panel in Revit's UI.
Want to add or remove tools? Copy or delete a folder. Voilà!
**Here is pyRevit Extension's Anatomy:**

💡 *The left column is the bare minimum. Everything else? Just nice-to-haves for organization or extra functionality.*
If you are new to pyRevit, check out [this short video](https://www.youtube.com/watch?v=kLNwxT-xIhM) to learn how to create your own extension and understand the basics.

## Build Toolbar Quick
pyRevit and its extensions are open-source, which means you've got access to source code of all add-ins.
And by exploring existing tools, you can build you own custom toolbar with 30-50 useful tools in no time. It's very common way to start with pyRevit.
This isn't done to claim sombody's work. It's a strategic step to create a proof of concept and introduce pyRevit to your team and the boss.
It's much easier to say "Look at this magic" and explain the potential of pyRevit and show that you cna modify everything.
It makes it clear that:
- It's easy to start
- It's possible to achieve
- And most importantly - It's worth investing into.
So, let me show you where to find countless examples of pyRevit code so you can learn from existing code and impress your boss.
## pyRevit Toolbar
Firstly, look at pyRevit toolbar. There are a lot of useful tools and I still find new tools to me from time to time.
Once you find a tool you like:
- Use **ALT + CLICK** to open source folder of that Add-In
- Copy .**pushbutton **folder
- Paste into your own extension
- Reload **pyRevit **and voila.
✅**Achievement unlocked:** Steal Like an Artist.
## pyRevit Additional Extensions
**Want More?** Well, check out additional extensions in pyRevit.
Go to **pyRevit -> Extensions Manager.**

This will open up this menu to install even more pyRevit extensions made by other pyRevit Hackers. And everything is also 100% Open-Source.
**Isn't it amazing?**

**EF-Tools** extension alone has more than 70 tools, and I grant you the permission to do anything you want with my code.
So don't feel any guilt for reusing my tools. I want you to!
## GitHub
Do you want to open Pandora's Box of pyRevit extensions, where you can get hundreds or even thosands more?
**Are you ready?**
- Go to GitHub
- Search for 'pyRevit' (or [click here](https://github.com/search?q=pyRevit&type=repositories))
- Explore 250+ repos that represent extensions

Can you imagine thousands more pyRevit Add-ins 🤯?
Let's do a quick math. Let's say out of everything we find only 15% are going to be good.
**260 x 0.15 = 39 Extensions**
And then let's say you find 3 tools in each one of them worth copying.
**39 x 3 = 117 Amazing Tools**
That's just very conservative numbers. In reality some of you are going to find even more tools or less. Depending on the discipline and what kind of works you do.
But it should be clear that there are a lot of useful tools you can learn from and even reuse parts of them.
**Still not convinced that pyRevit is the best add-in for Revit?**
### 🔎This Prompt Will Help Beginners Understand Revit API Code Faster.
https://learnrevitapi.com/newsletter/chat-gpt-prompt-for-revit-api-code/
Last month, I opened an old script of mine that I hadn't touched for a long time. I thought 'No problem - it's my own code, it won't take long '. But I was wrong...
You see, when I'm testing an idea, I write code quick and dirty. And then I go back and clean it up once I know it works.
But I hadn't refactored this one yet, and it felt like solving a rubik's cube in the dark.
Sound Familiar?
Now, imagine trying to read someone else’s code written in the same rushed, chaotic style. What do you do?
## Code can be Confusing
As you know, pyRevit and its extensions are open-source, which is amazing. It gives us access to hundreds, maybe even thousands of tools so we can:
- Explore Code
- Learn From it
- Copy Reusable Snippets
But let’s be real, sometimes, looking at someone else’s code is like reading another language.
You’ve probably heard the programmer joke:
*When I wrote it, only God and I knew how it worked. Now, only God knows.*
## How to Reverse Engineer code?
Back in the day, reverse engineering meant hours of scrolling through code, documentation, googling every line of code you don't know and questioning your life choices. We all hated it, but we didn't have a better option.
Today, we do. AI has changed the game and we can get faster and better answers without judgement about asking stupid questions (I'm also guilty of the last one).
But here's the catch: **AI is only as good as your prompt.**
So you need to spend some time on creating better prompts to get much better results. Or you could use the prompt I made for beginners to help them reverse engineer sombody's code.
Would you want that?
## The Prompt 📜
I was working on a tutorial for beginners and after some trial and error (and a lot of tea), I came up with this gem. It's perfect for helping beginners understand the code they found.
-, -, -, -, -, -, -, -, -, -
Here is the prompt:
> **NB** **I want you to act as a seasoned Python software engineer with extensive expertise in Revit API and pyRevit. I will provide a piece of existing pyRevit code, and I need you to:**
>
> 1. **Provide a short and clear code overview outlining all the steps.**
> 2. **Write a step-by-step tutorial tailored for a beginner pyRevit user, explaining each section of the code in simple terms.**
> 3. **Describe all Revit API concepts used in the code, offering beginner-friendly examples where necessary.**
>
> **Here is the code:**
>
> **{PASTE CODE HERE}**
-, -, -, -, -, -, -, -, -, -
This prompt works magic because:
1. It explains the code in plain English without BS.
2. It generates a tutorial for beginners based on the code.
3. It identifies Revit API concepts you need to know and often explains them clearly for beginners.
The secret is to ask it to make a tutorial, it starts to think differently about the output. This approach is like having a teacher walk you through the code step by step.
But sometimes you need to ask that teacher twice 👀.
## P.S.
Got a better prompt? I’d love to hear what works for you when chatting with AI.
**Just hit *****Reply*****!**
### A New Year’s Resolution Worth Keeping: Revit Automation
https://learnrevitapi.com/newsletter/new-year-resolution-automate-revit/
Welcome to 2025!
It’s time to set those New Year’s resolutions.
Yes, the same ones we swore we’d stick to last January and promptly forgot by mid-February... But hey, let’s give it another shot, right?
**Setting goals is the first step in turning the invisible into the inevitable.** – Tony Robbins
And imagining is free, so we’ve got that going for us already! And on top of that, I've also prepared something to help you achieve this goal of **becoming pyRevit Hacker **in 2025.
## pyRevit Hacker - Basics
I've decided to create a shorter version of my **pyRevit Hackers Course** to make it:
- Easier to Follow
- More Affordable
- And Much Quicker to get the first win and start bragging to your friends about your new super power in Revit.
And the best news, it’s *almost done*! I'm ready to release this masterpiece very soon during **January 2025**.
**But are you ready to be a part of it?**

This Course will provide you the necessary pyRevit and Revit API Basics and give a taste of being a pyRevit Hacker.
After this course you should have enough pyRevit basics and Revit API Basics to start creating your own custom tools.
Stay tuned for more news and release information!
## P.S.
I also set my New Year's Resolutions and I want to provide even more useful content about Revit API and pyRevit during 2025.
But, hold up - I'd love to know **what kind of content you enjoy **the most:
- EF-Tools Complete Tools
- EF-Tools Code Breakdown
- Revit API Tutorials
- Revit API Longer Webinars
- pyRevit Podcast
- Anything else?
Would you mind hitting **Reply **and telling me what do you love (or hate) the most, so I can focus on what you actually enjoy?
Seriously, the sooner you reply, the sooner I can stop talking to myself about what my audience wants and actually hear it from you.
**Hit Reply **to get more of what you Enjoy**.**
### Revit API Quick vs Slow Filters (What are they?)
https://learnrevitapi.com/newsletter/revit-api-quick-vs-slow-filters-what-are-they/
If you've worked with the Revit API for a while, you've probably come across Revit API Filters.
They might seem tough at first, but they're not too hard to use. The main challenge is figuring out which filters are available in the Revit API.
Even I found some new filters myself not long ago...
> **TIP** **💡So Let's look at all filters in Revit API**
## Filter Types
When I talk about **Revit API filters**, I mean filters that can be applied to [**FilteredElementCollector**](https://www.revitapidocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3.htm)[ ](https://www.revitapidocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3.htm)for get elements.
Don’t confuse them with View Filters, which is another topic.
Generally, there are 3 types of filters in Revit API:
- [**ElementQuickFilter**](https://www.revitapidocs.com/2023/ebc95d82-11fc-69f6-2df1-52331dd36443.htm)
- [**ElementSlowFilter**](https://www.revitapidocs.com/2023/e06b1e14-dd8d-8137-74ac-8ac4929eee85.htm)
- [**ElementLogicalFilter**](https://www.revitapidocs.com/2023/3b8d6b55-0cab-1810-1188-840800e5eaa2.htm)
Let's briefly explore each of them to understand how they work.
## Slow vs Quick Filters?
You might be wondering why there are both 'slow' and 'quick' filters.
Does 'slow' mean we shouldn't use those filters?
And the answer is - Not at all!
As the name suggest one type of filters is quicker than the other.
Quick filters work faster because they look at a database record. They don't need to know every detail about the elements to filter them

On the other hand,** slow filters** need more information about each element. That means they have to load all the details of the elements into memory to check their different properties.
> **WARN** **❗But you shouldn't even worry about this difference.**
>
> **Most of the time, this just means your script will take a tiny bit longer - like a fraction of a second instead of one second.**
>
> **For most of our scripts, this small difference doesn't matter. The main thing is to make it work. Worrying about speed only matters if it's really slow.**
>
> **💪 So just use whatever works for you!**
## Quick FIlters
All quick filters are based on [**ElementQuickFilter**](https://www.revitapidocs.com/2023/ebc95d82-11fc-69f6-2df1-52331dd36443.htm) Class.
This means you can scroll down to **Inheritance Hierarchy **to see all of them.
I would recommend scrolling through the list and read their names. They are quite self-explanatory.

Also, almost half of these filters have shortcuts in the methods of **FilteredElementCollector**.
> **TIP** **💡 Shortcut means that there is a method in FilteredElementCollector that applies that filter to the collector.**
>
> **For Example:**
> **.**[**OfClass**](https://www.revitapidocs.com/2023/b0a5f22c-6951-c3af-cd29-1f28f574035d.htm)**() method applies **[**ElementClassFilter**](https://www.revitapidocs.com/2023/4b7fb6d7-cb9c-d556-56fc-003a0b8a51b7.htm)** to the collector**
>
> **So, if a filter has a shortcut like this, just use it. It makes things easier!**
## Slow Filters
Just like quick filters, all slow filters are based on ElementSlowFilter class. So you can scroll down to inheritance Hierarchy and get a list of all these filters!

💡None of Slow Filters have shortcuts in FEC class. However, there are many interesting filters to explore.
Especially **ElementParameterFilter** and [**ElementIntersectsFilter**](https://help.autodesk.com/view/RVT/2024/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Element_Intersection_Filters_html)**. **These are not as simple to use, but they are really powerful!
I've recently created a detailed video about **ElementParameterFilters**. You can watch it by clicking on this thumbnail:

## Logical Filters
Lastly, there are just 2 logical filters:
- [**LogicalAndFilter**](https://www.revitapidocs.com/2023/3e334aaf-2b39-58bd-d2cc-94e9c89bac57.htm)
- [**LogicalOrFilter**](https://www.revitapidocs.com/2023/a00da224-d330-452d-a45f-5abffa2e57e6.htm)
These filters combine other filters using **AND/OR** logic. When applied to a collector, either all filters must be true (**AND **logic) or at least one (**OR **logic) to select your elements.
## How to Apply Filters?
**FilteredElementCollector **has a method called [**WherePasses**](https://www.revitapidocs.com/2023/42d4eef3-55a1-2739-0ef8-6bc1d9fc2755.htm), which takes your Filter as an argument.
To create a filter you would need to look in Filter's Constructors.
Let's start simple and look at - [**ElementIsCurveDrivenFilter**](https://www.revitapidocs.com/2023/cdfd2844-094c-cf6b-8303-3f34a125668f.htm)
This filter requires no arguments, so you simply call it to create and apply the collector.

Other filters might have more arguments to create them.
For example - [**FamilySymbolFilter**](https://www.revitapidocs.com/2023/24cfdb4a-07e4-522d-4b9a-e0bba9387d5f.htm)
This filter needs Family Id as an argument.
I will manually write Id of that Family in this example:

> **TIP** **💡 Generally, most filters are quite straightforward to use.**
>
> **The key is knowing if there's a filter that can help you find the right elements. Once you know that, you will figure out how to use it.**
>
> **So, I would encourage you to scroll through the list of filters to better understand them.**
## Resources
I recently discovered the** Revit API Developer's Guide by Autodesk**.
It has an nice page about all these filters, which I highly recommend for a deeper understanding.
[Here is the link](https://help.autodesk.com/view/RVT/2024/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Applying_Filters_html)
### pyRevit Hackers Map: 59 countries where people automate Revit.
https://learnrevitapi.com/newsletter/pyrevit-hackers-map-where-people-automate-revit/
When I started the LearnRevitAPI Course, I never imagined it would reach so far and wide. Today I've decided to put it in perspective and create this cool map overview with countries where pyRevit Hackers live.AEC experts from 59 countries are becoming pyRevit Hackers🪄

This map isn't just a cool visual. It's a representation of where AEC experts understand the value of programming and automation, and they aren't afraid of code to make it happen.
**A huge thanks to this growing community of pyRevit Hackers.**
Your feedback, questions and success stories motivate me to keep improving course materials and creating even more lessons to help you automate your boring work.
## List of Countries
If you are curious where pyRevit Hackers live, here is a list of all countries from where people have joined LearnRevitAPI Platform.
- Albania
- Algeria
- Argentina
- Australia
- Austria (🏠I live here)
- Belgium
- Brazil
- Bulgaria
- Canada
- Chile
- China
- Colombia
- Croatia
- Czechia
- Denmark (I got BA here)
- Ecuador
- Egypt
- El Salvador
- Estonia (🛖Home)
- Finland
- France
- Germany
- Greece
- Hong Kong
- Hungary
- India
- Ireland
- Israel
- Italy
- Japan
- Korea
- Lithuania
- Luxembourg
- Malaysia
- Mexico
- Netherlands
- New Zealand
- Norway
- Peru
- Philippines
- Poland
- Portugal
- Romania
- Saudi Arabia
- Serbia
- Singapore
- Slovakia
- Slovenia
- South Africa
- Spain
- Sweden
- Switzerland
- Turkey
- Ukraine
- United Arab Emirates
- United Kingdom ( I worked in Yorkshire a bit)
- United States of America
- Viet Nam
- Virgin Islands
## P.S.
Have an idea for a video?
Let me know.
### ✨ Do You Want to Become pyRevit Hacker in a Week?
https://learnrevitapi.com/newsletter/wanna-become-pyrevit-hacker/
Are you a busy AEC Professional who is tired of being just another Revit User?What if becoming **pyRevit hacker** can finally let you:
🔸 Create Custom Tools for your workflows
🔸 Automate Repetitive Tasks
🔸 And take your career to another level**Does it sound exciting to you?**
## How to become pyRevit Hacker?
There are many reading this who want to become pyRevit Hacker. But some of you don't even know where to start.
Maybe idea of learning python, pyRevit and Revit API feels overwhelming. And you don't want to spend months to get started...
I get it, that's a valid concern...
However, what if there was a **mini-course** designed specifically to help you get started with:
🔹 **pyRevit Basics** – How to create your First Revit Toolbar.
🔹 **Python Basics **– How to code inside of Revit.
🔹 **Revit API Basics **– Enough to create simple Revit Add-ins
💻 I want to condense beginner's basics into a 2-3 hours mini-course that will help Revit Users to go from zero to creating your own simple Revit Add-ins in a week, max 2.
That sounds ambitious, but I know 100% that it can be done with the right training. And I want to provide you that training.
**Does it sound like something you would want to be a part of?**
## Wanna be pyRevit Hacker?
If what I wrote about **pyRevit Hacker Mini-Course** sounds exciting to you, reply: **'I want to become pyRevit Hacker🪄'**
This will do 2 things:
1. It shows me how many people are interested
2. You will be among the first people to be notified.
3. Maybe even you get a special discount 👀
You are one step away from becoming **pyRevit Hacker**
### 🤔How To Select Elements in Revit Last Changed By Specific User
https://learnrevitapi.com/newsletter/select-elements-last-changed-by-specific-user/
🤔 **Ever caught yourself asking, “Who did this?” in a Revit project? **If yes, you’re not alone.
While there is a tool to identify who modified a specific element, it’s not much help when you want to select everything one user has touched.
💡 **Let’s learn how to find, sort, and select elements last modified by a specific user.**

## Get All Elements
➡️ First, let’s get all 3D elements in our Revit project. We’ll use the [**FilteredElementCollector**](https://www.revitapidocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3.htm)` for that`. We can apply **WhereElementIsViewIndependent **to get all 3D Elements and exclude view dependant elements like tags and dimensions.

💡 **Tip:** You can adapt this method to collect different types of elements depending on your needs.
### Who Did That?
Now we can go through all elements and look inside who has last touched them.
There is a [**WorksharingUtils**](https://www.revitapidocs.com/2023/ae7857a0-4e9b-f9c1-84c7-8b250af68068.htm) class in Revit API that has a method - [**GetWorksharingTooltipInfo**](https://www.revitapidocs.com/2023/1e54c25f-7d7a-7484-be7b-d741084418a9.htm).

This method returns a [**WorksharingTooltipInfo**](https://www.revitapidocs.com/2023/64e2bf53-2787-6cb7-ac29-b73777892ed3.htm) object with these key properties:
- [.](https://www.revitapidocs.com/2023/c6d2a047-8f18-103a-804d-cd2a0ff43c40.htm)[**Creator**](https://www.revitapidocs.com/2023/c6d2a047-8f18-103a-804d-cd2a0ff43c40.htm)
- [.](https://www.revitapidocs.com/2023/d6f0d595-a7e8-b2fa-9e9b-c74c705cb350.htm)[**Owner**](https://www.revitapidocs.com/2023/d6f0d595-a7e8-b2fa-9e9b-c74c705cb350.htm)
- [.](https://www.revitapidocs.com/2023/6d289dd3-16cd-499f-0837-573db0fb508e.htm)[**LastChangedBy**](https://www.revitapidocs.com/2023/6d289dd3-16cd-499f-0837-573db0fb508e.htm)
Here is a code sample:

💡 **Focus on the property that matters most to you.**
### Sort Elements by User
By now you have all 3D elements and you know who touched them last. Let's sort it in a dictionary sorted by LastChangedBy user.
I will use defaultdict. It allows you to specify the default value for items in case they don't exist. This will help you avoid the error and save a few lines of code so you can append items even to new keys right away.
❌ Otherwise you would need to check if user already exists in a **dict**, and either create an empty list or append to existing. Sounds boring, isn't it...
Here is the Code

### 👉 Select User from List
Lastly, let's create a simple UI form to choose between users to select elements.
The easiest way to do that is to use [SelectFromList ](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056?pvs=25#a0077880c0054f80817decc20c5cc816)form from [pyrevit.forms](https://pyrevitlabs.notion.site/Effective-Input-ea95e95282a24ba9b154ef88f4f8d056).

And that's how it will look:

### Select Elements
Now we have everything we needed. We just need to select these elements with [Selection.SetElementIds()](https://www.revitapidocs.com/2023/cf8c11bb-f0c7-6d50-cbdf-41d0a010d9d6.htm).

Since it need ICollection we need t convert a list of items into a .NET List[ElementIds]. That's not complicated, you just need to import it and specify the right Type.
Here is the code:

### Final Code
✨ Here is the final Result put together.

### Testimonial Highlight
🥳Another Happy LearnRevitAPI member

### 🌍5 New Languages are added to my Revit API Tutorials
https://learnrevitapi.com/newsletter/revit-api-uttorials-available-in-multiple-languages/
🤯Over night I can speak 5 New Languages on YouTube!
Well, kind of...
YouTube has granted my channel an Auto-Audio Dubbing feature and it will translate audio into 5 new languages. Isn't it amazing?
## How to change audio?
When you open my YouTube Videos, you can click on ⚙️ icon and select an Audio Track.

You can test it on** **[**this video**](https://youtu.be/R4y8acUa2LY)
That's a game-changer! It means you can enjoy my Revit API and pyRevit tutorials in other languages. That's a heck of a feature for people who find it hard to follow my tutorials in English.
I'm very excited to reach the new audiences and spread what I know about Revit API and pyRevit in more languages.
Check it out on my YouTube. ANd please let me know:
❓**Are Translations Good Enough❓**
## Translate my Courses
Many have asked me previously about translations for Learn Revit API.
It would be amazing to add more languages, and it's kind of possible. But it would take a lot of time to create good translations and add to all my videos.
I want to look into that in the future and see if I can automate this process.
Meanwhile, could you let me know **what language are you most interested in?**
💡If there is huge demand for a certain language I might look into that sooner.
Happy Coding!
Viel Spaß beim Programmieren!
¡Feliz codificación!
Buona programmazione!
Boa codificação!
Bon codage !
Хорошего Программирования!
### ❌Avoid These 30 Beginner pyRevit Errors with this Checklist
https://learnrevitapi.com/newsletter/pyrevit-checklist-to-avoid-30-most-common-beginerrs-mistakes/
🤦♂️ Ever spent days making a Revit Add-In, felt super proud, and finally shared it with your team. Then, nce they hit the button - BAM - they get a giant red error message...
It’s the worst. Not only is it embarrassing, it can even reduce the trust your team has in your automation skills.
So I've made something to avoid that.
## How to Avoid Revit API Issues?
If you’ve been there (and who hasn’t?), I’ve made something that’ll save you next time.
You can grab my **30-Step pyRevit Checklist** that will help you catch those easy-to-miss Revit API errors. Use it before you share your tools with your boss to maintain your pyRevit Hacker reputation.
You can [**watch this video**](https://lnkd.in/dkiFyahu) where I go through the checklist and share my thoughts on these points.
## 📃pyRevit Checklist
Use this pyRevit Checklist to avoid common Revit API errors:
👇


## P.S.
If I missed something, please tell me so I can update the checklist.
Click **'Reply'** to help me complete this Checklist.
### 🔽Revit API Filters: Quick vs Slow, what's the difference?
https://learnrevitapi.com/newsletter/revit-api-filters-quick-vs-slow-whats-the-difference/
If you want to get very specific elements you might need to use Revit API filters. They are a bit confusing at first, and you don't even know what's available.
So let me get you up to speed about filters in Revit API.
### Filter Types
When I talk about **Revit API filters**, I mean filters that can be applied to [**FilteredElementCollector**](https://www.revitapidocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3.htm)[ ](https://www.revitapidocs.com/2023/263cf06b-98be-6f91-c4da-fb47d01688f3.htm)for get elements.
Don’t confuse them with View Filters, which is another topic.
Generally, there are 3 types of filters in Revit API:
- [**ElementQuickFilter**](https://www.revitapidocs.com/2023/ebc95d82-11fc-69f6-2df1-52331dd36443.htm)
- [**ElementSlowFilter**](https://www.revitapidocs.com/2023/e06b1e14-dd8d-8137-74ac-8ac4929eee85.htm)
- [**ElementLogicalFilter**](https://www.revitapidocs.com/2023/3b8d6b55-0cab-1810-1188-840800e5eaa2.htm)
Let's briefly explore each of them to understand how they work.
### Slow vs Quick Filters?
You might be wondering why there are 'slow' and 'quick' filters?
Does 'slow' mean we shouldn't use those filters? And the answer is - Not at all!
As the name suggests, one type of filter is quicker than the other.
Quick filters work faster because they look at a database record. They don't need to know every detail about the elements to filter them.

On the other hand,** slow filters** need more information about each element. That means they have to load all the details of the elements into memory to check their different properties.
**❗But you shouldn't even worry about this difference.**
Most of the time, this just means your script will take a 0.0001s longer, so I wouldn't worry unless I do something crazy.
💪 Focus on making them work and leave efficiency for another day.
### Quick Filters
All quick filters are based on [**ElementQuickFilter**](https://www.revitapidocs.com/2023/ebc95d82-11fc-69f6-2df1-52331dd36443.htm) Class.
This means you can scroll down to **Inheritance Hierarchy **to see all of them.
I would recommend scrolling through the list and read their names. They are quite self-explanatory.

Also, many of these filters have method shortcuts in FEC Class.
💡Method Shortcut means that there is a method in **FilteredElementCollector **that applies that filter to the collector.
For Example:
.[**OfClass**](https://www.revitapidocs.com/2023/b0a5f22c-6951-c3af-cd29-1f28f574035d.htm)() method applies [**ElementClassFilter**](https://www.revitapidocs.com/2023/4b7fb6d7-cb9c-d556-56fc-003a0b8a51b7.htm) to the FEC collector. So it's a simple way to use it that makes it quicker and easier for us.
But you could also create it separately and apply by using **WherePasses()** method.
### Slow Filters
Next Slow Filters. Just like quick filters, all slow filters are based on [**ElementSlowFilter class**](https://preview.mailerlite.io/preview/52352/emails/107466222859192217).
So you can scroll down to **Inheritance Hierarchy** and get a list of all these filters!

💡None of the Slow Filters have shortcuts in the FEC **class.** However, there are many interesting filters to explore.
Especially **ElementParameterFilter** and [**ElementIntersectsFilter**](https://help.autodesk.com/view/RVT/2024/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Element_Intersection_Filters_html)**. **These are not as simple to use, but they are really powerful!
I've recently created a detailed video about **ElementParameterFilters**. You can [watch it here](https://www.youtube.com/watch?v=GV1nwVtuCjA).

## Logical Filters
Lastly, there are just 2 logical filters:
- [**LogicalAndFilter**](https://www.revitapidocs.com/2023/3e334aaf-2b39-58bd-d2cc-94e9c89bac57.htm)
- [**LogicalOrFilter**](https://www.revitapidocs.com/2023/a00da224-d330-452d-a45f-5abffa2e57e6.htm)
These filters combine other filters using **AND/OR** logic. When applied to a collector, either all filters must be true (**AND **logic) or at least one (**OR **logic) to select your elements.
## How to Apply Filters?
Now how do we apply filters?
First of all, we need to create them by looking at the constructor method and providing the right arguments if necessary.
Once you have a filter, you can use a method called - **WherePasses **to apply your filters.
Let's start simple and look at - [**ElementIsCurveDrivenFilter**](https://www.revitapidocs.com/2023/cdfd2844-094c-cf6b-8303-3f34a125668f.htm)
This filter requires no arguments, so you simply call it to create and apply the collector.

Other filters might have more arguments to create them.
For example - [**FamilySymbolFilter**](https://www.revitapidocs.com/2023/24cfdb4a-07e4-522d-4b9a-e0bba9387d5f.htm)
This filter needs Family Id as an argument.
I will manually write the **ID of that Symbol **in this example:

## Conclusion
💡 Generally, most filters are quite straightforward to use.
The key is knowing if there's a filter that can help you find the right elements. Once you know that, you will figure out how to use it.
So, I would encourage you to scroll through the list of filters to better understand them.
## P.S.
Do you want to learn more about any specific filter?
Let me know.
### 📙How To Master Getting Elements in Revit API
https://learnrevitapi.com/newsletter/master-getting-elements-in-revit-api-with-fec/
Getting the right Elements is half the solution, and it doesn't need to be complicated.
Let's explore how to get elements elements by using FilteredElementCollector Class.
## What is FEC?
FilteredElementCollector(FEC) is one of the most used classes in Revit API. It allows you to get elements by applying filters.
There are 2 ways to apply filters:
- Use FEC methods (Simple Filtering)
- Create actual Revit API Filters (More Advanced)
In a nutshell here is how FEC is usually used.
1. You create collector by providing correct **doc**
2. Then filter by Class or Category (or both)
3. Then you filter Instances or Types
4. And you convert to a list of Elements or Element Ids
This is the most typical way of getting elements with **FEC**

## Revit API is Repetitive
**FilteredElementCollector is easier than it looks!**
I know it might be confusing to see that loooong line of code for the first time. However, it's one of the most repetitive classes.
👀 Have a look at the image below.

You can see that to get different kinds of elements we use nearly the same line of code with minor changes. You just need to use it a few times to get used to that.
## More FEC Examples
The best way to learn about FEC class is to see a lot of examples and then copy a few yourself.
So, have a look at even more examples of using FEC and compare the code when you get different elements.

## Video Tutorial
If you want to learn more about FilteredElementCollectors, I recommend you to** **[**watch this video**](https://www.youtube.com/watch?v=MfJTPIOo7nY) where I will break it down and provide more examples.

## Download E-Book on FEC
Additionally, I want to provide you my older E-Book on how to work with FilteredElementColletor. It has explanation and also a lot of code examples.
I made this E-Book in 2022 and it had thousands of downloads since. So I hope you will like it.

[**Download E-Book Here:**](https://download.filekitcdn.com/d/ru8eCyToA7UfCbdDJsbTqJ/bFWCg4T67LczK1EAq6sAKL)
[**Master Getting Elements with Revit API**](https://download.filekitcdn.com/d/ru8eCyToA7UfCbdDJsbTqJ/bFWCg4T67LczK1EAq6sAKL)
### 🎦Video Tutorial on Automating Shared Parameters with Revit API
https://learnrevitapi.com/newsletter/revitapi-shared-parameters-tutorial/
After I've shared snippets on automating shared parameters, I got a really good engagement from you, so I decided to make an additional video to explain it better.
I hope it will help you understand the workflow better and save a lot of time bringing your parameters to your projects.
[**Click Here**](https://youtu.be/R4y8acUa2LY) to watch watch Video Tutorial:
**Automate Shared parameters in Revit with pyRevit**

## Code from Video
Here is the full code snippet from the video.
It might be long, but it's fairly simple if you follow me along the video above.

### Why Beginners Shouldn't Be Afraid to Explore Revit API
https://learnrevitapi.com/newsletter/why-beginners-shouldnt-be-afraid-of-revit-api/
If you are a beginner Revit API hacker, you shouldn't be afraid to explore Revit API. You won't change anything by accident.
Whenever you make changes with Revit API you need to use 🔓Transaction.
If you don't, you will encounter an error message saying 'Attempt to modify project without Transaction'.
And this is great news for beginners. It means you don't have to be afraid to mess something up when you explore Revit API.
Let me explain.
## Why we need Transactions?
Transaction Class in Revit API is like a guardian of your projects. It makes sure that you can only make changes that are on purpose, and nothing is changed by accident.
**This is great news for beginners as you don't have to be afraid to explore Revit API.**
Many are afraid to try anything new with Revit API on the live projects, and it's good protective measure for sure, but also know you can't mess it up by accident.
## How Transactions Work?
Transactions are very simple to use. You have to create a transaction by providing:
- **doc **- The project where you make changes
- **change-name** - Text shown in the Undo menu of Revit
And here is how it looks

You can write anything before and after the Transaction, just make sure that code that makes any changes is between **Start **and **Commit **statements.
## What if I get an Error?
Often time you might encounter errors with your code during Transaction that was started. And it's also nothing to worry about.
If you **Start **Transaction and then you get an error, it will be **RolledBack **by default. It means it will not apply any changes and keep the same state as before transaction was started.
But it's still recommended that you use **Try/Excep**t statements, to avoid showing huge red wall of error text to users.
However, make sure you can see error message during development, so you can solve the issue.
Here is example with Try/Except

## Transaction with Loops
Another important advice I want to share is to keep transactions out of loops.
Sometimes it makes sense to make it inside the loop, but keep in mind that it will drastically affect your execution time, as each change would have to update the database, and it can take a lot of time on large projects...
So as a rule of thumb - keep Transactions out of loops if possible.

## Transaction Context-Manager
Lastly, I want to let you know that you can use **Transactions **as a **context-manager.** If you new to python - context-manager is when you use **with** keyword.
It's pretty much the same thing, but some people might prefer to use it for readability purposes.
Here is example:

💡 You can even create custom context-manager and include Start, Commit, Try, Except all included.
## Have Questions?
Let me know if you have any questions about Transactions and how to make changes in Revit API.
**Hit 'Reply'** and ask a question.
### Automate Key Parameters in Revit API
https://learnrevitapi.com/newsletter/automate-key-parameters-in-revit-api/
After last couple of emails about shared parameters I got an interesting question:
**'What about Key-Parameters in Revit API?'**
And it's a tricky one, so let me explain.
## Key Parameters
As you know we can create **Key Parameters** in Revit to control multiple values. It's very common to use them with Rooms to control multiple parameters.

And if you explore it with Revit API, you will realize that you can't set key values using **String** names, instead it has **StorageType.ElementId**, so it can be tricky to find the right values.
So let me break it down.
## Get Key-Parameter Values
To get all key parameter values, I use a trick with **FilteredElementColletor **and **ViewSchedule**.
If you going to open **ViewSchedule for your Key-Parameter **you can get 2 important values:
- **KeyScheduleParameterName Property **to match schedule to your parameter name
- **Possible Key Values **to get the right **ElementId**
I think this code snippet will explain it far better:

- With this code we define the name of Key-Parameter we are interested in ('Room Style')
- Get All Schedules
- Find Schedule with matching KeyScheduleParameterName
- Get Values with **FilteredElementCollector(doc, view.Id)**
- Sort in a Dictionary
This is the easiest way I found to get these values.
## Set Key-Parameter Values
Once you have a list of possible values, it becomes simple.
You can select the value you want, and use **Set **with **ElementId** value.
Here is sample:

This will help you automate your Key-Parameters with Revit API.
## Have Other Revit API Questions?
Let me know if you have other Revit API Questions, especially about parameters while I'm on this topic.
This helps me find interesting ideas to make content about.
**Hit 'Reply'**
### Automate Shared Parameters in your Projects with Revit API
https://learnrevitapi.com/newsletter/automate-shared-parameters-in-your-projects-with-revit-api/
Importing parameters in Revit one by one is really boring and soul-draining. It's one of the tasks I hated the most...
So, being a pyRevit Hacker, I wrote a script to solve it. And I want to share the basics with you so you can do it as well.
## Brainstorming
Before you start automating anything in Revit, just go through the process manually and try to break down all the steps you do.

Let's write all the manual steps we do:
- Select Shared Parameter
- Choose Type/Instance
- Choose Parameter Group
- Choose 'Values can very by group'
- Choose Categories
I bet you already do these steps so fast, that you don't even notice it. Now we need to follow the same steps with code.
And let's start from the end and look at the documentation. You will find the following method to add parameters:

💡 This method will be obsolete in 2025, but it works in all previous versions. So I will only describe that.
You can see we only need 3 arguments, let's get them one by one.
## 1. Definition
Definitions are the blueprints of your parameters. And we can get **ExternalDefinitions** from **SharedParameterFile**.

Step 1: Select Shared Parameter
Here is a complete code snippet that will:
- Open SharedParameterFile
- Iterate through Groups and Definitions
- Sort in a Dict
- Create pyRevit.SelectFromList form to select

💡You can adjust the code to anything else if you want other logic on selecting parameters.
## 2. Binding
The next one is Binding. If you explore docs, you will notice that it's an abstract class and we need to use children classes:
- **InstanceBinding**
- **TypeBinding**
So we are creating option for this setting.

Step 2: Select ParameterBinding
When you look at how to create them, you will notice that we also need to create a CategorySet.
- **InstanceBinding Constructor (CategorySet)**
- **TypeBinding Constructor (CategorySet)**
So we are combining Category Selection and Instance/Type toggle. Here is a code:
There are 2 ways to get your categories and then you can insert them to your NewCategorySet:

Then we need to decide if we want Instance or Type Binding, and we also have 2 options to create this kind of binding:

💡 You just need to select one code line from this example.
## 3. Group
Lastly, we need to choose a ParamegerGroup.

Step 3: Select Parameter Group
It's very easy because we will use **BuiltInParameterGroup Enumeration**, so it already contains all possible values same as in Revit UI.

## Put it all Together
Alright, we went through all the steps briefly, now let's just combine it into a single code snippet you could actually start using to automate this boring task with some python code.
Here is full python code:

And here is the end result in action:

## Testimonial Highlight
Here is a recent LearnRevitAPI Testimonial.

### 🤔 Check if Shared Parameters Loaded with Revit API
https://learnrevitapi.com/newsletter/check-if-shared-parameters-loaded-with-revit-api/
Whenever you create a custom tools, you often need to work with your shared parameters. And before you do anything with it, you better ensure that you have your parameters loaded to avoid crashing.Here is how to do that.
## How to read Project Parameters?

We need to get that list of loaded parameters inside the project and check if out parameter names are included or not.
We need to get Parameter Bindings Map in Revit API with this code:

Keep in mind, that it's a bit tricky to work with, because you need to use **ForwardIterator** to get items from it. You can't treat it like a regular list or other containers.
## Forward Iterator
A **ForwardIterator** in the Revit API is like a one-way list reader. It lets you go through items in a collection one at a time, starting from the first item and moving forward, but you can't go backward or skip around.
It's used in API to be as efficient as possible in terms of memory handling.
Here is a code example of how to get **ForwardIterator **and grab all parameter definitions and read their names.

Keep in mind that you get Definitions
- A **Parameter Definition** describes the parameter's rules and structure, like its name ("Height"), type (Length), and other things... It's the template used by elements.
- A **Parameter** is what every element have based on the definition and it can have different values across all elements.
## Check if Parameter Loaded
Lastly, once you have a list of loaded parameter names, it's quick and easy to check what is loaded or not.
Here is how

## Final Snippet
In conclusion, let's put it all together in a single snippet.
I know that it looks confusing to use **ForwardIterators, **but you can just copy this code and make a function out of it.

## Want more?
Let me know if you want to learn more about Shared Parameters in Revit API and what exactly you want to learn.
Hit '**Reply**' to share ideas.
## Testimonial of the Week
I love getting feedback from my audience and students. Here is the recent one that made my day!

You can[ ](https://kudos.learnrevitapi.com)[**share testimonials here**](https://kudos.learnrevitapi.com)
### 🌚Automate Dark Theme Icons for pyRevit with THIS Script
https://learnrevitapi.com/newsletter/automate-dark-icons-in-pyrevit/
As you know Revit has a dark theme. Some people love it, some hate it. But it certainly affects how our extensions look like.Your extension might not look good in dark theme if you use dark icons... So, let's solve this.
And being a developer, don't you even dare fixing it manually! Let's put our coding skills to work and create dark theme icons for all our tools with a single click.
👇 [**Watch Video Tutorial Here**](https://youtu.be/AeMghfEIGLs) 👇

## Prepare project
We will use any python 3 version so we can use **Pillow **package. This is the most used package for Image manipulation with python.
If you use pyCharm, open Interpreter Settings and install pillow package. If you use different IDE, you would need to use **pip install pillow** via console.

💡 I recommend to create a new virtual environment so you don't clutter you main space. But you can also uninstall it later.
## Convert icon.png
Next, add any icon as a test file in the same folder with your python script. Once we make the code work for one image, we will adjust to go through the whole extension.
Now place any** icon.png** next to your **python **file and let's write the following code:

Here is what's going on:
- Open image with Image class from pillow library
- Define Color to replace with
- Load Image Data (list of pixels)
- Replace visible pixels (Keep Transparency)
- Save Updated Image as **icon.dark.png**
## Refactor to a function
Before going further, let's convert our code into a function to make it easier to work with.

## Get All Icons
Now we need to scale and find all icons in our extension. There are many ways to do that, I will use os.walk function.
Here is a simple function:

os.walk will provide:
- root - the provided root path
- dirs - all nested folders
- files - list of all files in all nested folders
So we will use files and filter those ending with icon.png.
**yield - **creates a generator from the function. Instead of returning whole list at once, it will be giving one item at the time.
## Create Dark Icons
And lastly, you can convert all your icons for the dark theme by calling these 2 functions.

And now congratulations. If you followed correctly, you should have dark-theme icons in pyRevit. Here is how my EF-Tools looks like:

## P.S.
Don't forget to watch the [**full tutorial here**](https://youtu.be/AeMghfEIGLs):

### 🤔 Did you know you could use pyRevit in Revit 25 for months ?
https://learnrevitapi.com/newsletter/pyrevit-for-revit-2025-wip/
Did you know that we could use pyRevit in Revit 2025 for couple of months already?
If you are a regular Revit user, it means you can continue using your favorite pyRevit tools.And if you are a pyRevit hacker, it means that you can test your code in Revit 2025 and continue developing more.
[**Click Here**](https://youtu.be/B1CJTK-4U8g) to watch 3-minute Tutorial on that:

## I was lazy to update
Like many of you, I knew about it for months, but I was too lazy to install and test it.
But now I'm finally starting to work on EF-Tools and I need to test my tools in Revit 2025. So I had no choice, but to install pyRevit WIP version to test it.
And it's great. I had no issues, everything works and so far haven't found any bugs. I only heard from some people that you might not be able to install other extensions from GitHub for now.
But it sounds like the package used in pyRevit is a little outdated. So nothing serious so far.
[**Check the video**](https://youtu.be/5acR-vAaL5E)** **if you also need pyRevit in Revit 2025.
## Found a bug?
If you happen to find any bugs with pyRevit in Revit 2025, I think it would be great to share it with dev team on GitHub.
Most of the times finding the bugs is the hardest task.
### ⌨️Use this code to load your custom UI forms in pyRevit
https://learnrevitapi.com/newsletter/load-your-custom-ui-forms-in-pyrevit/
Probably you've heard that WPF is really hard to get started with. Maybe you even tried and failed, and now you are convinced it's impossible to learn it...
However, it's actually not that hard to get started if you know where to start.

**Definitions:**
**WPF **- Framework for creating custom UI Forms
**XAML **- Markup language for creating WPF Front-End Design
**🥷pyRevit Hacker - **A person necessary to make it all work. Luckily that's who is reading this message right now.
## 😥 How I Started
Like many of you, I wanted to create a custom UI forms in pyRevit. I read that WPF is the best option, but I had no idea what it means and where to start. And unlike you, I had no Chat GPT....
So therefore, in the old school manner I went on YouTube and found a bunch of tutorials.
But, 99% of WPF tutorials were for C#... And the 1% that mention IronPython weren't that helpful to apply in pyRevit for absolute beginners.
I was about to give up, but then I realized that pyRevit had a bunch of WPF forms with the source code. I tried to put all the pieces of the puzzle together, but I remember that it was really hard for an absolute beginner.
I've spent couple of days and somehow I managed to display my first form. I still had no idea what's going on, and I did too many mistakes on my first try.
But being a stubborn learner I continued experimenting with WPF with the brute force. I made a bunch of simple WPF forms but they were over complicated and I still had very little understanding of what's going on.
## ✨Here is the Solution✨
So let me save you countless hours or even days of struggling with the most important code snippet you will need.
In general, you need 2 scripts for WPF forms.
XAML script for Front-End Design
IronPython script for Back-End Logic
And the biggest challenge is to connect these 2 files.
That's where majority of pyRevit users fall. But not you!
So, I've attached an image with a code snippet that shows you how to load any XAML file into your class to display it in Revit. That's the first step you need to do to create WPF form.

Remarks:
- Place XAML file in the same folder as python
- Do not add any Events in XAML
I hope it will help you with WPF forms!
## Still Confused?
If you still confused about WPF, you can use this training that will help you get started and understand what the hell is WPF.
[**Click here**](https://learnrevitapi.com/free-lessons/wpf) to watch the training.
### 🔽 Revit API Parameter Basics for Beginners: How to Get, Read and Set
https://learnrevitapi.com/newsletter/revit-api-parameter-basics-for-beginners/
Revit is all about working with parameters. That's where we store our data and control everything else.So, it's crucial to understand how to Get, Read and Set new values in your parameters.So, Let's have an overlook of parameters in Revit API.
## Parameter Types
Firstly, keep in mind that there are 5 types of parameters in Revit API:
**🔹Built-In Parameter**
**🔹Project Parameter**
**🔹Shared Parameter**
**🔸Global Parameter**
**🔸Family Parameter**
Let's look into how to work with the first 3 types of parameters.
## How to Get Parameters?
When dealing with parameters, firstly you need to get them. There are multiple ways of getting you parameter:
- **LookupParameter('p_name') **Method
- **get_Parameter(BuiltInParameter) **Method
- **GetParameter(ForgeTypeId) **Method
- **GetParameters('p_name') **Method
- Iterate through **Parameters IList**
And maybe even a few more...
Personally, I prefer to use **get_Parameter **and **LookupParameter **methods, so that's what I will teach you.
## Get Shared/Project Parameters
Shared and project parameters will always have the same names (as long as they are added to the project...)
You can get these parameters by using **LookupParameter('p_name')** method and providing parameter name as an argument. Very straight-forward.
When you use this method, make sure you also check if you found the parameter, because it's very likely that parameters from one project, might not be present in another project.
Here is a simple example:

💡NB! Do not use this method for Built-In parameters because they are language dependent.
## Get Built-In Parameters
To get built-in parameters, it's best if you use **get_Parameter(BuiltInParameter)** method.
For that you need to use **BuiltInParameter** **Enumeration**, that contains a list of all possible values. It's really big list and it's not always obvious names...
So you have 2 options to find the right **bip **(**BuiltInParameter**):
- **Guess it with Autocomplete.**
Sometimes it's similar to how parameter is named, so you might guess it.
- **Check with RevitLookup**.
Go to Revit -> Select an element -> Snoop with Revit Lookup -> Open Parameters -> Find your parameter -> Look into Definition.BuiltInParameter.
That's where you will see the exact bip you need to use.
e.g. **Comments **have bip:
**BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS**
Here is a code sample to get Built-In Parameter:

💡It's possible to get Built-In Param by name, but you might break it in other Revit languages. So better stick to the method I showed you above.
## Instance vs Type Parameters
Also, very important: How to get Instance vs Type parameters. That's very simple, but beginners often stumble over this.
Let me be clear.
**element.Parameters** -> List of **Instance **Parameters
**elem_type.Parameters** -> List of **Type **Paramters
Element and element type are related in Revit API, they are not the same object! So you have to get the right object to get the right parameter.
But it's not hard, here is an example of getting Instance and Type parameters:

## How to Get Paramter Value?
Now you have a parameter, how do you read it?
To read parameters, you need to know its **StorageType. **Usually it's very clear. If you work with text parameters like comments, mark and other, it will have **StorageType.String.**
If it's a numeric parameter, it can be **StorageType.Double **or **StorageType.Integer.**
If it refers to other objects like Types, Materials, Levels... Then it will have **StorageType.ElementId**
You need to know the StorageType, because there are separate methods for getting values with the right type. If in doubt, you can also reference **Parameter.StorageType** property.
Once you know it, you can use one of the following methods:
**param.AsDouble()**
**param.AsElementId()**
**param.AsInteger()**
**param.AsString()**
Here is screenshot from **RevitLookup:**

Usually you would look into your elements with Revit Lookup and it will be very clear what you get with each of these methods.
In the example, you can see that **StorageType **is **String **and **AsString **will return you **'Special Wall'** value.
So you would write:

💡 Same applies to both Built-In or Shared Parameters.
## How to Set Parameters?
Lastly, how do you override parameter values?
We need to use **.Set()** method to change value, and you need to provide a value with the correct type.
💡If you provide wrong type, it won't show you errors! It will silently ignore what you tried to do, and you might spend hours debugging because you don't see error message but also nothing changes.
🔓 Another thing to keep in mind is that you need to use Transaction.
In Revit API we can't make any changes to our projects, unless we use **Transaction.Start** and **Transaction.Commit. **This is like a guardian of your Revit projects to avoid unwanted changes and make it easier for us beginners to explore API.
Here is an example of how to do that:

## Bonus Example
💪 Give it a try yourself!
Open RevitPythonShell and write this,
it will get more clear what is going on.
✅ Try Getting a few BuiltInParameters. Read and Set values.
✅ Do the same with Project/Shared Parameters

This code snippet will teach you a lot about Parameters in Revit API. Give it a try.
## Want to learn more?
[**Click here**](https://www.youtube.com/watch?t=373s&v=YoLxucuC6Ss) to check my video about Revit API Parameters on YouTube. This will help you learn more and see some examples in action.
## P.S.
Have any questions about Parameters in Revit API?
Hit 'Reply' and let me know.
### 📰New Sheet Generator for Revit with pyRevit Source Code
https://learnrevitapi.com/newsletter/free-sheet-generator-for-autodesk-revit/
In the past, I hated creating a lot of sheets in Revit and then dragging one view at the time... And while it's not so bad, waiting for Revit to load up all the views and make repetitive clicks over and over was too boring...
So finally, I decided to make this process faster and more fun by creating EF-SheetGenerator.This tool should speed up sheet creation in Revit with a lot of controls. And you are in luck, since you can steal all the source code I wrote including my awesome WPF form.
You can watch[ ](https://youtu.be/SxcxeErbLgc)[**this 4-minute video**](https://youtu.be/SxcxeErbLgc) to see how it works:

**Here is the **[**Source Code on GitHub**](https://github.com/ErikFrits/EF-Tools/tree/main/EF_Tools.tab/Sheets.panel/col1.stack/EF_SheetGenerator.pushbutton)
## How it works?
This tool is part of my **EF-Tools extension**. So you can install it, use it, look at the source code and even steal something for your own tools.
In general, the tools is quite simple.
- Get a list of all views
- Sort desired Views by Sheets
- Provide SheetName and SheetNumber
- Choose TitleBlock
- And then Iterate and create:
- Sheets
- ViewPorts
Many of you can do that on your own already.
But, the biggest challenge is the WPF UI form, it's quite advanced because of Drag and Drop functionality and behind-code to create new SheetCard on the + symbol.
But with the source code and help of Chat GPT you can decipher what I wrote, and apply to your own needs.
If you decide to my code for other tools, please tag me on LinkedIn when you share your results. I'm very curious.
## EF-Tools is Back
Also, EF-Tools is finally back on track!
This is how I started my career 3-4 years ago as a content creator/educator, and I think that's what many were waiting for.
So, I want to:
- Fix bugs in existing tools
- Rewrite some tools to improve functionality
- Update UI Design
- Add More Cool Tools
So, if you are an EF-Tools user, be prepared to see a lot of tools change their places or even names.
## Have Suggestions?
Feel free to many suggestions for EF-Tools.
Especially, if you know about certain bugs in existing tools.
### ✨Big News for LearnRevitAPI: 400 Members✨
https://learnrevitapi.com/newsletter/big-news-for-learn-revit-api/
🎉 Today we hit a big milestone of 400 members, who love this course and the community. 🎉
A year ago, I launched the LearnRevitAPI course with a simple goal: to help AEC professionals Learn Revit API and pyRevit, saving time and unlocking new possibilities in their Revit workflows.And we are on the right track !🙏Huge thanks to everyone who joined early.

## Platform is Changing.
The LearnRevitAPI Platform is changing!
The best courses are never finished, so this platform is going to turn into a library of courses for pyRevit developers with annual subscription (Existing Members keep Lifetime).
This change will allow me to:
- Add More Courses
- Update Existing Modules/Lessons
- Invite other experts on the platform
In general, I will continue making the best platform to learn programming for Revit and provide you a better experience.
## First Bonus Course
The first FREE bonus course is coming in less than a week.
Starting on 20th of November, all members will get access to a new bonus course: **WPF Course for pyRevit Users**
It's an in-depth WPF training specifically made for pyRevit users. It will help you create good-looking UI Forms from scratch where you have full control.
And there is more courses planned for the future!
**🎉 Thanks again everyone once again 🎉**
**and Happy Coding!**
### 🚀WPF Course for pyRevit - Lesson 04
https://learnrevitapi.com/newsletter/wpf-course-for-pyrevit-lesson-04/
🚀Are you Ready to create **your First WPF Form with XAML?**
In this lesson, we’ll create a simple WPF Form and I’ll break down UI components and how they work as we use them.
Afterall, the best way to get familiar is to start using XAML.
🙌 Enjoy the lesson, you will learn a lot!
[**👉 Click Here to Watch Full Lesson**](https://learnrevitapi.com/free-lessons/wpf/1-04-xaml-intro)

## What Exactly Is XAML?
XAML stands for **eXtensible Application Markup Language**.
It's a declarative language that we use to define and initialize objects in **WPF**. Think of it as a blueprint for your user interface.
Just like **HTML **is used to structure content on the web, **XAML **is used to structure your **UI components** in a **WPF **form.
Also, keep in mind that
- **WPF** is a framework for building rich desktop applications
- **XAML** is an XML-based language for defining UI elements in WPF.
XAML has a very similar syntax to HTML to define components with angle brackets and to fill in attributes inside the opening tag.

But unlike HTML, **XAML is strongly tied to the .NET framework **and therefore is used with .NET languages like C#, VB.NET, and IronPython.
Obviously, it has different names for components and attributes than HTML, but you'll see this in a moment.
## Why Do We Use XAML in WPF?
The beauty of XAML lies in the ability to **separate the UI design of your forms from the code logic**.
This separation makes it much easier to manage and maintain your application, especially at scale.
Designers can work on the look and feel of the XAML forms, while developers can focus on the backend code and think about all the logic and everything they need for the form.
But in your case, you're going to be both the designer and developer💪.
## Behind-Code in WPF
Also, keep in mind that you can create your WPF forms by only using Python code **without any XAML**, and it's usually referred to as using **Behind-Code **when we create WPF forms with python code.
But it's going to be a mess as you would need to declare a lot of classes and fill in all the properties one by one. But sometimes it might be necessary, and we will dive into that during the course.
But in general, we'll use **XAML **for our main **front-end **and **python **to populate data and interaction for the form in the **back-end**.
## Learn More in Full Lesson
There is no way I can describe everything about XAML in this email, so I highly recommend you to [**Click Here**](https://learnrevitapi.com/free-lessons/wpf/1-04-xaml-intro) to Watch the Full lesson.
It's best if you follow along the video and try to code it yourself. That's how you learn XAML x10 times faster
### ✨WPF Course for pyRevit - Lesson 03
https://learnrevitapi.com/newsletter/wpf-course-for-pyrevit-lesson-3-visual-studio-basics-for-beginners/
Welcome to the 3rd Lesson of **WPF course for pyRevit**
By now, you should have your Visual Studio installed, and you were able to create **WPF project (for .NET Framework)**
Now, let me take you on a short tour around **Visual Studio **to show you a few essential things.
I will show you the most important things, so you know where to focus your attention before we dive into XAML and start coding.
Let's continue where we stopped in the previous lesson.
[**👉 Watch Full Lesson here**](https://learnrevitapi.com/free-lessons/wpf/1-03-visual-studio-tour)

## Visual Studio
As I've mentioned in [the previous lesson](https://youtu.be/NxgBInJSixg), Visual Studio is an IDE for large scale application development. It includes a lot of very advanced features.
But we don't need most of it. We only need the most important features for WPF so we can write XAML code efficiently and have a live preview of our forms.
So, let's go through the most important features and where to find them, so you feel more comfortable with the IDE before we start coding.
## WPF Designer (Preview Feature)
Once you start a WPF Project and open XAML file, you will see the main working area.
This is a place for writing a XAML code and see live preview of your form. This is the most important feature, because you need to see how your XAML code will look like to your users.
💡 We could also open C# and other files, but we won't need that. We are here just for the XAML code.

When you start a new project, XAML file always includes a placeholder template with a **``** tag, which represents the WPF class of your form.
Let's add a new **`