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

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.