Copy Elements with Revit API + Python

This article will show you how to CopyElements using Revit API and python. There are 3 CopyElements methods to choose from and I have examples for all of them included!

Tags:  Revit API
Oct 2022

📄 RevitAPI Docs: CopyElements Methods

First of all let's have a look at the available methods in Revit API to copy elements.

Revit API has three methods to copy elements depending on how you want to copy.

Method: Description:
CopyElements(Document, ICollection ElementId , XYZ) Copies a set of elements and places the copies at a location indicated by a given translation.
CopyElements(Document, ICollection ElementId , Document, Transform, CopyPasteOptions) Copies a set of elements from source document to destination document.
CopyElements(View, ICollection ElementId , View, Transform, CopyPasteOptions) Copies a set of elements from source view to destination view.

CopyElements Methods

0️⃣ Prepare Elements to Copy

First of all let's prepare some base that will be used in all 3 examples, where we can get common variables.

You can see that we need to provide elements as ICollection[ElementId] for all the methods.
I will create List[ElementId] instead since it's similar data type. Below you can see an example where I get all walls in the view and create a List out of it.

code
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *

#⬇️ Imports .NET 
import clr
clr.AddReference('System')
from System.Collections.Generic import List

#📦 Variables
doc         = __revit__.Document
active_view = doc.ActiveView

#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc)\
                        .OfCategory(BuiltInCategory.OST_Walls)\
                        .WhereElementIsNotElementType()\
                        .ToElementIds()

#✅ Create List[ElementId]()
List_all_walls_view = List[ElementId](all_walls_view_ids)

__author__ = '🙋 Erik Frits'

1️⃣ Method A: Copy Elements with Vector

code
ElementTransformUtils.CopyElements(Document,
                     ICollection<ElementId>, 
                     XYZ)

Now Let's have a look at how to actually copy our elements. I will start with the simplest method: copy elements using a vector.

📐XYZ() Vector

We have everything prepared except for the vector. Creating vector is the same as defining a point. We need to use XYZ() class and provide x, y, z values to where we want to copy elements.

For Example, let's say I want to move my elements 50 feet on the X-Axis, 150 feet on the Y-Axis, and we won't change their Z-Axis.

code
vector = XYZ(50,150,0)

👆 This would be the vector that we need.

Let's combine the whole thing and make a script that will copy our walls with vector.

👇 Click to open

code
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *

#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List

#📦 Variables
doc     = __revit__.ActiveUIDocument.Document

#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc)\
                        .OfCategory(BuiltInCategory.OST_Walls)\
                        .WhereElementIsNotElementType()\
                        .ToElementIds()

#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_view_ids)

#📐 VECTOR
vector = XYZ(50,150,0)

#➕ Copy Elements
t = Transaction(doc, 'Copy Elements: A')
t.Start()
ElementTransformUtils.CopyElements(doc, elementsToCopy, vector)
t.Commit()

__author__ = '🙋 Erik Frits'

2️⃣ Method B: Copy Elements from View to View

code
CopyElements(View, ICollection<ElementId>, View, Transform, CopyPasteOptions)

The second method is used to copy Elements across different Revit Views including ViewSheet. This time we need to get source view, elements to copy, destination view(can be another project), Transform (change position or angle of selection), and CopyPasteOptions.


I will be getting random views in my Project, make sure to adjust to your needs!

👇 Click to open

code
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *

#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List

#📦 Variables
doc         = __revit__.ActiveUIDocument.Document
active_view = doc.ActiveView

#✅ Get Elements (I will just get all walls in View)
all_walls_view_ids = FilteredElementCollector(doc, active_view.Id)\
 .OfCategory(BuiltInCategory.OST_Walls)\
                        .WhereElementIsNotElementType()\
                        .ToElementIds()


#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_view_ids)

#🔎 GET ANOTHER VIEW
all_views = FilteredElementCollector(doc)\
              .OfCategory(BuiltInCategory.OST_Views)\
              .WhereElementIsNotElementType()\
              .ToElements()

random_floor_plan = [view for view in all_views if view.ViewType == ViewType.FloorPlan and view.Name =='Level 2'][0]

# Define Transform and CopyPasteOptions() 
transform    = Transform.Identity
opts         = CopyPasteOptions()


# COPY ELEMENTS BETWEEN VIEWS
t = Transaction(doc, 'Copy Elements: A')
t.Start()
ElementTransformUtils.CopyElements(active_view, 
                                elementsToCopy, 
                                random_floor_plan, 
                                transform, 
                                opts)
t.Commit()

#🥸 Report 
print("{} Elements copied from {} -> {}"\
      .format(len(elementsToCopy),
                active_view.Name,
                random_floor_plan.Name))

__author__ = '🙋 Erik Frits'
code
# -*- coding: utf-8 -*-
#⬇️ Imports
from Autodesk.Revit.DB import *

#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List

#📦 Variables
doc         = __revit__.ActiveUIDocument.Document

#✅ Get Elements (I will just get all lines in View)
all_lines = FilteredElementCollector(doc).OfClass(CurveElement).ToElementIds()

#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_lines)

#🔎 GET ALL SHEETS
all_sheet = FilteredElementCollector(doc)\
              .OfCategory(BuiltInCategory.OST_Sheets)\
              .WhereElementIsNotElementType()\
              .ToElements()


# Define Transform and CopyPasteOptions() 
transform    = Transform.Identity
opts         = CopyPasteOptions()


# COPY ELEMENTS BETWEEN VIEWS
t = Transaction(doc, 'Copy Elements: B.2')
t.Start()
ElementTransformUtils.CopyElements(all_sheet[0], 
                                elementsToCopy, 
                                all_sheet[1], 
                                transform, 
                                opts)
t.Commit()

#🥸 Report 
print("{} Elements copied from {} -> {}"\
      .format(len(elementsToCopy),
                all_sheet[0].SheetNumber,
                all_sheet[1].SheetNumber))

__author__ = '🙋 Erik Frits'

3️⃣ Method C: Copy Elements from Project to Project

Lastly, I am going to show you how to copy elements between projects. By now you should have a good understanding how to work with any of these method, but I will give you another example.

I am going to get all open projects and then take all walls from project A and copy them to project B.

👇 Click to open

code
# -*- coding: utf-8 -*-
#⬇️ Imports
import sys
from Autodesk.Revit.DB import *

#⬇️ Imports .NET
import clr
clr.AddReference('System')
from System.Collections.Generic import List

#📦 Variables
app         = __revit__.Application


#✌ GET ALL OPEN DOCUMENTS (Needed 2)
all_docs = list(app.Documents)

if len(all_docs) != 2:
    print('This will work only if you have exactly 2 projects open!')
    sys.exit()

doc_A = all_docs[0]
doc_B = all_docs[1]


#✅ Get Elements (I will just get all walls in View)
all_walls_A = FilteredElementCollector(doc_A)\
                        .OfCategory(BuiltInCategory.OST_Walls)\
                        .WhereElementIsNotElementType()\
                        .ToElementIds()

#✅ Create List[ElementId]()
elementsToCopy = List[ElementId](all_walls_A)

# Define Transform and CopyPasteOptions()
transform    = Transform.Identity
opts         = CopyPasteOptions()


# COPY ELEMENTS BETWEEN PROJECTS
t = Transaction(doc, 'Copy Elements C: Between Projects')
t.Start()
ElementTransformUtils.CopyElements(doc_A,
                                elementsToCopy,
                                doc_B,
                                transform,
                                opts)
t.Commit()

#🥸 Report
print("{} Elements copied from {} -> {}"\
      .format(len(elementsToCopy),
                doc_A.Title,
                doc_B.Title))

__author__ = '🙋 Erik Frits'

Conclusion

Copying elements is not that hard once you know what methods are available and how to use them. Whenever you will need to copy more, just reference this article again, and I am sure it will help you out multiple times!

⌨️ Happy Coding!

— Erik Frits