Friday, May 19, 2017

Autodesk University 2017 Class Proposals

This year Autodesk University is allowing people to vote on the classes that they would like to see offered at the upcoming AU2017 in November. I have submitted two (2) classes for people to vote on. If you would like to see these classes, please take a couple minutes and vote for them...

Website: http://au.autodesk.com/speaker-resource-center/call-for-proposals/voting

To find my classes use the following (or search by name):















Friday, April 21, 2017

Revit Lookup 2018

Continuing with the tradition of compiling the awesome opensource Revit addin "Revit Lookup", I have taken the Revit 2018 version and compiled it for those that do not know or want to try compiling the source code for themselves.

Download Revit Lookup 2018 here.

I have added a link on the right side of the blog and will keep it updated whenever there is a new build available.


Revit Lookup (https://github.com/jeremytammik/RevitLookup)
Interactive Revit BIM database exploration tool to view and navigate element properties and relationships.

Please refer to The Building Coder for more information.



Thursday, April 13, 2017

Revit 2018 Export Warnings from Model to Excel

Revit 2018 has added a great new addition to the API that allows you to collect all of the Warnings that exist in the model. Previously, you could only export this list by using the builtin "Export" button in the Warnings dialog, that exported to a HTML file.

The new addition is the following:

IList<FailureMessage> warnings = doc.GetWarnings();

The following macro will export all the warnings in your model to Excel:

public void ExportWarningsToExcel()
{
 // make sure to add a reference to Excel Object Library
 // put the following (minus the // into your using statements)
 // using xls = Microsoft.Office.Interop.Excel;
 // using System.Reflection;
 
 // create a new Excel connection
 xls.Application xlApp = new xls.Application();   
 
 // make sure you have access to Excel
 if (null == xlApp)
 {
  TaskDialog.Show("Error", "Failed to start or access Excel");
  
  return;
 }
 
 // get the current model
 Document doc = this.ActiveUIDocument.Document;
 
 // get a list of all the model's warnings
 IList<FailureMessage> warnings = doc.GetWarnings();
 
 try
 {
  // show the Excel window
  xlApp.Visible = true;
  
  // create a new Workbook in Excel
  xls.Workbook workbook = xlApp.Workbooks.Add(Missing.Value);
  
  // create a new Worksheet in Excel
  xls.Worksheet worksheet = (xls.Worksheet)workbook.Worksheets.Item[1];
  
  // name the Worksheet with the model name
  worksheet.Name = doc.Title;
      
  // create a header row
  worksheet.Cells[1,1] = "Warning Description";
  worksheet.Cells[1,2] = "Elements";
  
  // count the number of warnings
  int numWarnings = 0;
  // start on row 2 for warnings
  int row = 2;
  
  // loop through each warning
  foreach (FailureMessage fmsg in warnings)
  {
   // add the warning desciption to cell in Excel
   worksheet.Cells[row, 1] = fmsg.GetDescriptionText();
   
   // create a string to hold element info
   string elements = "";
        
   // loop through the element ids
   foreach (ElementId eid in fmsg.GetFailingElements())
   {
    // get the element
    Element e = doc.GetElement(eid);
    
    // add the element category
    elements += e.Category.Name + " : ";

    // some elements fail when getting their family type, so skip getting type if it fails
    try
    {
     // get the element family type
     elements += e.LookupParameter("Family").AsValueString() + " : ";
    }
    catch
    {
     
    }
          
    // add the element name
    elements += e.Name + " : ";
    
    // add the element id
    elements += "id " + eid.ToString() + System.Environment.NewLine + System.Environment.NewLine;
   }
   
   // add elements to cell in Excel
   worksheet.Cells[row, 2] = elements;
   
   // go to next row to Excel
   ++row;
   
   // increment number of warnings
   numWarnings++;
  }
  // expand columns to fit text
  xls.Range col1 = worksheet.get_Range("A1", Missing.Value);
  xls.Range col2 = worksheet.get_Range("B1", Missing.Value);
  col1.EntireColumn.ColumnWidth = 70;
  col1.EntireColumn.WrapText = true;
  col2.EntireColumn.ColumnWidth = 25;
  
  // show dialog for results
  TaskDialog.Show("Success", "Exported " + numWarnings.ToString() + " warnings to Excel!!!");
 }
 catch (Exception ex)
 {
  TaskDialog.Show("Error", "Something bad happened!!!" + System.Environment.NewLine
      + System.Environment.NewLine + ex.Message);    
 }
 
}

Friday, February 24, 2017

Export All Possible Revit Warnings

A few weeks ago, Konrad Sobon, posted a Python script for exporting all the possible Revit warnings to use in a Dynamo script that analyzes and ranks the warnings in the current model. Since I mostly work in C#, I took his Python script and created a C# macro. I've had several requests for it, so here it is...


public void ExportWarnings()
{
    try
    {
        using (StreamWriter writer = new StreamWriter(@"C:\temp\warnings.txt"))
        {
            FailureDefinitionRegistry failures = Autodesk.Revit.ApplicationServices.Application.GetFailureDefinitionRegistry();
            IList<FailureDefinitionAccessor> failuresList = failures.ListAllFailureDefinitions();
            
            foreach (FailureDefinitionAccessor failure in failuresList)
            {
                if (failure.GetSeverity() == FailureSeverity.Warning)
                    writer.WriteLine(failure.GetDescriptionText());
            }
            
            writer.Close();
        }
    }
    catch
    {
        
    }
    
}


And the resulting file from Revit 2017 : Warnings.txt

Wednesday, February 01, 2017

Adding Revisions to a Sheet Index

Recently, I had someone make a request for adding an X to a column in a sheet index schedule for all the revisions that sheet had. Currently, they have to do it by hand and it is tedious.





















To get this to work, I added a parameter for each revision called "Seq #" (with # being the revision sequence number). I looped through each revision on each sheet and looked up it's sequence number, then add an X to the parameter matching it.

Here is a video showing how it fills in the sheet index schedule:






And the code...


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public void SheetRevisions()
{
 Document doc = this.ActiveUIDocument.Document;
 
 using (Transaction t = new Transaction(doc, "Revisions on Sheet"))
 {
  t.Start();
  
  // loop through all the sheets in the model
  foreach (ViewSheet vs in new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)))
  {
   // get a list of all the Revision Ids for this sheet
   IList<ElementId> revIds = vs.GetAllRevisionIds();
   
   // if at least 1 Revision, continue
   if (revIds.Count > 0)
   {
    // loop through each of the Revision Ids
    foreach (ElementId eid in revIds)
    {
     // get the actual Revision element
     Element elem = doc.GetElement(eid);
     Revision rev = elem as Revision;
     
     // add an X to the parameter named "Seq #"
     vs.LookupParameter("Seq " + rev.SequenceNumber.ToString()).Set("X");
    }
    
   }
  }
  
  t.Commit();
 }   
}

Monday, May 02, 2016

RevitLookup 2017

I have compiled the latest source code for RevitLookup 2017 from Jeremy Tammik's GitHub (https://github.com/jeremytammik/RevitLookup).

Note: I did not create or edit this Revit Addin. I am only compiling it for those that don't understand or want to compile it for themselves.

Here is the download link: RevitLookup2017.zip

It is also listed on the right-hand column under downloads.

Wednesday, March 16, 2016

PDQ Deploy and Inventory for Autodesk and other applications

I have been using PDQ Deploy and Inventory for about 2 years now. It has been one of the highest ROIs on a product I have ever used. The ease, speed, and reliability of being able to push a product, product updates, and custom product settings out to 350+ PCs from a $1000 pair of tools has been a game changer for my company.


What is PDQ?

PDQ Deploy and PDQ Inventory (by Admin Arsenal) are a pair of applications that allow BIM Mangers, IT Admins, etc to deploy software and files silently across many PCs as well as keep an inventory of all the PCs software, hardware, and more. The programs do not require any pre-installation of software on the PCs and can install just about anything most companies need across a single office or multiple offices.













My Setup

My company currently uses PDQ to inventory well over 400 PCs and pushes deployments across 7 offices in 2 countries. We use PDQ inventory to track which PCs have which versions and service packs of all software applications, then use PDQ Deployment to automatically push updates to them. We also use PDQ to push out new versions of applications as they become available. Lastly, we use PDQ to deploy suites of applications to new systems within the company, gone are the old days of having a system image with everything installed.

PDQ Inventory

PDQ Inventory can tie into your Active Directory (AD) to quickly learn about all of the PCs within your company. My company has PCs in an AD container system like in the image below. By having PCs grouped based on office and whether it is a desktop/laptop/conference room/server, allows us to only inventory the PCs we want to use for deployments. We do not currently use PDQ Inventory or Deploy for servers.






















PDQ Inventory is used to create reports about which systems have which software as well as the version of the software. These reports are easy to build using the built-in report creator.



































PDQ Inventory also has what are called “collections”. The collections are live reports of PCs that meet the criteria of the collection. For instance in the next image, it shows all the PCs that have an Autodesk product installed, then the PCs that have Revit 2016 installed, and finally the PCs in each office that have Revit 2016 installed. These collections can be used as a source of PCs that PDQ Deployment can use to deploy a package to.




PDQ Deploy

PDQ Deploy allows you to create packages of applications, patches, and settings than you can then push remotely and silently to any number of PCs.

Creating a package in PDQ Deploy is as easy as specifying the msi, exe, bat, etc file that you want to deploy. By combing several steps (see image) you end up with a full blown package like the image below for Revit 2016, Dynamo, several addins, ini files and updates.




































Once you have a package built, you choose the PCs to push the package to. This can be from Active Directory, from a collection in PDQ Inventory, or even from a text file. We typically push out to about 10 PCs at a time. For PCs in other offices, we use a DFSR share to replicate all of the installation files to each office. Then the packages use a DFS namespace that is identical in each office to do the install from.

Here is the output for a package that installs AutoCAD Architecture 2016 (w/ SPs and hotfixes), uninstalls all pre-2015 Autodesk software on the PC, installs Revit 2016 (w/ addins, updates, ini files, etc), and Bluebeam PDF.




Conclusion


There are lots of other features that I won't touch on that include scheduling, automatic (start install when computer comes on), pre-made packages, and lots more.

The pair of applications have saved us countless hours for deploying software that the savings are probably immeasurable. If you want to try this out, the company has trial versions available. And if you have more questions about how we use it, please feel free to leave a comment.



Tuesday, April 21, 2015

RevitLookup for Revit 2016

With Revit 2016 officially out, I am working on updating my addins for 2016. One of the most invaluable addins has already been updated. Per Jeremy Tammik on his website, http://thebuildingcoder.typepad.com/blog/2015/04/revit-2016-api-news-and-devdays-online-recording.html, RevitLookup has been updated for Revit 2016.

















You can get the source code here: https://github.com/jeremytammik/RevitLookup/releases/tag/2016.0.0.6 and build it yourself.

Or you can download a zip with a version that I have already built here: https://app.box.com/s/5hxbjrtgk77a80uwvycvfxinjvo9tzvt

Just extract the contents of the zip file into your Revit 2016 addins folder ( C:\ProgramData\Autodesk\Revit\Addins\2016\ )

Thursday, April 02, 2015

Convert View Names on Sheets to UPPERCASE

Here is a quick little Revit Macro that will change all the View names on Sheets to UPPERCASE. This helps when browsing through the Project Browser to identify which views are placed on Sheets. It is one directional at the moment, so if a view that is already UPPERCASE is not on a sheet anymore it won't change it back to lowercase. If I add this in the future I will post an update then.


public void SheetViewNamesToUppercase()
{
    Document doc =  this.ActiveUIDocument.Document;
   
    using(Transaction t = new Transaction(doc, "Sheet View Names to Uppercase"))
    {
        t.Start();
       
        foreach(ViewSheet vs in new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)))
        {
            foreach(ElementId eid in vs.GetAllPlacedViews())
            {
                try
                {
                    View v = doc.GetElement(eid) as View;
                    v.Name = v.Name.ToUpper();
                }
                catch
                {                           
                }
               
            }
        }
       
        foreach (ViewSchedule vsc in new FilteredElementCollector(doc).OfClass(typeof(ViewSchedule)))
        {
            foreach (ScheduleSheetInstance ssi in new FilteredElementCollector(doc).OfClass(typeof(ScheduleSheetInstance)))
            {
                if (vsc.Name == ssi.Name)
                {
                    try
                    {
                        vsc.Name = vsc.Name.ToUpper();
                    }
                    catch
                    {                               
                    }
                   
                }
            }
        }

        t.Commit();
    }
}

Friday, February 20, 2015

Quick Macro for Duplicating an Existing Sheet and Views

I had someone recently ask me if it was possible to duplicate a sheet and it's views in Revit. It isn't possible within Revit by default, but with a little bit of code, I was able to get a macro that would duplicate the sheet and it's views. Give the macro a try, just make sure you are in a sheet view before running the macro.

Note: the duplicated views and sheets are renamed with "-DUP" since they need to be unique in Revit. You can change this in the code to be anything you want.

public void DuplicateSheet()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
    ViewSheet vs = doc.ActiveView as ViewSheet;
   
    using(Transaction t = new Transaction(doc, "Duplicate Sheet"))
    {
        t.Start();
   
        FamilyInstance titleblock = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance))
            .OfCategory(BuiltInCategory.OST_TitleBlocks).Cast<FamilyInstance>()
            .First(q => q.OwnerViewId == vs.Id);

        ViewSheet newsheet = ViewSheet.Create(doc, titleblock.GetTypeId());
        newsheet.SheetNumber = vs.SheetNumber + "-DUP";
        newsheet.Name = vs.Name;
       
        // all views but schedules
        foreach(ElementId eid in vs.GetAllPlacedViews())
        {
            View ev = doc.GetElement(eid) as View;
           
            View newview = null;
           
            // legends
            if (ev.ViewType == ViewType.Legend)
            {
                newview = ev;
            }
            // all non-legend and non-schedule views
            else
            {
                ElementId newviewid = ev.Duplicate(ViewDuplicateOption.WithDetailing);
                newview = doc.GetElement(newviewid) as View;
                newview.Name = ev.Name + "-DUP";
            }
           
            foreach (Viewport vp in new FilteredElementCollector(doc).OfClass(typeof(Viewport)))
            {
                                               
                if (vp.SheetId == vs.Id && vp.ViewId == ev.Id)
                {
                    BoundingBoxXYZ vpbb = vp.get_BoundingBox(vs);
                    XYZ initialCenter = (vpbb.Max + vpbb.Min) / 2;
                   
                    Viewport newvp = Viewport.Create(doc, newsheet.Id, newview.Id, XYZ.Zero);
                   
                    BoundingBoxXYZ newvpbb = newvp.get_BoundingBox(newsheet);
                    XYZ newCenter = (newvpbb.Max + newvpbb.Min) / 2;
                   
                    ElementTransformUtils.MoveElement(doc, newvp.Id, new XYZ(
                        initialCenter.X - newCenter.X,
                        initialCenter.Y - newCenter.Y,
                        0));
                }
                   
            }
           
        }
       
        // schedules
       
        foreach (ScheduleSheetInstance si in (new FilteredElementCollector(doc).OfClass(typeof(ScheduleSheetInstance))))
        {
            if (si.OwnerViewId == vs.Id)
            {
                if (!si.IsTitleblockRevisionSchedule)
                {                           
                    foreach (ViewSchedule vsc in new FilteredElementCollector(doc).OfClass(typeof(ViewSchedule)))
                    {
                        if (si.ScheduleId == vsc.Id)
                        {
                            BoundingBoxXYZ sibb = si.get_BoundingBox(vs);
                            XYZ initialCenter = (sibb.Max + sibb.Min) / 2;
                           
                            ScheduleSheetInstance newssi = ScheduleSheetInstance.Create(doc, newsheet.Id, vsc.Id, XYZ.Zero);
                           
                            BoundingBoxXYZ newsibb = newssi.get_BoundingBox(newsheet);
                            XYZ newCenter = (newsibb.Max + newsibb.Min) / 2;
                           
                            ElementTransformUtils.MoveElement(doc, newssi.Id, new XYZ(
                                initialCenter.X - newCenter.X,
                                initialCenter.Y - newCenter.Y,
                                0));
                        }
                    }
                }

            }
        }
       
   
        t.Commit();
    }
   
}

Wednesday, February 11, 2015

Revit Macro for Mass Importing Shared Parameters

The following was a quick attempt to see if I could mass import a bunch of shared parameters into my projects. Its part of a tool I am building that needed some unique parameters for schedules and tags.

public void ImportSharedParameters()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
  
    // location of shared parameters file
    string spfile = @"\\corp.ktgy.com\bim\DT\API\Unit Coin\Shared Parameter-KTGY.txt";
  
    using (Transaction t = new Transaction(doc, "Import Shared Parameters"))
    {
        t.Start();
        

        // create a new line for each parameter like this:
       // doc, SharedParametersFile, ParameterName, Category, ParameterGroup, VaryByGroupInstance         CreateProjParameter(doc, spfile, "Building", BuiltInCategory.OST_Rooms, BuiltInParameterGroup.PG_IDENTITY_DATA, true);
        CreateProjParameter(doc, spfile, "Unit Area", BuiltInCategory.OST_Rooms, BuiltInParameterGroup.PG_GENERAL, true);
                      
        t.Commit();
    }
}


public void CreateProjParameter( Document doc, string sharedParameterFile, string parameterName,
                                BuiltInCategory bicategory, BuiltInParameterGroup bipgroup, Boolean varyByGroup)
{
    // load the shared parameters file
    Application.SharedParametersFilename = sharedParameterFile;
  
    // select the category
    Category cat = doc.Settings.Categories.get_Item(bicategory);
    // create a new category set
    CategorySet catset = Application.Create.NewCategorySet();
    // add category to category set
    catset.Insert(cat);
  
    // loaded shared parameter file
    DefinitionFile deffile = Application.OpenSharedParameterFile();
  
    try
    {
        // find the parameter in the shared parameters file
        // by searching each parameter group
        var v = (from DefinitionGroup dg in deffile.Groups
                 from ExternalDefinition d in dg.Definitions
                 where d.Name == parameterName
                 select d);
      
        ExternalDefinition def = v.First();
      
        // bind the parameter to the category and parameter group
        Binding binding = Application.Create.NewInstanceBinding(catset);
        BindingMap map = doc.ParameterBindings;
        map.Insert(def, binding, bipgroup);
      
        // change parameter to be "Values can vary by group instance"
        if(varyByGroup)
        {
            BindingMap grpmap = doc.ParameterBindings;
            DefinitionBindingMapIterator it = grpmap.ForwardIterator();
          
            while (it.MoveNext())
            {
                Definition d = it.Key as Definition;
                if (d.Name == parameterName)
                {
                    InternalDefinition idef = it.Key as InternalDefinition;
                    idef.SetAllowVaryBetweenGroups(doc, true);
                }
            }
        }
                      
    }
    catch (Exception ex)
    {
               TaskDialog.Show("Error", ex.Message);
    }
}

Thursday, January 15, 2015

BIM Consortium Revit Addin Bug Fix Edition

I uploaded a new build of the BIM Consortium Addin today with quite a few bug fixes. The most notable ones being...

  • Delete Unused Views would crash Revit randomly. Tool completely re-written to be more stable
  • Rooms to 3D Views and the Room 3D Tags shouldn't error out when there are un-bounded or non-placed rooms anymore
If you come across any other bugs, make sure to shoot me an email at troygates@gmail.com.


Download HERE 

Monday, July 21, 2014

BIMConsortium Revit Addin Update + New Tools + 2015 Compatible












A new update is available located here: BIMCon_Addin_1.2.zip


Updated
  • Addin now supports both Revit 2014 and 2015
  • Delete Views - Added option to delete all views NOT on a Sheet
















New

3D Room Tags
This tool will place a generic family with 3D text into the center of every room at the specified height above the room's level. Load the included family Room Tag 3D BIMCon.rfa. This family can be modified to what you want it to look like as long as it keeps the same name. I will add an option in the future to pick a family of your own.


















Room to 3D Views
This tool will create four (4) 3D Camera Views for every room in the model. The views are placed at lower-left and upper-right at floor and above ceiling. The heights are adjustable.

* Note: Because of how the API determines a room boundary as a rectangular box, the cameras may be located outside the actual rooms.























Merge Text
This tool is actually two (2) tools, Merge 2 Text and Merge Multiple Text.
















The first one will take two (2) pieces of text and merge them together with several options available.





















The second tool will merge several text elements into the first one selected. Notice that you need to hit ESC to end the selection of elements.

















NOTE:
If you receive an error in Revit about not being able to load the addin, go to the folder where you saved the dll file, right-click the file and go to properties. In the properties dialog click the button to Unblock the file.


Tuesday, June 24, 2014

Revit Lookup 2015 Addin

During my class (BIM Managers Guide to Automating Revit Using Macros) at RTC in Schaumburg (Chicago) last week, I mentioned the Revit Lookup addin. Afterwards several people asked where they could download a compiled version. I compiled the most recent source from https://github.com/jeremytammik/RevitLookup/ and uploaded it to my blog so you can download it (below).

Download
Revit Lookup 2015

Install Instructions
Extract the 2 files to C:\ProgramData\Autodesk\Revit\Addins\2015\


If you are interested in 2013 and 2014 versions you can find them in a blog post from last year: http://revitcoaster.blogspot.com/2013/09/creating-macros-larug-sept-2013.html 

Thursday, June 05, 2014

View Schedule with Detail Numbers Macro for Revit

A question was posted on http://revitforum.org about showing a view's detail number in a view list schedule. Revit has a parameter for the Detail Number (see first image) but it isn't accessible to add in a view list schedule.

Original post: http://www.revitforum.org/architecture-general-revit-questions/20119-detail-number-view-list-schedule.html




















Solution

Step 1
Create a View List schedule (or edit an existing one) and add a new text Parameter named "Detail_Number" (notice the _ in the name)






















Step 2
Create a new macro with the following routine and run it

public void DetailNumber()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
  
    string strDetailNumber = "Detail_Number";         
  
    FilteredElementCollector collector = new FilteredElementCollector(doc);
    ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();
  
    using (Transaction t = new Transaction(doc, "Detail Number"))
    {
        t.Start();
      
        foreach(Element e in collection)
        {
            View v = e as View;
          
            try
            {
                Parameter bpDetailNumber = v.get_Parameter(BuiltInParameter.VIEWPORT_DETAIL_NUMBER);
                v.get_Parameter(strDetailNumber).Set(bpDetailNumber.AsString());
            }
            catch
            {
              
            }
          
        }
      
        t.Commit();
    }
}


Results
All the views that are on sheets now have the Detail Number copied into the Detail_Number parameter.



















Run the macro whenever you want to update the values in the new parameter to reflect the current state of the project (aka is doesn't auto update and needs to be run manually).

Wednesday, February 12, 2014

BIM Consortium Addin Updated With New Tool








A new update has been uploaded of the BIM Consortium Revit Addin. The new release adds some polish to the existing tools and  also adds a new tool. Hope you enjoy them as much as I had making them.

Download: https://drive.google.com/file/d/0B16E2YBKmeUtbmZsNDFIUmJHMm8/edit



Dependent Views from Scope Boxes (New)
This new tool will allow you to create dependent views for any number of floor or ceiling plans and apply a Scope Box to them. This tool was created for setting up projects that have multiple work areas divided up using scope boxes.



























Dependent Views (Updated)
The tool now has an interface that allows you to pick how many dependent views you want to duplicate of the current view.















Delete Views (Updated)
Added a logo to the dialog box.























3D Grid Creator (Updated)
Added a logo to the dialog box.


Wednesday, January 29, 2014

BIM Consortium Revit Add-in First Release

I have been working with the Los Angeles Revit Users Group leadership group (known as the BIM Consortium) to start creating a set of Revit add-ins based on meeting discussions. I'm happy to announce the first release of the add-in.

Download: https://drive.google.com/file/d/0B16E2YBKmeUtbmZsNDFIUmJHMm8/edit

Instructions for installation are inside the zip file.


This initial release comes with 3 tools...




3D Grid Generator
This tool is based on the 3D Grid family created by Jay Zallan. Jay demoed the family during a meeting that I happened to also be discussing macros. I challenged myself to take Jay's family and create a macro that would automatically place a 3D Grid family on every grid line in the model. After several iterations, I converted the macro to an add-in and here it is.

The tool is very simple. First load the 3D Grids family included with the add-in into your Revit model. Then start the tool and choose the levels that you would like to have 3D grids on. Then you can use Jay's original guide on how to use the 3D grids. Quick video demo can be found here: https://www.youtube.com/watch?v=-wSnc9-j2O8



** The first release does have a limitation that I am working on fixing and will release in a future update. It currently won't recognize that a 3D grid already exists when creating them. So if you run the tool twice on the same level you will end up with two families in the same place and Revit will let you know. If you want to place new copies if your grid changes, for now you will need to delete the existing 3D grids before you create new ones.


Create Dependent Views
This tool is very simple and came as a request. It will simply duplicate as dependent the active view 5 times. Saves you 5 right-clicks.

** I have already received a request to add a dialog that allows you to pick your own number. It will be in a future update.


Delete Views
This tool was the original reason I wanted to learn how to create macros in Revit. As an MEP firm I work with a lot of models from other companies. In order to keep the numerous linked models manageable, I clean the models by deleting views, legends, schedules, and sheets. I used to do this by hand by deleting them from the project browser. Now I can run this tool and get it done quickly.

Word of caution, this will DELETE views and sheets from your currently active model. Be careful using the tool (I take no responsibility for your usage :-) ).

To use the tool, start from a view you want to keep (Revit requires at least 1 view in a model). Run the tool and choose the option that best suits your model usage.


  • Delete All Non-Plan Views – this option will delete all views except floor and ceiling plans. This is best for consultant models that you will be using linked views.
  • Delete All Views – this option will delete all views in a model except the currently active one.
  • Delete All Except Containing – this option will delete all views except ones containing the word you type in. This is best for prearranged view names for linked models. IE: another company has created views with consultant in the name. Type consultant into the box to delete all but the consultant views.
  • Delete Sheets Too – this option will also delete all the sheets in addition to the options chosen above.

Macro to change all families to the same LEADER ARROWHEAD style

I had a request to write a macro that would change all families' Leader Arrowhead style to the same type in a project.



This is the code I came up with:


public void UpdateLeaders()
        {
            UIDocument uidoc = this.ActiveUIDocument;
            Document doc = uidoc.Document;
            
            // create a collection of all the Arrowhead types
            ElementId id = new ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME);
            ParameterValueProvider provider = new ParameterValueProvider(id);
            FilterStringRuleEvaluator evaluator = new FilterStringEquals();
            FilterRule rule = new FilterStringRule(provider, evaluator, "Arrowhead", false);
            ElementParameterFilter filter = new ElementParameterFilter(rule); 
            FilteredElementCollector collector2 = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).WherePasses(filter);
            
            ElementId arrowheadId = null;
              
            // loop through the collection of Arrowhead types and get the Id of a specific one
            foreach(ElementId eid in collector2.ToElementIds())
            {
                if(doc.GetElement(eid).Name == "Arrow Filled 30 Degree") //change the name to the arrowhead type you want to use
                {
                    arrowheadId = eid;
                }
            }
            
            // create a collection of all families
            List<Family> families = new List<Family>(new FilteredElementCollector(doc).OfClass(typeof(Family)).Cast<Family>());
            using(Transaction t = new Transaction(doc, "Update Leaders"))
            {
                t.Start();        
                // loop through all families and get their types       
                foreach(Family f in families)
                {
                    FamilySymbolSet symbols = f.Symbols;
                    List<FamilySymbol> symbols2 = new List<FamilySymbol>(symbols.Cast<FamilySymbol>());
                 
                     // loop through the family types and try switching the parameter Leader Arrowhead to the one chosen above
                     // if the type doesn't have this parameter it will skip to the next family type
                    foreach(FamilySymbol fs in symbols2)
                    {
                        try
                         {
                             fs.get_Parameter(BuiltInParameter.LEADER_ARROWHEAD).Set(arrowheadId);
                         }
                         catch
                         {
                             
                         }
                     }
                }
                t.Commit();
            }
        }


Tuesday, November 19, 2013

Setting an Image's Visibility to Off in a Family

I am revamping several of our engineer's stamps for Revit 2014 and didn't want to go through the old process of converting their signature from an image to CAD and then importing to Revit. So I decided to just use the images and went to set the Visibility to a parameter and found it wasn't available (I already knew this from way back, but forgot about it).

Image in Family with no Parameter for Visibility

















Looking over the small list of parameters, it hit me. Why not make the Width and Height equal to 0 when I don't want to see the signature, thus setting it to not visible.

So I setup 3 parameters called Show Signature, Sig_W, and Sig_H. I then linked the Image's Width to Sig_W and Height to Sig_H. Lastly I created a formula for Sig_W and Sig_H to adjust the image size off of the parameter Show Signature's value.

New Parameters and Formulas


















Linking the Width and Height to the New Parameters

Monday, November 18, 2013

Quick Macro that creates 5 Dependent Views for the Current View

I had a user that needed to create 5 dependent views for 5 areas in a building across several views and disciplines. To save him time, I created this quick macro that will create 5 dependent views for the active view. This will save a lot of right-clicking on each view.

Code:


        public void CreateDependentViews()
        {
            UIDocument uidoc = this.ActiveUIDocument;
            Document doc = uidoc.Document;

            using(Transaction t = new Transaction(doc, "Duplicate View 5x"))
            {
                t.Start();
              
                int i = 0;
              
                while (i < 5)
                {
                    uidoc.ActiveView.Duplicate(ViewDuplicateOption.AsDependent);
                    i++;
                }               
                t.Commit();                   
            }           
        }


I expanded it a bit more and did some renaming based on Areas just to enhance it a bit.

Code:

        public void CreateDependentViews()
        {
            UIDocument uidoc = this.ActiveUIDocument;
            Document doc = uidoc.Document;

            using(Transaction t = new Transaction(doc, "Duplicate View 5x"))
            {
                t.Start();
               
                int i = 0;
               
                while (i < 5)
                {
                    ElementId dupViewId = uidoc.ActiveView.Duplicate(ViewDuplicateOption.AsDependent);
                    View dupView = doc.GetElement(dupViewId) as View;
                    char c = (char) (i + 65);
                    dupView.Name = uidoc.ActiveView.Name + " - AREA " + c.ToString();
                   
                    i++;
                }
               
                t.Commit();                   
            }           
        }