Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

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, 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

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);
    }
}

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, January 29, 2014

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();
            }
        }


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();                   
            }           
        }

Saturday, October 19, 2013

Macro that Exports All Sheets to DWG

***UPDATED***
Code has been updated to fix a bug with Sheet Placeholders causing an error.

Jay Zallan asked me if I could help him create a macro that would quickly export all sheets to DWG files for his consultants that only use CAD. Here is the result, a macro that will export all the sheets to DWG into a dated subfolder where the model is located. The DWGs have bound views and shared coordinates.

Macro has also been added to https://bitbucket.org/BoostYourBIM/revit_api_public/

Code:
        public void ExportSheetsToDWG()
        {
            // setup uidoc and doc for accessing the Revit UI (uidoc) and the Model (doc)
            UIDocument uidoc = this.ActiveUIDocument;
            Document doc = uidoc.Document;
           
            // get all the elements in the model database
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            // filter out all elements except Views
            ICollection<Element> collection = collector.OfClass(typeof(ViewSheet)).ToElements();
           
            // create a transaction
            using(Transaction t = new Transaction(doc, "Export Sheets"))
            {
                // start the transaction
                t.Start();
               
                // create a list to hold the sheets
                List<ElementId> sheetsToDWG = new List<ElementId>();
               
                // create DWG export options
                DWGExportOptions dwgOptions = new DWGExportOptions();
                dwgOptions.MergedViews = true;
                dwgOptions.SharedCoords = true;
               
                // add a counter to count the sheets exported
                int x = 0;
            
                // loop through each view in the model
                foreach (Element e in collection)
                {                   
                    try
                    {   
                        ViewSheet viewsheet = e as ViewSheet;
                       
                        // only add sheets to list
                        if (viewsheet.IsPlaceholder == false)
                        {
                            sheetsToDWG.Add(e.Id);
                            x += 1;
                        }
                    }
                    catch
                    {
                    }
                }

                string path = "";
                string file = "";
               
                // get the current date and time
                DateTime dtnow = DateTime.Now;
                string dt = string.Format("{0:yyyyMMdd HHmm}", dtnow);
               
                if (doc.PathName != "")
                {
                    // use model path + date and time
                    path = Path.GetDirectoryName(doc.PathName) + "\\" + dt;                   
                }
                else
                {
                    // model has not been saved
                    // use C:\DWG_Export + date and time
                    path = "C:\\DWG_Export\\" + dt;
                    file = "NONAME";
                }
               
                // create folder
                Directory.CreateDirectory(path);
               
                // export
                doc.Export(path, file, sheetsToDWG, dwgOptions);
               
                TaskDialog.Show("Export Sheets to DWG", x + " sheets exported to:\n" + path);
            }
        }