Oct 20, 2022

Copy Elements with RevitAPI + 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!

📄 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.

NB! All these methods come from ElementTransformUtils class.


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 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.

# -*- 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

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.

Here is the syntax.

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

It just means we need to define X,Y,Z coordinates of how we want to move elements.

📐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.

💡Keep in mind that Revit API uses feet as internal units.

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.

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.

# -*- 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

Now let's copy elements between Views, here is the syntax:

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

💡 Bonus: We can also take views from 2 different projects and copy between them!

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!

2️⃣🅰️Copy Elements between Views

# -*- 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()

#👇 Adjust to your needs.
random_floor_plan = [view for view in all_views if view.ViewType == ViewType.FloorPlan][0]

# Define Transform and CopyPasteOptions() 
transform    = Transform.Identity # We can change position and rotation with Transform
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'

2️⃣🅱️Copy Elements between Sheets

We use the same logic for copying elements between Sheets.

# -*- 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.

# -*- 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 elements, just reference this article again, and I am sure it will help you out multiple times!

Join Newsletter

📩 You will be added to Revit API Newsletter

Join Us!

which is already read by 7400+ people!

Ready to become Revit Hero for your office? Learn Revit API!

Join this comprehensive course that will guide you step by step on how to create your dream tools for Revit that save time.