Code Examples April 15, 2018

Variable scope:

If you haven't heard of variable scope, you may be in for a tough time trying to figure out how to carry data from one part of you program to another. You can pass variables and objects to functions through parameters, but sometimes it’s nice to have a variable that is available through-out your addin or macro.

For an addin, these can be defined right after the Iexternal command line:

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]

public class MyAddin : IExternalCommand

{

public static string myreturn = null;

public static string mycomment = null;

……

}

For a macro, you can declare these right before your macro entry point. That is right after the "endregion" line. (You might have to expand one of the plus signs to see this line of code.) I'm not sure that is the proper place to put those variables, but it works.

Also, it might be safer to declare them as private instead of public. For example:

private static string myreturn = null;

Get the selection:

// Get the element selection of current document.

Selection selection = uidoc.Selection;

//store element id's

ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();

Verify a selection is a certain family type:

foreach (ElementId id in selectedIds) //for each selected element

{

Element e = doc.GetElement(id); //get the element from the id

if (e.Name.ToString() != "receptacle") //check each element to see if it is a receptacle

{

TaskDialog.Show("Revit Keynote Editor", "Please only select receptacles.");

}

}

Get an element from the element id or reference:

The Revit API has 3 ways to work with elements, the element, the element id, or the element reference. Different commands need the element passed in different ways. Here are some conversions:

Element e = doc.GetElement(id); //element id to element

Element e = doc.GetElement(ref); //element reference to element

ElementId id = ref.elementID; //element reference to elementid

ElementId id = e.ID; //element to an elementid

Reference r = new Reference (element); //element to an element reference

Get element parameters:

foreach (ElementId id in selectedIds) //for each selected element

{

Element e = doc.GetElement(id); //get the element from the id

mycomment = e.LookupParameter("Comment"); //lookup the value of the parameter named "Comment"

//if Comment is a text parameter, mycomment should be declared as a string

//earlier in the program

mynumber = e.LookupParameter("Note Number"); //lookup the value of the parameter named "Note Number"

//if Comment is a integer parameter, mynumber should be declared as a integer

//earlier in the program

pickedtypeid = e.GetTypeId(); //get the elements type (the id of the family the element belongs to)

Element et = doc.GetElement(pickedtypeid); //get the family type from the type ID (similar to getting an element from

//the element id

pickedtype = et.LookupParameter("Family Name"); //get the name of the family type

}

Change a parameter:

Autodesk.Revit.DB.Transaction t = new Autodesk.Revit.DB.Transaction(doc, "Change Parameter");

t.Start();

foreach (ElementId id in selectedIds) //for each selected element

{

Element e = doc.GetElement(id); //get the element from the id

Parameter myparam = e.LookupParameter("Comment"); //lookup the value of the parameter named "Comment"

myparam.Set(mynewcomment);

}// end foreach

t.Commit();

Get a specific family name and type, and place it:

FilteredElementCollector familyCollector = new FilteredElementCollector(doc);

familyCollector.OfClass(typeof(FamilySymbol));

FamilySymbol familySymbolToFind = null;

foreach (FamilySymbol familySymbol in familyCollector)

{

//To search by FamilySymbol name

if (familySymbol.Name == "receptacle" && familySymbol.Family.Name == "duplex")

familySymbolToFind = familySymbol;

//To search by Family name

}// end foreach

uidoc.PromptForFamilyInstancePlacement(familySymbolToFind);

Get or Change an elements workset:

using (Transaction tx = new Transaction(doc,"Change Workset"))

{

tx.Start();

foreach (Element e in elements)

{

//Get the workset;

Parameter wsparam =e.get_Parameter(BuiltInParameter.ELEM_PARTITION_PARAM);

//Change the workset;

try

{

e.get_Parameter(BuiltInParameter.ELEM_PARTITION_PARAM).Set(sharedGridWorksetId);

TaskDialog.Show("Changed", e.Name.ToString());

}

catch

{

}

}

tx.Commit();

}

Open a shared parameters file:

(Note the use of the “this” keyword in the following code which is used in macros to refer to the object that called the code. Sometimes this is necessary for document level macros as opposed to application level macros. Note that this code is intended to be ran from within the family editor.

public void AddSharedParameters()

{

//UIDocument uiDoc = this.ActiveUIDocument; //dont need this

Document doc = this.ActiveUIDocument.Document;

//open a shared parameters filename

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.InitialDirectory = (@"C:\Your folder here");

if (openFileDialog1.ShowDialog() == DialogResult.OK)

{

foreach (string path in openFileDialog1.FileNames)

{

FileInfo filePath = new FileInfo(path);

//MessageBox.Show("filePath.FullName.ToString() = " + filePath.FullName.ToString());

this.Application.SharedParametersFilename = filePath.FullName.ToString();

}

}

this.Application.OpenSharedParameterFile ();

Insert a shared parameter from the shared parameter file. (This is intended to be ran from within the family editor).

Category cat = doc.Settings.Categories.get_Item(BuiltInCategory.OST_LightingFixtures); //change the category here

// if you are using something besides light fixtures

DefinitionFile spFile = this.Application.OpenSharedParameterFile();

FamilyManager famMan = doc.FamilyManager;

IList<FamilyParameter> existfamilyPar = famMan.GetParameters();

foreach (DefinitionGroup dG in spFile.Groups) //get each group in the shared parameter file

{

var v = (from ExternalDefinition d in dG.Definitions select d);

using (Transaction t = new Transaction(doc))

{

t.Start("Add Shared Parameters");

foreach (ExternalDefinition eD in v) //get each parameter in the current group

{

try

{FamilyParameter fp = famMan.AddParameter (eD,BuiltInParameterGroup.PG_GENERAL,false); //change the

//group here if you want the parameters in a different group

}

catch

{

}

}//end foreach

t.Commit();

}//end using transaction

}// end foreach

Sort family parameters:

using (Transaction t = new Transaction(doc))

{

t.Start("Sort Parameters");

famMan.ReorderParameters(sortedfamilyPar);

t.Commit();

Get and place groups:

public void GroupInfo()

{

UIDocument uiDoc = this.ActiveUIDocument;

Document doc = this.ActiveUIDocument.Document;

GroupType groupType = new FilteredElementCollector(doc)

.OfClass(typeof(GroupType)).OfType<GroupType>()

.Where(g => g.Name == "Breaker").FirstOrDefault();

GroupType groupType2 = new FilteredElementCollector(doc)

.OfClass(typeof(GroupType)).OfType<GroupType>()

.Where(g => g.Name == "Contactor").FirstOrDefault();

GroupType groupType3 = new FilteredElementCollector(doc)

.OfClass(typeof(GroupType)).OfType<GroupType>()

.Where(g => g.Name == "Panelboard").FirstOrDefault();

TaskDialog.Show("Group Type:" , groupType.ToString() + " " + groupType2.Name.ToString() + " " + groupType3.Name.ToString());

string message = "GroupType";

//Retrieve a set of all the groups that have this type.

foreach (Group group in groupType.Groups)

{

// Get GroupType group name

message = "\nThe group type name is : " + groupType.Name;

//Returns all the members of the group.

message += "\nThe types and ids of the group members are : ";

IList<ElementId> groupMembers = group.GetMemberIds();

foreach (ElementId memberId in groupMembers)

{

Element element = group.Document.GetElement(memberId);

// Get GroupType group element id

message += "\n\t" + element.GetType().Name + " : " + memberId.IntegerValue;

}

}

TaskDialog.Show("Revit",message);

// place a group

using (Transaction t = new Transaction(doc))

{

t.Start("Add Group");

XYZ mypoint = new XYZ(5, 5, 5);

doc.Create.PlaceGroup(mypoint, groupType3);

t.Commit();

}

}

Open a section view: (string variable viewname contains name of section view.)

FilteredElementCollector collector = new FilteredElementCollector(doc);

collector.OfClass(typeof(ViewSection));

foreach (ViewSection current in collector)

{

if (current.Name == viewname)

{

//Transaction tx = new Transaction(doc);

//tx.Start( "Open Section" );

uidoc.ActiveView = current;

uidoc.RefreshActiveView();

break;

//tx.Commit();

} // end if

}// end foreach ViewSection

Remove family parameters: (Run from within the family manager).

public void RemoveFPMacro()

{

//UIDocument uiDoc = this.ActiveUIDocument; //dont need this

Document doc = this.ActiveUIDocument.Document;

FamilyManager famMan = doc.FamilyManager;

IList<FamilyParameter> familyPar = famMan.GetParameters();

//list all the parameters in order to show the original ones

String strNames = null;

foreach (FamilyParameter fp in familyPar)

{

strNames = strNames + fp.Definition.Name.ToString() + "\n";

}

TaskDialog.Show("Original Order", strNames);

//Delete all parameters that start with something

using (Transaction t = new Transaction(doc))

{

t.Start("Delete parameters");

foreach (FamilyParameter fp in familyPar)

{

if (fp.Definition.Name.StartsWith("Electrical"))

{

famMan.RemoveParameter (fp);

}

else if (fp.Definition.Name.StartsWith("MEP"))

{

famMan.RemoveParameter (fp);

}

else if (fp.Definition.Name.StartsWith("Plumbing"))

{

famMan.RemoveParameter (fp);

}

}

t.Commit();

}

}

}//end public partial class

}//end namespace

Rotate elements about their center points:

foreach (ElementId id in selectedIds)

{

Element e = doc.GetElement(id);

BoundingBoxXYZ box = e.get_BoundingBox(doc.ActiveView);

if (null == box)

{

throw new Exception("Selected element doesn't contain a bounding box.");

}

XYZ p1 = new XYZ((box.Min.X + box.Max.X)/2, (box.Min.Y + box.Max.Y)/2, 0);

XYZ p2 = new XYZ((box.Min.X + box.Max.X)/2, (box.Min.Y + box.Max.Y)/2, 10);

Line axis = Line.CreateBound(p1, p2);

ElementTransformUtils.RotateElement(doc, id, axis, Math.PI/2);

}

}

catch

{

TaskDialog.Show("Revit C# Error", "Error rotating elements.");

}

finally

{ }

Copy and paste elements:

Autodesk.Revit.DB.Transaction t = new Autodesk.Revit.DB.Transaction(doc, "Copy and Paste");

point1 = selection.PickPoint("Please pick a base point.");

point2 = selection.PickPoint("Please pick a point to place elements");

point3 = point2.Subtract(point1);

t.Start();

ICollection<ElementId> pastedIds = ElementTransformUtils.CopyElements(doc, selectedIds, point3);

t.Commit();

Get an elements phase and workset:

Phase createsource = new Phase;

Phase demosource = new Phase;

if (elementcopy.HasPhases())

{

if (elementcopy.Document.GetElement(elementcopy.CreatedPhaseId) != null)

{

Createsource = elementcopy.Document.GetElement(elementcopy.CreatedPhaseId) as Phase;

}// end if

if (elementcopy.Document.GetElement(elementcopy.DemolishedPhaseId) != null)

{

demosource = elementcopy.Document.GetElement(elementcopy.DemolishedPhaseId) as Phase;

}// end if

}// end HasPhases

Set an elements phase and workset: (demosource and createsource are variables holding valid phases, and could be obtained from an element as shown above);

myelement = doc.GetElement(id);

if (myelement.HasPhases() && myelement.ArePhasesModifiable())

{

if (createsource != null)

{

myelement.get_Parameter(BuiltInParameter.PHASE_CREATED).Set(createsource.Id);

}// end if

}// end if

if (myelement.HasPhases() && myelement.ArePhasesModifiable())

{

if (demosource != null)

{

myelement.get_Parameter(BuiltInParameter.PHASE_DEMOLISHED).Set(demosource.Id);

}// end if

}// end if

Place an element: must include a "using Autodesk.Revit.DB.Structure;" in the setup code.

public void StructType() //minimum code to place a family instance with NewFamilyInstance

{

Document doc = this.ActiveUIDocument.Document;

FilteredElementCollector familyCollector = new FilteredElementCollector(doc);

familyCollector.OfClass(typeof(FamilySymbol));

FamilySymbol familySymbolToFind = null;

foreach (FamilySymbol familySymbol in familyCollector)

{

if (familySymbol.Name == "Data")

{familySymbolToFind = familySymbol;

}

}

Transaction tx = new Transaction(doc);

tx.Start("Place");

XYZ insert_point = new XYZ(0,0,0);

doc.Create.NewFamilyInstance(insert_point, familySymbolToFind, StructuralType.NonStructural);

tx.Commit();

}

}