Skip to content

Instantly share code, notes, and snippets.

@giobel
Last active October 9, 2025 03:16
Show Gist options
  • Select an option

  • Save giobel/b8a7e5929c0c1e03a66080d5a0d93801 to your computer and use it in GitHub Desktop.

Select an option

Save giobel/b8a7e5929c0c1e03a66080d5a0d93801 to your computer and use it in GitHub Desktop.
*Rebars*
MACRO FOR REBARS WORKFLOWS
import pyautogui
import time
import tkinter as tk
from tkinter import messagebox
from pynput import mouse
from pynput import keyboard
import math
clicked_points = [] #start, step, end
delay = 3
def on_click(x, y, button, pressed):
if pressed:
#print(f"You clicked at ({x}, {y}) with {button}")
clicked_points.append((x,y))
# Stop after collecting 5 points (change as needed)
if len(clicked_points) >= 3:
#print("Captured 3 points:")
for point in clicked_points:
print(point)
return False # Stop listening
def on_press(key):
try:
global delay
#print(f"Key pressed: {key.char}")
delay = int(key.char)
return False
except AttributeError:
print(f"Special key pressed: {key}")
root = tk.Tk()
root.withdraw() # Hide the main window
root.attributes("-topmost", True) # Make sure it's on top
tk.messagebox.showinfo("ScreenGrabber", f"Please click start,offset and end point")
with mouse.Listener(on_click=on_click) as listener:
listener.join()
screenWidth, screenHeight = pyautogui.size() # Get the size of the primary monitor.
print (screenWidth, screenHeight)
#time.sleep(3) # Wait for the window to appear
currentMouseX, currentMouseY = pyautogui.position()
print (currentMouseX, currentMouseY)
start = clicked_points[0]
end = clicked_points[2]
step = clicked_points[1][1]-clicked_points[0][1]
count = math.ceil((end[1] - start[1])/step) + 1
print (f"length {end[1] - start[1]}")
print (f"step {step}")
print (f"count {count}")
tk.messagebox.showinfo("ScreenGrabber", f"Click OK and type the delay in seconds. Default is 3 seconds")
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
time.sleep(1)
for i in range(0,count):
pyautogui.moveTo(start[0], start[1] + i * step)
pyautogui.click()
time.sleep(delay) # Wait for the window to appear
timestamp = time.time()
local_time = time.localtime(timestamp)
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
formatted_time = formatted_time.replace(':','_')
screenshot = pyautogui.screenshot()
screenshot.save(formatted_time + "_FBA.png")
tk.messagebox.showinfo("ScreenGrabber", f"Done")
public void CombineGroups(){
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
//ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
ICollection<Element> selectedIds = new FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType().ToElements();
var grouped = selectedIds.GroupBy(x => x.Name);
//TaskDialog.Show("R", selectedIds.Count().ToString());
//TaskDialog.Show("R", source.Name);
GroupType gt = doc.GetElement(selectedIds.First().Id) as GroupType;
string changed = "";
using (Transaction t = new Transaction(doc,"Combine groups")){
t.Start();
foreach (var group in grouped) {
if (group.Count()>1){
Element source = doc.GetElement(group.First().Id);
int counter = 0;
foreach (var element in group) {
element.ChangeTypeId(source.GetTypeId());
counter ++;
}
changed += source.Name + " combined "+ counter + " times \n";
}
}
t.Commit();
}
//GroupType gt = g.GroupType;
TaskDialog.Show("T", changed);
}
public void ExportGroupsSubElements(){
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
// GET MODEL GROUPS IN THE ACTIVE VIEW
ICollection<Element> groupsInView= new FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType().ToElements();
StringBuilder sb = new StringBuilder();
//MAY NEED TO BE UPDATED TO YOUR LOCAL FILE PATH
string outputFile = @"C:\Temp\RevitGroups.csv";
string headers = "GROUP NAME, GROUP ID, GROUP ELEMENT IDS";
//FILTER REBARS AND STRUCTURAL CONNECTIONS ONLY
List<BuiltInCategory> builtInCats = new List<BuiltInCategory>(){BuiltInCategory.OST_Rebar, BuiltInCategory.OST_StructConnections};
ElementMulticategoryFilter multiFilter = new ElementMulticategoryFilter(builtInCats);
foreach (var group in groupsInView) {
Group currentGroup = group as Group;
string eids = "";
foreach (var element in currentGroup.GetDependentElements(multiFilter)) {
string uniqueId = doc.GetElement(element).UniqueId;
eids += uniqueId + " ";
}
if (eids != "")
sb.AppendLine(group.Name + ',' + group.Id + ',' + eids);
}
File.WriteAllText(outputFile, headers + "\n");
File.AppendAllText(outputFile, sb.ToString());
//UNCOMMENT TO LAUNCH EXCEL
//System.Diagnostics.Process process = new System.Diagnostics.Process();
//process.StartInfo.FileName = outputFile;
//process.Start();
}
public void RegroupBars(){
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
//THIS FILE PATH SHOULD MATCH THE EXPORTED FILE FROM THE PREVIOUS MACRO
string inputFile = @"C:\Temp\RevitGroups.csv";
var counts = new Dictionary<string, int>();
string errors = "Groups throwing errors: \n";
using (Transaction t = new Transaction(doc, "Regroup Bars"))
{
t.Start();
using (TextFieldParser parser = new TextFieldParser(inputFile))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
List<string> parameters = parser.ReadLine().Split(',').ToList();
while (!parser.EndOfData)
{
var line = parser.ReadLine();
var values = line.Split(',').ToList();
string groupName = values[0];
var eids = values[2].Split(' ');
//TaskDialog.Show("R", eids.Count().ToString());
List<ElementId> explodedIds = new List<ElementId>();
foreach (var element in eids) {
try{
explodedIds.Add(doc.GetElement(element).Id);
}
catch{}
}
//TaskDialog.Show("R", explodedIds.Count().ToString());
try{
Group regroup = doc.Create.NewGroup(explodedIds);
regroup.GroupType.Name = groupName;
}
catch{
errors += groupName+"\n";
//throw new SystemException("Error "+ groupName);
}
//TaskDialog.Show("R", groupName);
}
}
t.Commit();
TaskDialog.Show("R", errors);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment