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();
}
}
Friday, February 20, 2015
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);
}
}