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\ )
Tuesday, April 21, 2015
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();
}
}
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();
}
}
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);
}
}
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