Jul 2, 2024

How to Cut a Pipe/Duct in half with Revit API/

Let me show you how to cut a Pipe/Duct in half with Revit API. You will need to use BreakCurve method.

How to Cut Pipe/Duct in half?

If you want to split your pipes or ducts then you need the following methods:

These methods need 3 arguments:

  • doc

  • ElementId of Pipe/Duct

  • Point where to spit

Also keep in mind that these methods will return an ElementId of a new pipe/duct segment, or None if it failed.

Prepare a button

Let's begin by creating a pyRevit button and adding a code to select a Pipe/Duct.

# -*- coding: utf-8 -*-
__title__   = "Split Pipe/Duct"
  
#⬇️ IMPORTS
#==================================================
from Autodesk.Revit.DB              import *
from Autodesk.Revit.UI.Selection    import ObjectType, ISelectionFilter
from Autodesk.Revit.DB.Mechanical   import Duct, MechanicalUtils
from Autodesk.Revit.DB.Plumbing     import Pipe, PlumbingUtils
  
  #📦 VARIABLES
#==================================================
uidoc  = __revit__.ActiveUIDocument
doc    = __revit__.ActiveUIDocument.Document #type:Document

#🎯 MAIN
#==================================================
#✨ Limit Selection to Pipe/Ducts
class ISF_Pipe_Duct(ISelectionFilter):
    def AllowElement(self, element):
        if type(element) in [Pipe, Duct]:
            return True

#👉 Select Pipe/Ducts
ref_pipe_ducts = uidoc.Selection.PickObjects(ObjectType.Element, ISF_Pipe_Duct())
pipe_ducts     = [doc.GetElement(ref) for ref in ref_pipe_ducts]

This Code Snippet should return us a list of Pipes/Ducts together.

Get Middle Point

Now we need to think of where we want to cut our Pipes/Ducts. In my case, I will grab the middle point.

To calculate the middle point we would need to get the elem.Location.Curve and then by getting pt_start and pt_end we can calculate the middle point.

# Iterate through Pipes/Ducts
for elem in pipe_ducts:
    #📏 Get Middle Point
    crv       = elem.Location.Curve
    pt_start  = crv.GetEndPoint(0)
    pt_end    = crv.GetEndPoint(1)
    pt_middle = (pt_start + pt_end)/2

Split Pipe/Duct in Half with BreakCurve

Now we can cut it in half. But keep in mind that there are separate methods for Pipes and Cuts. So we have to make a check and then use PlumbingUtils or MechanicalUtils accordingly.

Here is a snippet and don't forget the Transaction.

# Start Transaction for changes.
t = Transaction(doc,'Split Pipe/Duct')
t.Start()   #🔓

#️✂️️ Cut Pipe/Duct
if type(elem) == Pipe:
   new_elem_id = PlumbingUtils.BreakCurve(doc, elem.Id, pt_middle)

elif type(elem) == Duct:
    new_elem_id = MechanicalUtils.BreakCurve(doc, elem.Id, pt_middle)


if new_elem_id:
    new_elem = doc.GetElement(new_elem_id)
    print(new_elem)

t.Commit()  #🔒

✨Final Code Snippet

Here is the complete code to avoid any confusion..

# -*- coding: utf-8 -*-
__title__   = "Split Pipe/Duct"

#⬇️ IMPORTS
#==================================================
from Autodesk.Revit.DB              import *
from Autodesk.Revit.UI.Selection    import ObjectType, ISelectionFilter
from Autodesk.Revit.DB.Mechanical   import Duct, MechanicalUtils
from Autodesk.Revit.DB.Plumbing     import Pipe, PlumbingUtils

#📦 VARIABLES
#==================================================
uidoc  = __revit__.ActiveUIDocument
doc    = __revit__.ActiveUIDocument.Document #type:Document

#🎯 MAIN
#==================================================
#✨ Limit Selection to Pipe/Ducts
class ISF_Pipe_Duct(ISelectionFilter):
    def AllowElement(self, element):
        if type(element) in [Pipe, Duct]:
            return True

#👉 Select Pipe/Ducts
ref_pipe_ducts = uidoc.Selection.PickObjects(ObjectType.Element, ISF_Pipe_Duct())
pipe_ducts     = [doc.GetElement(ref) for ref in ref_pipe_ducts]

# Iterate through Pipes/Ducts
for elem in pipe_ducts:
    try:
        #📏 Get Middle Point
        crv       = elem.Location.Curve
        pt_start  = crv.GetEndPoint(0)
        pt_end    = crv.GetEndPoint(1)
        pt_middle = (pt_start + pt_end)/2

        # Start Transaction for changes.
        t = Transaction(doc,'Split Pipe/Duct')
        t.Start()   #🔓

        #️✂️️ Cut Pipe/Duct
        if type(elem) == Pipe:
           new_elem_id = PlumbingUtils.BreakCurve(doc, elem.Id, pt_middle)

        elif type(elem) == Duct:
            new_elem_id = MechanicalUtils.BreakCurve(doc, elem.Id, pt_middle)


        if new_elem_id:
            new_elem = doc.GetElement(new_elem_id)
            print(new_elem)

        t.Commit()  #🔒

    except Exception as e:
        print('⚠️Error with ElementId({}): {}'.format(elem.Id,e))

Want to Learn More?

🔥 Amazing Revit API Resources!

Join Revit API

Newsletter Today!

Join Us!

which is already read by 5500+ people!

Get short Revit API Lessons and Tips directly in your mail!