Hello World From Revit

So what better way to start my first blog post than with the classic “Hello World”.  Well not really the normal Hello World as the one on the Walkthrough: Hello World 

TaskDialog.Show("My Window Title", "Hello World");

but a little more exciting one that introduces some cool challenges like the one in the picture below.

Hello World From Revit

 In today’s post I’m going to cover two very important and useful codes. The  1st one is how to get the XYZ insertion point of a Revit family instance , and the 2nd one is how to place a family instance in a specific XYZ coordinate.

For my set up I’m going to be using the Revit macro manager  (Sharp Develop Software) for beginners. Here is an easy tutorial to get you started with Revit macros .

To get the XYZ insertion point of a Revit family instance we will need to  be able to select a family instance first. Using the following code example will allow you not only to select a single family instance, but multiple family instances  along with  pre-selected objects in to a list.

public void HELLO_WORLD_XYZ()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
Autodesk.Revit.DB.View view = doc.ActiveView; 
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
	
// Select Element(s) Example Code
	Element el = null;

	List<ElementId> ids = new List<ElementId>();
	
	Selection sel = uidoc.Selection;
	
	ICollection<ElementId> selIds = sel.GetElementIds();
	
	if (0 < selIds.Count)
	{
	foreach (ElementId id in selIds)
	{
	ids.Add(id);
	}
	}
	
	if (0 == selIds.Count)
	{
	IList<Autodesk.Revit.DB.Reference> refs = null;
	
	try
	{
	refs = sel.PickObjects(ObjectType.Element,
	"Please select a Element .");
	}
	catch (Autodesk.Revit.Exceptions
	.OperationCanceledException)
	{
	//  return Result.Cancelled;
	}
	ids = new List<ElementId>(
	refs.Select<Autodesk.Revit.DB.Reference, ElementId>(
	r => r.ElementId));
	}
	
	foreach (ElementId id1 in ids)
	{
	
	el = doc.GetElement(id1);
	
	}
// End Select Element(s) Example Code
}

Now we need to create a list that will store our XYZ coordinates.

List <LocationPoint> locationxyz = new List<LocationPoint>();

Next add the actual code that gets the location point of a family instance and adds them into the list.

	LocationPoint point = el.Location as LocationPoint;
	
	locationxyz.Add(point);

Finally lets add a dialog to show us if the code is working correctly.

	foreach ( LocationPoint a in locationxyz)
	{
	TaskDialog.Show("Location Point", "XYZ = "+a.Point.ToString());
	}

Now lets combine those codes…

public void HELLO_WORLD_XYZ()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
Autodesk.Revit.DB.View view = doc.ActiveView; 
Autodesk.Revit.ApplicationServices.Application app = doc.Application;

// Select Element(s) Example Code	
	Element el = null;
//list that will store our XYZ coordinates
	
        List <LocationPoint> locationxyz = new List<LocationPoint>();
	
// End list that will store our XYZ coordinates	

	List<ElementId> ids = new List<ElementId>();
	
	Selection sel = uidoc.Selection;
	
	ICollection<ElementId> selIds = sel.GetElementIds();
	
	if (0 < selIds.Count)
	{
	foreach (ElementId id in selIds)
	{
	ids.Add(id);
	}
	}
	
	if (0 == selIds.Count)
	{
	IList<Autodesk.Revit.DB.Reference> refs = null;
	
	try
	{
	refs = sel.PickObjects(ObjectType.Element,
	"Please select a Element .");
	}
	catch (Autodesk.Revit.Exceptions
	.OperationCanceledException)
	{
	//  return Result.Cancelled;
	}
	ids = new List<ElementId>(
	refs.Select<Autodesk.Revit.DB.Reference, ElementId>(
	r => r.ElementId));
	}
	
	foreach (ElementId id1 in ids)
	{
	
	el = doc.GetElement(id1);

// Gets Location Points and adds them into a list
	
        LocationPoint point = el.Location as LocationPoint;
	
	locationxyz.Add(point);

// Ends Gets location points and adds them into a list	
	}
// End Select Element(s) Example Code

// Goes to every point in a list and displays them one by one
	
        foreach ( LocationPoint a in locationxyz)
	{
	TaskDialog.Show("Location Point", "XYZ = "+a.Point.ToString());
	}
// Ends goes to every point in a list and displays the one by one
}

When you compile the code (F8) and Run it on a selected family instance it will show a dialog like this one.

HelloWorld_Dialog

Now that we know how to get those location points, we will need to start a Revit transaction to modify the Revit document.

 using (Transaction tx = new Transaction(doc))
	{	
		tx.Start("Place Family Instance");
// Your code goes here
		tx.Commit();
	}

Between the tx.start() and the tx.commit() we need to add the “create new instance code”. This code requires the Location Point, Family Symbol and the current view.

FamilySymbol famSym = new        FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Where(q => q.Name == SymbolName).First() as FamilySymbol;
		
XYZ Insert = new XYZ(X,Y,Z);

FamilyInstance instance = doc.Create.NewFamilyInstance(Insert, famSym, view);

Finally here is the complete example code for placing a family symbol in an specific XYZ coordinate.

public void Place_Family_Instace()
{			
	UIDocument uidoc = this.ActiveUIDocument;
	Document doc = uidoc.Document;
	Autodesk.Revit.DB.View view = doc.ActiveView; 
	Autodesk.Revit.ApplicationServices.Application app = doc.Application;
	
//change those 0 values to your own XYZ
		double X = 0;  
		double Y = 0;
		double Z = 0;

//Change that symbol name with you own 
          string SymbolName = "Running Section";		

    using (Transaction tx = new Transaction(doc))
	{	
		tx.Start("Place Family Instance");

Now it’s time to be creative,  and read those XYZ from an External CSV file —> HelloWorld.csv!

public void Place_Family_Instace_from_CSV)
{
			
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
Autodesk.Revit.DB.View view = doc.ActiveView; 
Autodesk.Revit.ApplicationServices.Application app = doc.Application;	
		
double X ;
double Y ;
double Z ;
	string SymbolName = "Running Section";
	//string SymbolName = "Soldier & Plan";
	//string SymbolName = "Circle Wire Tick Mark";
	
 System.Windows.Forms.OpenFileDialog openFileDialog1 = new System.Windows.Forms.OpenFileDialog();

    openFileDialog1.Filter = "CSV (*.csv)|*.csv|All files (*.*)|*.*" ;
    openFileDialog1.FilterIndex = 1 ;
    openFileDialog1.RestoreDirectory = true ;

    if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        List<string[]> parsedData = new List<string[]>();

        using (System.IO.StreamReader readFile = new System.IO.StreamReader(openFileDialog1.InitialDirectory + openFileDialog1.FileName))
        {
            string line;
            string[] row;

            while ((line = readFile.ReadLine()) != null)
            {
                row = line.Split(',');
                parsedData.Add(row);

            }
        }
        int end = parsedData.Count() ;
  for (int i = 0; i < end ; i++)
        {
        	X = Convert.ToDouble (parsedData[i][0].ToString());
        	Y = Convert.ToDouble (parsedData[i][1].ToString());
        	Z = Convert.ToDouble (parsedData[i][2].ToString());
        	
    		using (Transaction tx = new Transaction(doc))
	{

		tx.Start("Place Family Instance");

		FamilySymbol famSym = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Where(q => q.Name == SymbolName).First() as FamilySymbol;
		XYZ Insert = new XYZ(X,Y,Z);
		FamilyInstance instance = doc.Create.NewFamilyInstance(Insert, famSym, view);
		tx.Commit();
	}
        }
    }

}

The result output will be something like the picture below. Try changing the family symbol and the XYZ values to change the appearance.

Hello World CSV Output

Here is the Complete source code and csv file for this example.Web Hello world Example

Spread the knowledge

Leave a Reply