- added searchbox with basic fuzzysearching still needs to handle backspace (right now it clears the list blank and requires rerun)
- added autoresize width to longest name
- set it to open in the screen center
- got basic functionality working for detail itesm - it finds relevant views and opens them I need to set it so that it opens sheets first if a view is placed it was correctly suggested that detail items are easier because they are view dependent - searching is fairly fast. It may not be the same for 3d objects
- moved each class to a separate .cs file
each class (and so each file) corresponds to a command (invoked from a hotkey or from a list in Add-Ins > External Tools) that seems to follow common conventions a single file became unmanagable in the end it all compiles to a single .dll (as long as they are in the same namespace)
- started CutWithModelGroupCommand command
doesn’t work so far - nothing happens
- pressing down arrow in searchbox immediately selects first entry in listbox, like in Everything from voidtools)
- pressing enter in searchbox immediately activates the first entry
- TODO FilterListBoxItems function incorrectly handles something and the list isn’t refrshing after pressing backspace
- TODO FilterListBoxItems make it fuzzy search space separated (like Everything from voidtools)
- stuck trying to cut toposolid with every element of a group
can’t figure out how to obtain solids from elements/elementgeometries
- got it working after a long struggle with misconceived BooleanOperationsUtils.ExecuteBooleanOperation function
it turned out that I should have used SolidSolidCutUtils.AddCutBetweenSolids it’s running as fast as trying to cut a single element - operations are batched in a single transaction https://forums.autodesk.com/t5/revit-api-forum/get-solid-from-familyinstance-keeps-returning-null/m-p/12692634/highlight/true#M78060
- got camera to move to an arbitrary project coordinate on the plan now need to obtain current coordinate of the view and move other plan views to it
- got it working (prompted ChatGPT in the right direction) views which are in different aspect ratio (tiles) appear to scale by height (but it may as well be good enough) interestingly enough it doesn’t just work across views of the same type - it can synchronize plans, sections, elevations and 3d views it doesn’t yet though read 3d view position correctly https://forums.autodesk.com/t5/revit-architecture-forum/syncing-camera-positioning/td-p/9315785
- worked for hardcoded value, so tried and failed to add the listbox/searchbox again, but it quickly got too convoluted
- started refactoring it so to create a single function that takes list of strings and resturns a reduced list of strings
- not sure yet how to handle callbacks to functions when key is pressed - maybe if they are empty return string, but if a value is passed call it likely this will change
- continued refactoring listbox/searchbox
- added mutliselect
- realized that Winform listbox offers a multicolumn mode and that it operates on the actual items (objects) and not strings, which should map better to OO nature or Revit
- this should allow me to replicate voidtools everything style of selection
- couldn’t list categories of all objects in the current document it would require iterating through all the objects which can take too long
- changed ListBoxSearchBox type to generics, so it returns list of any objects I imagine the next step to be taking list of parameters as an argument to read into a multicolumn listbox it should be really useful for SwitchWindow, which could benefit from sheet number
- need to fix searchbox as it doesn’t work after this change
- chatgpt correction, datagrid is the correct way to create tables in winforms (not multicolumn listbox)
- converted ListBoxSearchBox from listbox to datagrid
- added previous functionality (key handling, multiselection and automatic resizing)
- searchbox fix you can press backspace and retry queries without having to restart
- set datagrid to read-only
- can’t figure out why it doesn’t return selected objects
- figured out that I’ve incorrectly prompted chatgpt for checking passed objects for their properties
- it’s unncessary as datagriview reads (and binds rows) properties automatically when objects are bound as datasource
- got autoresize to work again
- needed to wrap it into event form.Load to run code only when the form is ready
- not sure why it wasn’t needed before
- needed to wrap it into event form.Load to run code only when the form is ready
- get serachbox to work
- took quite a few retries and in the end I again ended up picking chatgpt’s solution
- had to be only slightly modfied not to pick the list that it meant to be returned
- resorted to performing searches based on the list of properties supplied to the function
- as this list was meant to be used anyway for selecting columns it may as well be used for searching
- I couldn’t get it to work so that it would always just search through all available columns
- it may possibly cause issues later on
- I couldn’t get it to work so that it would always just search through all available columns
- as this list was meant to be used anyway for selecting columns it may as well be used for searching
- took quite a few retries and in the end I again ended up picking chatgpt’s solution
- didn’t get column selection to work yet
- done, requires GUI prompt
- after multiple attempts managed to prompt chatgpt correctly to specify which columns to display
- found confirmation that it should be possible in documentation (https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/datagrid?view=netframeworkdesktop-4.8)
- toggling AutoGenerateColumns to false hides any other columns
- minor fixed to keyhandling
- down arrow on searchbox goes directly to the second row (enter already selects the first row)
- using chatGPT created this function in only about 20 minutes
- it got the actual function wrong, but it was easy to find it online
- got confused when it didn’t work at first, but I’ve realized that 2D/3D extents in Revit operate independently on both ends of the levels in view and I just needed to add the second end to the for loop
- added OR | operator to searchbox same as in voidtools everything to search on multiple terms
- it took a single chatgpt prompt, very satisfying from productivity standpoint
- got confused by FilteredElementCollector selecting all elements (default behavior if invoked without other qualifiers)
- got it to work
- took half an hour to find a way to select multiple categories, because I couldn’t find a way to do it directly in FilteredElementCollector
so I’ve resorted to creating a list of elementIds and adding them category by category it still doesn’t seem to make a difference in terms of speed
- as an added bonus I’ve realized that the usual way of selecting categories (dragging a selection window over the area and filtering elements out) doesn’t work with elements inside groups, while my method includes them
- maybe it will be desirable in the future to disable selection inside model groups for performance purposes
- however worksets seem like a better or more correct way to manage performance of large models
- I don’t believe that it’ll be ever used, but it’s meant to be a joke claiming that the most basic feature (ctrl+a to select everything) has finally been added
- realized that external command can’t run while editing groups - a serious limitation
- refactored to use the new DataGrid instead of the old listbox
- turned out that there is no “category” property of built into view objects to use as a column, but “title” property can be used to achieve the same effect
- title is always prepended with view type (e.g. Sheet: or Drafting View:) and also follows the same convention as everything (type:)
- still need to implement space as an AND search
- briefly explored idea of reading .rvt files directly only to find out that it requires loading them in their entirety each time anyway
- realized that I’ve somehow completely missed the ViewType property
- using Title however also provides sheet number, so I’ve decided to use it instead
- this slightly defeats the purpose of datagrid (as opposed to a plain listbox)
- I’ve ended up adding ViewType columns after all
- FloorPlan view types weren’t included in the title
- added it to SwitchView and the new OpenViews as well
- using Title however also provides sheet number, so I’ve decided to use it instead
- added AND operator
- typing space will now search for multiple substrings
- managed to do it without breaking the previously added | OR operator
- fixed the bug when the form’s height was longer than the screen its top appeared in the center
- now it goes full height of the screen when it overflows the screen
- sort on the first column
- couldn’t get it to work
- ModificationOutsideTransactoionException
- doesn’t work for view-dependent elements (legends, detail groups)
- couldn’t get it to work neither
- ModificationOutsideTransactoionException
- got help to solve the transation exception issue - incorrectly put existing document into the transaction instead of the new one
- also moved creation/saving of the new document out of the transaction block
- https://forums.autodesk.com/t5/revit-api-forum/modificationoutsidetransactionexception-when-copying/m-p/12723267#M78335
- copying viewtemplate appears to pull a lot of other objects with it
- I found a way to suppress duplicate type warnings to speed up process of debuggin this issue https://forums.autodesk.com/t5/revit-api-forum/remove-warning-message-duplicate-types/m-p/8786636#M38700
- equivalent to the export
- took no time to write, only needed to shift .Close method for the source document as chatgpt closed it too soon
- started; aiming to create quick schedules out of currently selected elements
- hitting a problem with too many parameters, not sure which one should be displayed
- will need to also process some of them (only getting workset ids instead of workset names)
- after some deliberation I’ve realized that I will need to look into alternate ways of passing Datasource to dataGridView
- perhaps something that doesn’t require properties to exist on the objects
- gave height slight padding if it exceeds half the screen’s “working size”
- finally found a way to solve the issue of “unpacking” properties into additional columns
- needed to get ChatGPT 4 to suggest the correct approach
- instead of unpacking it in DataGrid function (via delegates) or trying to add custom properties to existing objects this code copies elements into “CustomElement” objects and passes them to DataGrid instead
- failed to create a quicker alternative, every time it ended up being two times slower than the regular pickbox window selection
- modified it to list only categories of elements visible in the current view
- after a few unsuccessful attempts of selecting objects I’ve realized how quick selecting all elements is via FilteredElementCollector itself, which made me revisit and successfully modify this function
- works fast even on large views (tested on a GA Plan)
- managed to add Parameters as columns
- they need to be passed as a dictionary in “proxy” objects “unpacked” dynamically in DataGridView
- managed at the same time not break other functions relying on DataGridView
- DataGridView is slowly turning into spaghetti code
- most of them turned out to be empty
- now need to only display non-empty ones
- it turns out that rows weren’t populating, so instead of using objects I will try to rewrite DataGrid to take some more flexible data structure like list or dictionary
- issues stem from the fact that C# is a statically typed language and won’t allow you to dynamically add properties
- managed to rewrite DataGrid method taking list of dictionaries instead of list of objects
- added new method with the same name, just with different signature (method overloading)
- it seems a bit faster
- a lot of functionality of datagrid wasn’t rewritten and so I couldn’t test if selection of elements still works
- another thing is the sheer size of parameter tables
- will require some more logic in searchbox to filter not only rows, but also columns
- try using $ (dollar sign) as a symbol designating column search instead of row search
- keep | symbol to delimit OR queries
- will require some more logic in searchbox to filter not only rows, but also columns
- rewrote keyhandling and confirmed that both functions now work correctly in effect letting user to filter down selection of objects
- brought back logic to resize the window
- needed to add width handling due to the amount of parameters
- adding better window positioning
- center of the screen with slight padding
- parameter to toggle span across multiple screens
- run into interesting issue when method overloading wasn’t letting me to add an optional paramater as it was picking another method
- I simply won’t make this parameter optional
- (ChatGPT4) refactored it into two functions, one to span winform across all available monitors and one to show it only on the current monitor
- it did it in an interesting way whereas one abstract class implements IExternalCommand and the two classes inherit from it and override an abstract boolean variable
- run into interesting issue when method overloading wasn’t letting me to add an optional paramater as it was picking another method
- realized that datagrid out of the box can be navigated horizontally with a subset of farily common keybindings
- for example ctrl plus right arrow key get you to the right most far cell
- I will still try to add shift plus arrow keys for immediate scroll as I think it would be more practical
- realized that datagrid out of the box can sort rows by clicking on column header names
- that might justify some extra complexity
- don’t select anything if Escape key was pressed
- updated DataGrid form kept returning entries even if escape was pressed
- I had to introduce an extra variable/flag to check if Escape wasn’t pressed and avoid extracting filtered entries at end
- updated DataGrid form kept returning entries even if escape was pressed
- realized that another version should be added to filter all elements visible in view, not just those currently selected
- renamed commands to “ListElements”
- ListSelectedElements
- ListSelectedElementsSpanAllScreens
- ListAllElementsInView
- split SelectCategories into two commands:
- SelectCategories
- SelectCategoriesInView
- now the first one scans all elements in the entire project, list available categories and selects them
- it may be useful when combined with ListSelectedElements to create quick schedules
- I still need to clean up ListSelectedElements to be faster and show more relevant information
- replaced OwnerViewId with OwnerViewName and GroupId with GroupName
- compute them before creating dictionary that gets passed to elementData List
- added autoreisizing of the columns’ width
- manual resizing of the width now is blocked
- hopefully it shouldn’t be an issue
- adjusted left and arrow keys handling in combination with shfit for speed control
- handling current cell selection became too complicated, but it may not matter if hopefully all horizontal motion keys (left/right arrow keys) are now overwritten
- fixed a bug introduced with the new left/right arrow key scrolling code using ColumnIndex instead of HorizontalScrollingOffset
- it could get stuck if keys were pressed too many times after reaching datagrid ends
- it should be smoother now as well as it scroll a constant amount instead of full column widths
- added command to select linked models with DataGridView
- under impression that there won’t be many more columns that will need to be added
- perhaps constituent materials
- perhaps location in XYZ?
- that would require some ranges in queries
- it might be useful for selecting objects across multiple floors in similar locations
- split them further, because loading all parameters was too slow for DataGrid
- ListSelectedElements
- ListSelectedElementsWithParameters
- ListSelectedElementsWithParametersSpanAllScreens
- ListAllElementsInView
- this time ChatGPT ended up only complicating it again, so I’ve resorted to a simple if statement
- chatGPT did help though with cleaning it up
- this time ChatGPT ended up only complicating it again, so I’ve resorted to a simple if statement
- still need to make these parameters combine all selected elements instead of just the first one
- showing the winform without parameters proved to display some resizing issues when the table width is smaller than the screen width
- solving them now
- accidentally run SelectAllElementtInView on the full model in 3D instead of ListElementsInView
- going to make supper while it loads
- turned out to not be this bad - done after about 5 minutes
- added automatic width resizing for the window
- couldn’t get it to work for height - window kept shifting towards the center of the screen
- changed background color instead
- confusingly enough needed to change background of the datagrid and not of the winform container itself
- changed background color instead
- managed to set sorting of the datagrid by default to be on the first column in descending order
- I tend to sort files in voidtools Everything by date modified as well as a default
- added ListAllElementsInViewWithParameters
- starting to notice a lot of lag
- look for a faster alternative
- checked if Everything voidtools GUI is available as a library, but sadly it’s not
- void recommended looking into “virtual listview”
- checked if Everything voidtools GUI is available as a library, but sadly it’s not
- look for a faster alternative
- starting to notice a lot of lag
- realized that I will need to create ListAllElementsByCategory anyway
- parameters are grouped by categories, so it’s in many cases unnecessary to add other parameters to columns
- I imagine this would fisrt pop the same selection window as for SelectCategories and then DataGrid for all elements (to select them)
- maybe it wouldn’t be necessary if GUI was faster and allowed you to dynamically filter by columns
- I imagine this would fisrt pop the same selection window as for SelectCategories and then DataGrid for all elements (to select them)
- parameters are grouped by categories, so it’s in many cases unnecessary to add other parameters to columns
- realized that more expressive query language is needed (e.g. Xpath, selenium, python requests)
- for example show a shared parameter (tenure) of a sibling (room) in a group for all model groups with name “bathroom”
- maybe it will be easier to write custom scripts to compute new parameters for objects
- or export revit to excel/sqlite, perform queries there and pull them back to display in revit
- added error handling in case no elements are selected
- inspired by Rhino ZS command
- took longer than expected, because the default uiDoc.ShowElements method was suspiciously slow
- prompted ChatGPT to write a custom one by calculating boundingbox and using the previous ZoomAndCenterRectangle (UIView)
- split and extended into new commands:
- SwitchViewByTitle
- same as before but now the current view is selected on start
- it should be more convenient to select related views
- same as before but now the current view is selected on start
- SwitchViewByHistory
- alternative that may be more useful, need to test it
- inspired partially by ctrl tab behavior in visual studio
- needs testing
- alternative that may be more useful, need to test it
- SwitchToLastView
- again tried to match behavior of ctrl tab in visual studio
- seems like native ctrl tab behavior of revit view switching when history order is turned on breaks it (GetOpenViews method may be returning them in wrong order)
- a workaround might be switching ctrl tab to tab order and relying solely on my implementation
- revit won’t let you assing ctrl tab to it however
- maybe there is some way to override it in c#?
- seems like native ctrl tab behavior of revit view switching when history order is turned on breaks it (GetOpenViews method may be returning them in wrong order)
- again tried to match behavior of ctrl tab in visual studio
- SwitchViewByTitle
- split DataGrid into two files
- used partial keyword to split class without renaming
- started
- added optional title parameter
- added double mouse click handling
- finished
- initial success after a few unsuccessful attempts that failed mostly due to inability to select room correctly
- turned out to be very fast
- instead of appending “- Copy” made it append “- Copy {timestamp}”
- conflicts caused the command to fail, there often were existing view with “- Copy” suffix already
- save currently opened UIViews to open them later (for example after reboot)
- don’t save them in revit model
- ravit offers extensible storage framework or shared parameters
- save them as a plain text file on the filesystem
- one view title per line
- assuming view titles are unique
- view titles include view type (e.g. area plan, sheet, schedule)
- considered %appdata%/local as its a standard location
- ended up prompting user to choose location as it allows you to save it on the server
- you can take snapshots
- you can share it with others
- you can open from other machines
- ended up prompting user to choose location as it allows you to save it on the server
- one view title per line
- one command to write and corresponding command to read (SaveOpenedViews and OpenSavedViews)
- added hotkeys (space in empty searchbox) to quickly switch to next/previous view
- spacebar to switch to the next view
- shift spacebar to switch to the previous view
- started custom command invoker to provide quick access to increasing number of revit commands
- also addin manager turned out to copy .dll each time to windows temp folder that never get deleted
- a better design will be to load dll into memory without going each time through file system
- hopefully it won’t break any of the scripts
- if it does it can be quickly confirmed by running the script via addin manager or load it directly
- hopefully it won’t break any of the scripts
- prompt user for a dll location, save this location in appdata text file and unless deleted keep reusing this location
- hopefully loading it each time on invocation won’t be too slow
- added key handling for enter when focus is on searchbox to select the first entry from the top
- same as it was for DataGrid1
- fix/hack to prevent width of the form to cut into datagrid when filtering datagrid (by typing in the searchbox)
- increased “requiredWidth” in form.Load calculations
- fixed bug when a view is activated on a sheet SwitchToLastView opens that view separately instead of its sheet
- on downside it now won’t be able to switch to separate views, but will always open the sheet on which they are placed
- if previous behavior is required SwitchViewByHistory can be used instead
- since yesterday’s hotkey addition (space in empty searchbox) it should be a relatively quick to combine them
- on my keybindings it would be (w r space) to invoke SwitchViewByTitle and choose the first entry (last view)
- since yesterday’s hotkey addition (space in empty searchbox) it should be a relatively quick to combine them
- if previous behavior is required SwitchViewByHistory can be used instead
- on downside it now won’t be able to switch to separate views, but will always open the sheet on which they are placed
- fixed bug where pressing space in searchbox didn’t filter datagrid as a list of AND statements
- remove rarely used | character handling (OR)
- added NOT statement to DataGrid2 for words that start with !exclamation mark in searchbox
- added NOT statement to DataGrid1 for words that start with !exclamation mark in searchbox
- added InvokeLastAddinCommand as a separate IExternalCommand
- this way it can be assigned a hotkey (qq`), which may be useful if a new command needs to be invoked frequently
- renamed filenames both commands use to save their data
- InvokeAddinCommand - %appdata%/revit-scripts/InvokeAddinCommand-last-dll-path
- InvokeLastAddinCommand - %appdata%/revit-scripts/InvokeAddinCommand-last-command
- changed SwitchToLastView behaviour so that when the last view to which you are switching is placed on a sheet AND that sheet is opened only then it opens the sheet instead of the view directly
InvokeLastAddinCommand was adding itself as the last invoked command, which led to an infinite loop added check to InvokeAddinCommand to prevent this command from ever being saved to %appdata%/revit-scripts
removed “scripts” namespace from all files it seemed unnecessary for a loosely coupled collection of revit commands
couldn’t find a way to detect whether a view is an active view on a sheet or a standalone view without knowing for sure the command would cause undesired behavior in various situations best effort workaround right now seems to be deactivating
can’t find a way to deactive view before switching to another view switching to sheet from an active view via uidoc.ActiveView = targetSheet doesn’t work (nothing happens) Postcommand doesn’t work (nothing happens) when run before switching view
this command is the lowest common working hack for the SwitchToLastView bug it opens the sheet of a currently active view and closes the standalone view, which is necessary for the uidoc.GetOpenUIViews to work it’s only use is meant to be when you forget to deactive view before switching and you need to quickly get back
due to bugs in uidoc.GetOpenUIViews added an IExternalApplication that logs all view changes to a file
added automatic cleanup on each view change heuristic if more than 200 lines truncate to 100
removed unopenable views (ViewTemplates, ProjectBrowser and SystemBrowser) from the list
changed SwitchToLastView to read from file created by LogViewChanges instead of using uidoc.GetOpenUIViews
moved SwitchViewByTitle SwitchViewByHistory and SwitchToLastView to separate .cs files as they weren’t sharing enough anymore
changed SwitchViewByHistory to read from file created by LogViewChanges instead of using uidoc.GetOpenUIViews
first I considered making LogViewChanges CleanUp function only trigger OnStartup to preserve all changes in the current session this limits usage of LogViewChanges file, but it shouldn’t be a problem to create a separate one if any specific use case come up made SwitchViewByTitle read this is a hack - it assumes that users will rarely close sheets if a user closes a sheet and expects the command to not move a user back to that sheet, it will anyway best workaround would be for the user to deactivate views each time
then I looked into DocumentChanged event, but this only provide added, modified and deleted events to elements closing views doesn’t trigger any of these events
then I thought about discerning if a sheet was closed by comparing number of opened views (previous sessions sheets cleaned up on startup) and check which is missing however user might have accidentally opened a sheet and now user would be forced to open sheet anyway
then I though about giving up and always opening sheets if it won’t be solved upstream and I can’t find a viable workaround this is it, it’s not a terrible tradeoff it’s better than accidentally opening separate views it seemed that this work went in vain, but using ViewActivated event instead of pulling information out of GetOpenUIViews makes the script synchronized with switching views via ctrl tab (and other revit UI navigations)
finally I decided to mandate usage of custom functions to close views CloseCurrentView and CloseViews LogViewChanges was modified to remove all entries from %appdata%/revit-scripts/LogViewChanges OnStartup LogViewChanges was modified to remove duplicate entries after inserting a new entry at the end if this fails the only repercussion really is that sheet will be opened instead of a view if accidentally a view gets removed in another way, they can be manually removed in %appdata%/revit-scripts/LogViewChanges if you don’t know what views changed you can make a diff by exporting all current views with SaveOpenedViews command this may miss some sheets, but may be good enough
added OrderBy LINQ method to sort both methods alphabetically
modified these functions so they add, edit and remove entries from an external file instead of using uidoc.GetOpenUIViews (due to above mentioned bug with views activated on sheets) drawback is if user closes views it won’t be captured in this system, so some inconsistencies may come up I’m hoping that closing views won’t be a frequent operations switching views and opening views will be reflected in both revit and this LogViewChanges
added initialindex to OpenViews copied verbatim from SwitchViewByTitle
performance is noticeably slower than before couldn’t find any performance improvements in the current approach (read file and query FilteredElementCollector) possibly storing ID as well as title in instead of title could make use of doc.GetElement method that was used previously and seemed faster cache could solve it - cache mechanism in revit process memory to reflect contents of LogViewChanges file
improved performance of SwitchToLastView by storing ID together with title in LogViewChanges and reading it with GetElement to get the correct View element instead of using FilteredElementCollector this required however changes to LogViewChanges SwitchViewByTitle CloseViews CloseCurrentView SwitchViewByHistory commands to parse correctly the new format
when view changes between projects or between families script didn’t work as it tried to read a view id from another family/project hacky solution is to iterate through all IDs in the most recent order until one works intention is for SwitchToLastView to always switch to the last view withing the same project ctrl tab builtin in revit can be then used to switch between views between projects/families
previously file got cleared when another revit session was started LogViewChanges was changed to create a separate file with project name instead, so multiple projects can use separate files this should also fix the previous issue where SwitchToLastView was confused about views from other documents (families/projects) LogViewChanges SwitchViewByTitle SwitchViewByHistory SwitchToLastView CloseCurrentView and CloseViews changed
instead of having to use SaveOpenedViews and OpenSavedViews new command was added OpenLastSessionViews that uses LogViewChanges file (for the corresponding project) I’ve kept forgetting about running SaveOpenedViews at the end of the day clearing file contents of the previous session in LogViewChanges was moved from OnStartup method to OnDocumentOpened, due to availability of the document title variable previous sessions from revit can be used to restore views, because it gets copied to a .bak file OnDocumentOpened event LogViewChanges files for families get deleted when documents is closing there would be too many of them and they usually don’t contain many views
added TraceAllLines to avoid exploding DWG file and cluttering the project with linestyles,patterns etc.
at first it seemed fast, but adding subsequent curves to the document became increasingly slower first curve only 3ms, but 1500th curve already at 200ms tried using directshape, but they are not allowed in a family unable to find a solution to the performance bottleneck will try exploding CAD and cleaning up instead turns out no scripting is needed, cleaning up can be done manually by selecting corresponding element and changing types then copying to a fresh family that will import only the copied types
added a simple script that just invokes NewFamily command I couldn’t find a way to automatically open and activate a family template this is best I could get
confirmed that OpenAndActivateDocument doesn’t work with family templates source
couldn’t switch to the next view after pressing space on the first try it worked on the second try possible discrepancy in the LogViewChange file?
ListAllFamilyTypesSpanAllScreens, ListAllFamilyTypesInView and ListSelectedFamilyTypes added to match corresponding methods that list instances as a lucky side effect this method actually selects family type element that can be then used to select all instances in view/project these methods came out of necessity to quickly list changes to types of detail items (drywalls)
the process had to be repeated enough times to warrant automating it export path is saved to %appdata%/revit-script/ExportSchedule - {schedule name}
renamed from ExportScheduleCommand entries like <Keynote Schedul N> and Keynote Legend N are filtered out these are presumably created by Revit from keynote schedule generated on the sheets
added sorting on the first column when user filters the list by typing in searchbox previously entries were going out of order for some reason
couldn’t find where children detail views were located, because they were usually hidden in the parent view this function was meant to draw their rectangles and select them, but it only crops current view I kept running in issues in view cropregion points not being coplanar limited usability
managed to draw and select lines around crop region by drawing everything that doesn’t throw an exception between the crop region points previous issues must have been cause by incorrect projections of the crop region box it’s a messy solution but for this purpose it works fine
made it work for multiple views in one command made it select the created after command finishes this allows to easily delete them afterwards or to zoom in to that view (ZoomToSelected command)
corrected the code to draw proper rectangle around the crop region instead of haphazardly connecting points got advice on the forum to use ViewCropRegionShapeManager to get the right crop region orientation
more convenient than going through the list prompted by revit in its cube gizmo, especially on larger projects doesn’t quite work yet - orientation of the resulted section box seems to be rotate on X axis
further attempts to fix incorrect rotation of the sectionbox didn’t solve anything asked for help on the forum
finally a command that works on the first try! it started getting really frustrating it’s not that important though, just resizes section box (3d only) by a custom amount
in response to inability to find exactly which sheets had a global revision assigned couldn’t schedule neither sheets nor titleblocks in revit out of the box unusually revit silently crashed not too long after this command run fortunately I synced just before that presumably it was cause by attaching debugger to revit
simplifies usage of SectionBox3DFromViewList (renamed) as usually you want to inspect a view that is currently already selected or active slight uncertainty about choosing the right view - there is no Revit API command, so had to find it by obtaining username and appending it to {3D - username} format if view doesn’t exist the script aborts, which might break it in the future if Revit team decides on a different convention
I’ve tried adding optional parameter to CustomGUIs.DataGrid2 to set initially selection, but none of the two approaches worked firstly trying DataGrid1 didn’t display entries secondly DataGrid2 didn’t display correct revisions gave up and reverted to the original working state - list works, but doesn’t display initially selected revisions on the current sheet
a simplified method of tagging selected objects takes into account scale of the active view similar to the builtin tag placing command it uses the last used tag type
they may streamline tag placement in larger number of views where elements have consistent shape uses code from TagSelectedElements command
usability improvements testing added category and family columns for clarity all three columns are needed
12:06
ListSheetsByDetailItemSelected command added and FamilyReferences command renamed to ListViewsByDetailItemSelected
many views listed by ListViewsByDetailItemSelected (previous FamilyReferences) weren’t useful as they weren’t officially issued it became more common to navigate the project by sheet names/numbers rather than view names view names often were secondary and unkept (copied from other views without renaming as only their “title on view” parameter was being changed)
renamed from revit-scripts to revit-motions contents of a separate “scripts” folder dumped into top level directory top folder and .csproj .csproj.user and .sln files renamed accordingly paths in .sln changed accordingly tested recompiling and run InvokeAddinCommand - both passed backup with previous setup created
change from ListBox to CustomGUI.DataGrid1 DataGrid2 didn’t have initial selection parameter yet initial selection set to be sheet on which currently active view is placed this should help when going sheet-by-sheet making changes to all detail items recorded demo
took a number of tries due to minor issues with chatgpt returns list of sheets that couldn’t be updated at the end if views with multiple scales were placed on a sheet
works only with Finish Face Interior and Finish Face Exterior a more general solution would be useful there wasn’t a builtin shortcut and clicking buttons was too cumbersome mentioned on the forum
unsolved issues place revision cloud exactly over viewport elements just didn’t work, no matter what I did, placing them always somewhere else merge curves together into combined loops (Boolean union) some issues could have been solved drawing revision cloud outside of the current view, in the sheet on which active view was placed one rectangle around all selected elements instead of multiple rectangles around individual elements reordering points of the rectangle so the revision cloud “points outwards” instead of “inwards”
simply pastes selected element to selected Views should be equivalent of “Paste to Current View” in Revit UI
realized that all revisions are “global” they can “per project” or “per sheet”, but all are first available globally perhaps another command “ListSheetsByRevisionOnCurrentSheet” or “ListSheetsByRevisionOnSheets”
18:20
added five commands to List and Set revisions on sheets grouped by global revisions and filtered by whether they are set by cloud or by sheet
tailored for our specific workflow with per-sheet revisions it’s quite common to accidentally assign revisions by cloud by cloud means first drawing a cloud around an area and then assigning it a revision this seemingly sets revision on the sheet, but it disappears when clouds get deleted it has been argued that we shouldn’t be deleting clouds on the other hand someone might unknowingly delete a revision cloud and break the log in this case this method is more robust to avoid this we always set revisions by sheet (button in properties panel) and then repeat the above steps it can be cumbersome however to return the clouds back to be by sheet if they were already assigned by cloud scripts below help you manage that by “forcing” revision into sheet, as well as listing sheets with given revisions where they were assigned by cloud SetRevisionsToSheets, SetRevisionsToSheetsWhereRevisionIsByCloud, SetRevisionsToSheetsWhereRevisionIsByCloudOrBySheet ListSheetsByRevisionsWhereRevisionIsByCloud set commands work like this: select revisions, select sheets and set these revisions to these sheets WhereRevisionIsByCloud list commands work the same, but open sheets instead of setting (“forcing”) revisions ListSheetsByRevisions already existed, but I’ve made it work for multiple selected revisions
used it in the above commands manipulating revisions to select the last entry by default on start due to amount of revisions the list always took a long time to navigate the most recent and so usually most relevant revisions always appeared at the bottom listing them in reverse order would be counterintuitive, because that’s also how they appear in revit ui it was already present and implemented in DataGrid1
previously Enter key press in searchbox caused only the first entry to be selected instead of the current datagrid selection not sure if this breaks any workflow, if it does perhaps a better way would be to handle it this way only if searchbox is empty
finished IncrementSheetNumbers scaringly enough first iteration for some reason broke undo button second iteration worked though it prompts one dialog for sheet selection and second dialog for increment integer can be negative
uses currently selected views on sheet and places them on another sheet in the same locations
only works in family editor sets value of a selected parameter to selected family types in response to an autodesk forum discussion generated with chatgpt model o1-preview tried also o4 model, but didn’t finish it and wanted to try new one instead after first few tries were unsuccessful
empty row was appearing in the datagrid list, which sometimes caused errors in some commands turned out that this was an option in WinForms that needed to be disabled this was on so user could enter new rows which made me wonder if I didn’t choose wrong GUI framework, as these datagrid are only used to reading/selecting perhaps I will use them to change data later on as well then chatgpt at the end of the previous conversation suggested this change (source)
variation on SetRevisionsToSheets series of commands made of convenience
couldn’t find a way to list sheets on which a legend was placed chatgpt
autodesk forum discussion initial selection was incorrectly assuming view - it was in fact viewport (legend placed on a sheet)
generalization of previoius prototype copying all element of a certain type from a selected linked model
ordinary ListTypes was too slow and I couldn’t find a way to cancel the operation risking crashing the model instead qualified it to specify a category first, however this still proved to be slow in our model
instead of using predetermined values it prompts for an arbitrary floating value, which is then used to resize (expand/shrink) section view (only in 3d view)
lists all sheets with all of their parameters useful for debugging sheet revisions, titles, scales etc.
added “current revision issued to” column this is incorrect, because other projects likely don’t use that parameter I’ve kept both this and probably more correct “Current Revision” should be useful to avoid adding revision with a wrong number
22:45
updated ListSheets to only 5 and move version with all parameters to a separate ListSheetsWithAllParameters command
listing all parameters is often too slow and in these 5 parameters can be sufficient for many use cases (hopefully)
first command that deletes object in Revit, a bit dangerous, but I double checked the code made it also delete revision clouds in views if views were placed on these sheets and had revision clouds in them it’s slower than I expected, cleaning all flat plans (circa 50 sheets) took about a minute perhaps that’s due to extra check to look for revision clouds in the views
equivalent of ListFamilyTypesInCurrentProject, but shows and selects only elements visible in current view
now revision clouds are being placed in the correct place (or close enough) clouds are being placed on sheets but based on location of selected elements in the view and view’s postition on the sheet couldn’t get the cloud to use the most recent revision on a sheet stil isn’t able to properly combine curveloops tightly around selected objects, but if elements are separate it seems to work well we’ll see about that as we use it…
SelectCategoriesInView now preserves selection of previous elements previously it deselected them and made a new selection
renamed with Select- prefix and made it so that previous selection is preserved
took me over the limit of chatgpt o1-preview, but got it to display total length column correctly got to the rest of minor amendments to the code via older 4o model haven’t reviewed the code, only checked if results are correct based on only about a dozen examples adding extra check for sheet name (in additino to owner view name) seemed to have added extra latency, but I’d rather not split it into two commands for a seemingly minor speed improvement once datagrid of dimensions is generated it can be copy pasted into files and compared for any before-after differences for example when changing family types dimensions may silently snap to another position errors when dimensinos change only pop up when they get deleted
updated handling of || and ! operators in filtering textbox widget
SelectFamilyTypesInCurrentView and SelectFamilyTypesInProject were renamed to SelectFamilyTypeInstancesInCurrentView SelectFamilyTypeInstancesInProject
11:51
fixed SwitchViewByTitle to show sheet as an initial selection when an view on a sheet is active
for some reason pressing Enter in SeachBox didn’t work
proof-of-concept almost works, it only fails when view has been modified by transforming it by its crop region I sometimes use this as well to quickly shift a view it is being used to rotate a view as well presumably this affects transformation of the view in a way which viewport.GetProjectionToSheetTransform method doesn’t account for I’m looking for hints about these transformation in view element itself rather than on viewport possibly it might get stored in view crop boundary as well
14:43
script to print transformation of a view didn’t show any difference before and after moving a view by its crop region, but script to print transformation of crop region did
15:00
paused further attempts for now as I couldn’t prompt chatgpt to account for cropbox transformation
it kept cluttering revit-scripts folder placing it into a separate folder and preventing it from logging if document if a family don’t see a need for it in something as simple as a family looks like they were meant to be deleted OnDocumentClosing, but it didn’t work then again why create them in the first place if they are going to be deleted took me in total only about 20-30 minutes to finish implementing it feared it might have taken longer, because debugging of any potential issues would require restarting revit
path change, folder added
- SwitchView, SwitchViewByHistory, SwitchToLastView
- CloseCurrentView, CloseViews
- OpenLastSessionViews
log files for families are correctly not being created
all commands continue working as intented
I’ve realized that “LogViewChanges -” prefix is now redundant as folder is used instead
need to change that everywhere now again
20:05
finished updating and testing, all works fine
spacebar search AND operator stoppoed working - requries prompt fixing customgui.datagrid1 works fine
likely will move detailed changes to git log from now on
need to revisit it later
22:38
tried adding SwithProject (or SwitchDocument) command, but it looks like it doesn’t work for documents loaded from Autodesk Cloud (bim360)
I don’t expect this to be solved any time soon chatgpt likely will end up holding revit models in two separate revit processes and find another way to share data between them other than clipboard
couldn’t find any way to access it via revit api
it would be useful, because its position resets each time it’s copied and has to be manually repositioned
there may be many hundreas of callouts on a project
23:22
confirmed that it’s unavailable in revit 2024 api now
https://forums.autodesk.com/t5/revit-ideas/allow-setting-of-callout-head-location-in-api/idi-p/10665304
forgot that “SelectModelGroups” already existed and behaves largely the same with exception that the new command also displays all parameters
https://chatgpt.com/share/67608357-c920-800c-b889-d62f09f1d50a suggested only placing IndependentTags, but these don’t pick up needed parameters https://forums.autodesk.com/t5/revit-ideas/revit-api-material-keynotes/idi-p/13214525
they should prove universally useful for a number of tasks I was hoping to use them specifically to set parameters to material elements to avoid waiting for them to reload individually, but each parameter would have a different value and this command can only set the same value to multiple family types or family instances at the moment
future improvement idea potentially would be to make entries in table individually editable to be able to input multiple different values in a single transaction
or I might just use ideate this pretty much replicates ideate functionality
11:52
improved “SetParametersOfFamilyTypes” command by letting previous windows make multiple selections and these selections to them be combined in subsequent lists
for example some parameters are shared by family types in multiple categories, e.g. we’ve had material for louvres in both doors and window family types
using InsideClipboard from NirSoft I confirmed that Revit doesn’t use system clipboard at all need to find a way to replicate this behavior cross-process
- export/import elements associated family types, line styles etc.
- place them at specific positions
I will start with view-dependent elements first
[2024-12-19 Thu 01:35] was able to automate export and import of families of selected elements between sessions, but basic placement wasn’t right, elements kept showing up in wrong positions and wrong orientations
https://chatgpt.com/c/67642cda-3ef0-800c-b89e-aa1d7283bc31
22:51
realized that there are builtin commands in revit already to save as “library” group or view and corresponding command to load/insert them
they may have some limitations that I haven’t discovered yet, like placing them in the same location as in the original file in these situations my Copy/PasteCrossSession commands may still prove useful while they are not perfect, they correctly place most of detail items in same locations they are fairly convenient, invoking any one of them automatically select currently selected group or currently active window it may still worth though to write separarate commands to perform bulk exports to avoid having to open entire project in the future when certain detail items are needed
01:41
tried adding “ExportSelectedViews” command to automate export process of revit sheets to separate files, but it was confirmed that it isn’t available in API
only possible via PostableCommand https://forums.autodesk.com/t5/revit-api-forum/api-version-of-quot-save-as-gt-library-quot/m-p/12452936/highlight/true#M75998
needed to update sheets numbered with a hyphen in third place, e.g. 35-501, 35-502 hopefully it won’t get more complex than that, wish we just all followed the iso standard chatgpt
22:53
tried writing DeleteSelectedSelections command, but it looks like “saved selections” aren’t available to revit api
the problem is that default EditSelection command in Revit won’t let you delete multiple saved selections in one go making deletions of multiple saved selections a cumbersome process may have to store Element Ids/GUIDs in a separate file instead to avoid this overhead in the future and manage it with custom commands
19:22
tried increasing performance of DataGrid2 by various means, but nothing seemed to make any major difference
virtual list control among other things hopefully no new bugs were introduced in the process
tried making it dark themed as well, but sadly couldn’t get scrollbars to change colors, so reverted back to light
17:59
found it with revitlookup addin - GetViewRange - PlanViewRange : GetOffset (bottom clip plane, underlay bottom, cut plane, top clip plane) and GetLevelId (level - bottom clip plane, cut plane, top clip plane)
chatgpt explained that likely culprit for incorrect bounding box calculations was using get_BoundingBox(null) instead of get_BoundingBox(activeview) the latter was needed to account for bounding box relative to active view https://chatgpt.com/share/67afdaf3-9d4c-800c-81bc-327cdd7382b1
waiting for o3 model to reset, hopefully it will find a solution, all other LLMs failed, couldn’t find a location parameter via revitlookup addin
having bad luck with sections in revit in general
13:40
couldn’t write a command that would automate creating a detail item family out of current elements
simialar in user experience as grouping
21:51
tried adding FacingFlip and HandFlip properties to RenameInstanceParametersOfSelectedElements command, but turned out that some elements can’t be flipped directly at all (CanFlipFacing and CanFlipHand methods to check)
may try later a separate command to perform mirror operation on them instead