How to split horizontal a pipe/duct curve?

Hello,

i “dynofabricated” a script to python… it works well until the intersection, how can i split my curves by point?

my code so far

from Autodesk.Revit.UI.Selection import Selection, ObjectType

#VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc   = __revit__.ActiveUIDocument.Document
selection = uidoc.Selection #type: Selection

#functions
def tolist(x):
    if hasattr(x,'__iter__'): return x
    else: return [x]

#🔷 PickObject
ref_picked_object = selection.PickObject(ObjectType.Element)
picked_object = doc.GetElement(ref_picked_object)

# 🧱 get geometry
lstElemNetWork = tolist(picked_object)

lstDS_Geo = []
for e in lstElemNetWork:
    if isinstance(e.Location, LocationCurve):
        rvtCurve = e.Location.Curve
        lstDS_Geo.append(rvtCurve)
    else:
        locPt = e.Location.Point
        connSet = e.MEPModel.ConnectorManager.Connectors
        lstConn = list(connSet)
        if connSet.Size == 2:
            try:
                pline = DB.PolyLine.Create(List[XYZ]([lstConn[0].Origin, locPt, lstConn[1].Origin]))
                lstDS_Geo.append(pline)#ToProtoType())
            except:
                # Unable to create Line. Points are likely coincident
                line = DB.Line.CreateBound(lstConn[0].Origin, lstConn[1].Origin)
                lstDS_Geo.append(line)#ToProtoType())
        else:
            for con in connSet:
                line = DB.Line.CreateBound(locPt, con.Origin)
                lstDS_Geo.append(line)#ToProtoType())

print(lstDS_Geo)

# 🛒 all levels
collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()
# 🎣 BuildingStory
levels = [i for i in collector if i.get_Parameter(BuiltInParameter.LEVEL_IS_BUILDING_STORY).AsInteger() == 1]
# 🏢 elevation
elevations = [i.Elevation for i in levels]
# ⚾ points
points = [XYZ(0, 0, elev) for elev in elevations]
# 🏓 planes
planes = [Plane.CreateByNormalAndOrigin(XYZ.BasisZ, point) for point in points]

for p in planes:
    print(p)




https://www.parametriczoo.com/index.php/2020/03/07/plane-line-intersection-in-revit-api/ 

Hi, can you explain in more detail what is the problem you’re facing?

@Luffy11

i can’t split pipes by revit geometry, only dynamo!

hi @andreasd811 , try this node from DynaTools package. It also has a node for splitting the duct too.

and if you want to code it, here’s an example:

def splitPipeByPoint(pipe,pts):
    ele = []
    with Transaction(doc,'Break Curve') as t:
        t.Start()
        result = []
        for pt in pts:
            try:
                ele.append(DB.Plumbing.PlumbingUtils.BreakCurve(doc,pipe.Id,pt))
            except Exception as er:
                result.append(er)
        ele.append(pipe.Id)
        result = [doc.GetElement(Id) for Id in ele]
        t.Commit()
    return result
1 Like

@Luffy11 ,

there are severial notes for that, but the crusial point are the points.

i need the intersecting point! (XYZ)

that what you discribe is the next step! i need the step before

@andreasd811 but I see in your screenshot that you already got the intersection points through the Geometry.Intersect node. Are they not the points you need?

1 Like

hi @andreasd811 , I did it


Here’s the Dynamo graph for you to refer:

1 Like

@Luffy11

i have to say i want to do it without a dynamo script. i will use only python. i can’t use DesignScript “Protogeometry” in Python.

https://discourse.pyrevitlabs.io/uploads/db0866/original/2X/b/b721827551d0d5c22e0229032ffb3ea285379c9c.png

this what i have in python. lines and planes

oh, I see. Sorry for misunderstanding. I found a way to find the intersection point between line and plane in this post. Have you tried it?
Solved: Re: How can we calculate the intersection between the plane and the penetrating line? - Autodesk Community - Revit Products

1 Like

@Luffy11

a work-around would be to create the projected points, based on XY of the pipeCurve Startpoint. and Z i get from the planes(levels) elevations… first i will try to get the really real intersection.

i would say “phantom points” they are duct-taped by XY,Z :wink:

grafik

1 Like

That’s an amazing way to solve the problem. Simple yet effective.

@Luffy11

just in theory. so i can leverage my points by elevation, BUT finally in my transaction happend nothing! look at that (hilarious) code

# -*- coding: utf-8 -*-
__title__ = "Split"
__doc__ = """Date    = 29.12.2022
_____________________________________________________________________
Description:
Code  - Split pipes, ducts, AirSegments,...
_____________________________________________________________________
Author: """

# IMPORTS
#==================================================
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import XYZ
from Autodesk.Revit.DB.Architecture import Room
from Autodesk.Revit.UI.Selection import ObjectType, PickBoxStyle, Selection

#pyrevit
from pyrevit import forms



# .NET Imports
import clr
clr.AddReference("System")
from System.Collections.Generic import List
from Autodesk.Revit.UI.Selection import Selection, ObjectType



#VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc   = __revit__.ActiveUIDocument.Document
selection = uidoc.Selection #type: Selection

#functions
def tolist(x):
    if hasattr(x,'__iter__'): return x
    else: return [x]

#🔷 PickObject
ref_picked_object = selection.PickObject(ObjectType.Element)
picked_object = doc.GetElement(ref_picked_object)

# 🧱 get geometry
lstElemNetWork = tolist(picked_object)

lstDS_Geo = []
lstDS_point = []
for e in lstElemNetWork:
	if isinstance(e.Location, LocationCurve):
		rvtCurve = e.Location.Curve
		lstDS_Geo.append(rvtCurve)
		lstDS_point.append(e.Location.Curve.GetEndPoint(0))
	else:
		locPt = e.Location.Point
		connSet = e.MEPModel.ConnectorManager.Connectors
		lstConn = list(connSet)
		if connSet.Size == 2:
			try:
				pline = DB.PolyLine.Create(List[XYZ]([lstConn[0].Origin, locPt, lstConn[1].Origin]))
				lstDS_Geo.append(pline)#ToProtoType())
			except:
				# Unable to create Line. Points are likely coincident
				line = DB.Line.CreateBound(lstConn[0].Origin, lstConn[1].Origin)
				lstDS_Geo.append(line)#ToProtoType())
		else:
			for con in connSet:
				line = DB.Line.CreateBound(locPt, con.Origin)
				lstDS_Geo.append(line)#ToProtoType())



# 🛒 all levels
collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()
# 🎣 BuildingStory
levels = [i for i in collector if i.get_Parameter(BuiltInParameter.LEVEL_IS_BUILDING_STORY).AsInteger() == 1]
# 🏢 elevation
elevations = [i.Elevation for i in levels]
# ⚾ points to split
points = [XYZ(lstDS_point[0].X, lstDS_point[0].Y, elev) for elev in elevations]

elements = picked_object if isinstance(picked_object, list) else [picked_object]


parents, childs, fittings = [], [], []
children = {}


def colCurve(col):
	loc = col.Location.Point
	bb = col.get_BoundingBox(None).Min
	height = col.get_Parameter(BuiltInParameter.INSTANCE_LENGTH_PARAM).AsDouble()
	start = XYZ(loc.X, loc.Y, bb.Z)
	end = XYZ(start.X, start.Y, start.Z + height)
	curve = Line.CreateBound(start, end)
	return curve


def pointOnLine(p, a, b):
	if not (p - a).CrossProduct(b - a).IsAlmostEqualTo(XYZ.Zero):
		return False
	if a.X != b.X:
		if a.X < p.X < b.X:
			return True
		if a.X > p.X > b.X:
			return True
	else:
		if a.Y < p.Y < b.Y:
			return True
		if a.Y > p.Y > b.Y:
			return True
	return False


def splitWall(ec, p):
	lc = ec.Location.Curve
	v0 = lc.GetEndPoint(0)
	v1 = lc.GetEndPoint(1)
	isOnLine = False
	if pointOnLine(p, v0, v1):
		isOnLine = True
	if isOnLine:
		join_1 = WallUtils.IsWallJoinAllowedAtEnd(ec, 1)
		WallUtils.DisallowWallJoinAtEnd(ec, 1)
		e1Id = ElementTransformUtils.CopyElement(doc, ec.Id, XYZ.Zero)[0]
		e1 = doc.GetElement(e1Id)
		WallUtils.DisallowWallJoinAtEnd(e1, 0)
		nc0 = DB.Line.CreateBound(v0, p)
		nc1 = DB.Line.CreateBound(v1, p)
		ec.Location.Curve = nc0
		e1.Location.Curve = nc1
		if join_1:
			WallUtils.DisallowWallJoinAtEnd(e1, 0)
		WallUtils.AllowWallJoinAtEnd(ec, 1)
		WallUtils.AllowWallJoinAtEnd(e1, 0)
	return e1Id


t = Transaction(doc,"Split")
t.Start()
for e, p in zip(elements, points):
	to_check = [e]
	if e.Id in children:
		to_check.extend(children[e.Id])

	splitId = None
	for ec in to_check:
		if isinstance(ec, DB.Plumbing.Pipe):
			try:
				splitId = DB.Plumbing.PlumbingUtils.BreakCurve(doc, ec.Id, p)
				break
			except:
				pass
		elif isinstance(ec, DB.Mechanical.Duct):
			try:
				splitId = DB.Mechanical.MechanicalUtils.BreakCurve(doc, ec.Id, p)
				break
			except:
				import traceback
				print(traceback.format_exc())

		elif isinstance(ec, DB.FamilyInstance) and ec.CanSplit:
			try:
				if ec.Location.ToString() == 'Autodesk.Revit.DB.LocationCurve':
					curvB = ec.Location.Curve
				elif ElementId(BuiltInCategory.OST_StructuralColumns) == ec.Category.Id and not ec.IsSlantedColumn:
					curvB = colCurve(ec)
				lenBeam = curvB.Length
				param = (curvB.GetEndPoint(0).DistanceTo(p)) / lenBeam
				splitId = ec.Split(param)
				break
			except:
				import traceback
				print(traceback.format_exc())

		elif isinstance(ec, DB.Wall):
			try:
				splitId = splitWall(ec, p)
				break
			except:
				import traceback
				print(traceback.format_exc())

	if splitId:
		split = doc.GetElement(splitId)
		if hasattr(split, "ConnectorManager"):
			newPipeConnectors = split.ConnectorManager.Connectors
			# Check
			connA = None
			connB = None
			for c in ec.ConnectorManager.Connectors:
				pc = c.Origin
				# get connectorB near to connectorA
				nearest = [x for x in newPipeConnectors if pc.DistanceTo(x.Origin) < 0.01]
				# If exists assign
				if nearest:
					connA = c
					connB = nearest[0]
			# Create fitting
			try:
				fittings.append(doc.Create.NewUnionFitting(connA, connB))
			except:
				import traceback
				print(traceback.format_exc())

		if e.Id in children:
			children[e.Id].append(split)
		else:
			children[e.Id] = [split]
		parents.append(ec)
		childs.append(split)
	else:
		parents.append(None)
		childs.append(None)
t.Commit()

the code runs without error, i got no traceback …

hi @andreasd811
Have you tried outputting the results of each function to see where the error starts? In my opinion, you should separate them into individual functions to make it easier to manage and debug when there are errors. This is my approach, and I hope it can help.

def splitPipeByPoint(pipe,pts):
    ele = []
    with Transaction(doc,'Break Curve') as t:
        t.Start()
        result = []
        for pt in pts:
            try:
                ele.append(DB.Plumbing.PlumbingUtils.BreakCurve(doc,pipe.Id,pt))
            except Exception as er:
                result.append(er)
        ele.append(pipe.Id)
        result = [doc.GetElement(Id) for Id in ele]
        t.Commit()
    return result

def closestConnectors(ele1, ele2):
	conn1 = ele1.ConnectorManager.Connectors
	conn2 = ele2.ConnectorManager.Connectors
	
	dist = 100000000
	connset = None
	for c in conn1:
		for d in conn2:
			conndist = c.Origin.DistanceTo(d.Origin)
			if conndist < dist:
				dist = conndist
				connset = [c,d]
	return connset

def createUnionFitting(ele1,ele2):
    connectors = closestConnectors(ele1,ele2)
    result = []
    with Transaction(doc,'Create Union Fitting') as t:
        t.Start()
        try:
            result.append(doc.Create.NewUnionFitting(connectors[0],connectors[1]))
        except Exception as er:
            result.append(er)
        t.Commit()
    return result

with TransactionGroup(doc,'Split Pipe by Length') as tg:
    tg.Start()

    newEles = []
    newEles2 = []
    for pipe,sub_lst in zip(validPipe,pts):
        newEles = splitPipeByPoint(pipe,sub_lst)
        newEles2 = newEles[1:]

        for ele1,ele2 in zip(newEles,newEles2):
            createUnionFitting(ele1,ele2)

    print ('Done')
    tg.Assimilate()

And one more thing to note is that the direction of the pipeline will also affect your tool. If your pipe is drawn from bottom to top, after splitting, the original pipe will be at the top; conversely, the original pipe will be at the bottom. Therefore, you can see in the Dynamo graph that I arranged the points according to the direction of the pipeline.

1 Like

@Luffy11

i can`t find the right way… even in the dynamo forum, is difficult to get


# -*- coding: utf-8 -*-
__title__ = "Split"
__doc__ = """Date    = 29.12.2022
_____________________________________________________________________
Description:
Code from lesson 03.05 - Rename Views
Tutorial on using selection and modifying properties.
_____________________________________________________________________
Author: """

# IMPORTS
#==================================================
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import XYZ
from Autodesk.Revit.DB.Architecture import Room
from Autodesk.Revit.UI.Selection import ObjectType, PickBoxStyle, Selection
from Autodesk.Revit.UI import UIDocument


#pyrevit
from pyrevit import forms



# .NET Imports
import clr
clr.AddReference("System")
from System.Collections.Generic import List



#VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc   = __revit__.ActiveUIDocument.Document
selection = uidoc.Selection #type: Selection

#functions
def tolist(x):
    if hasattr(x,'__iter__'): return x
    else: return [x]

#🔷 PickElemnetsbyRectangle
selected_elements = selection.PickElementsByRectangle('get MEP Segment')



# 🧱 get geometry
lstElemNetWork = tolist(selected_elements)

lstDS_Geo = []
lstDS_point = []
for e in lstElemNetWork:
	if isinstance(e.Location, LocationCurve):
		rvtCurve = e.Location.Curve
		lstDS_Geo.append(rvtCurve)
		lstDS_point.append(e.Location.Curve.GetEndPoint(0))
	else:
		locPt = e.Location.Point
		connSet = e.MEPModel.ConnectorManager.Connectors
		lstConn = list(connSet)
		if connSet.Size == 2:
			try:
				pline = DB.PolyLine.Create(List[XYZ]([lstConn[0].Origin, locPt, lstConn[1].Origin]))
				lstDS_Geo.append(pline)
			except:
				# Unable to create Line. Points are likely coincident
				line = DB.Line.CreateBound(lstConn[0].Origin, lstConn[1].Origin)
				lstDS_Geo.append(line)
		else:
			for con in connSet:
				line = DB.Line.CreateBound(locPt, con.Origin)
				lstDS_Geo.append(line)


# 🛒 all levels
collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()

# 🎣 BuildingStory
levels = [i for i in collector if i.get_Parameter(BuiltInParameter.LEVEL_IS_BUILDING_STORY).AsInteger() == 1]

# 🏢 elevation
elevations = [i.Elevation for i in levels]

# ⚾ points to split
points = [XYZ(lstDS_point[0].X, lstDS_point[0].Y, elev) for elev in elevations]

# 🏓 planes
planes = [Plane.CreateByNormalAndOrigin(XYZ.BasisZ, point) for point in points]

elements = selected_elements  if isinstance(selected_elements , list) else [selected_elements ]


def splitPipeByPoint(pipe, pts):
    ele = []
    with Transaction(doc, 'Break Curve') as t:
        t.Start()
        result = []
        for pt in pts:
            try:
                ele.append(DB.Plumbing.PlumbingUtils.BreakCurve(doc, pipe.Id, pt))
            except Exception as er:
                result.append(er)
        ele.append(pipe.Id)
        result = [doc.GetElement(Id) for Id in ele]
        t.Commit()
    return result


def closestConnectors(ele1, ele2):
    conn1 = ele1.ConnectorManager.Connectors
    conn2 = ele2.ConnectorManager.Connectors

    dist = 100000000
    connset = None
    for c in conn1:
        for d in conn2:
            conndist = c.Origin.DistanceTo(d.Origin)
            if conndist < dist:
                dist = conndist
                connset = [c, d]
    return connset


def createUnionFitting(ele1, ele2):
    connectors = closestConnectors(ele1, ele2)
    result = []
    with Transaction(doc, 'Create Union Fitting') as t:
        t.Start()
        try:
            result.append(doc.Create.NewUnionFitting(connectors[0], connectors[1]))
        except Exception as er:
            result.append(er)
        t.Commit()
    return result

# 🔓🔒🔑 split by length
with TransactionGroup(doc, 'Split Pipe by Length') as tg:
    tg.Start()

    newEles = []
    newEles2 = []
    for pipe, sub_lst in zip(selected_elements, points):
        newEles = splitPipeByPoint(pipe, sub_lst)
        newEles2 = newEles[1:]

        for ele1, ele2 in zip(newEles, newEles2):
            createUnionFitting(ele1, ele2)

    print('Done')
    tg.Assimilate()



i switched to rectangular selection. i want to reduce it just to split one pipe or(and) duct. any component that creats a vertical curve(line)

@andreasd811 ,
from what I understand, you want to split the vertical duct/pipe at points where the levels intersect with them? If so, I will try to dig into it when I have freetime (maybe in the weekend) and will let you know my result.

1 Like

@Luffy11

yes

without using dynamo

Hi @andreasd811 . I did it. Here are the code and the revit file (version 2022) for you to test


import clr 
import math
from pyrevit import revit,forms,script

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitAPIUI')
from  Autodesk.Revit.UI import*
from  Autodesk.Revit.UI.Selection import*


doc = __revit__.ActiveUIDocument.Document
view = doc.ActiveView
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
DB = Autodesk.Revit.DB
output = script.get_output()
unit = doc.GetUnits()
selection = uidoc.Selection
#-------------------------------------------------------------------------------
class SelectionFilter(ISelectionFilter):
    def __init__(self, categories):
        self.categories = categories

    def AllowElement(self, element):
        if element.Category.Name in self.categories:
            return True
        return False

    def AllowReference(self, reference, point):
        return False
        
def ToLst(ele):
    if isinstance(ele,list):
        return ele
    else:
        return [ele]

def Flatten_lv3 (lst):
    return [i for sub_lst in lst for i in sub_lst]

def AllElementsOfCategoryInView(categories):
	categories = ToLst(categories)
	allcates = doc.Settings.Categories
	valid_cate = []
	alleles = []
	for cate in allcates:
		for category in categories:
			if cate.Name == category:
				valid_cate.append(cate)

	for cate in valid_cate:
		alleles.append(FilteredElementCollector(doc,view.Id).OfCategoryId(cate.Id).WhereElementIsNotElementType().ToElements())

	return Flatten_lv3(alleles)

def IntersectionPlaneAndLine(plane,line):
    planePoint = plane.Origin
    planeNormal = plane.Normal
    lineStart = line.GetEndPoint(0)
    lineEnd = line.GetEndPoint(1)
    lineDirection = (lineEnd - lineStart).Normalize()

    # Check if the line is parallel to the plane
    # If yes, return None
    if planeNormal.DotProduct(lineDirection) == 0:
        return None
    
    lineParameter = (planeNormal.DotProduct(planePoint) - planeNormal.DotProduct(lineStart)) / planeNormal.DotProduct(lineDirection)

    return lineStart + lineParameter * lineDirection

def IsPointOnLine(point,line):
    # If a point C is on a line, it will be between start point(A) and end point(B) of a line
    # AB = AC + CB
    lineStart = line.GetEndPoint(0)
    lineEnd = line.GetEndPoint(1)
    lineLength = lineStart.DistanceTo(lineEnd)
    startToPoint = lineStart.DistanceTo(point)
    pointToEnd = point.DistanceTo(lineEnd)

    if lineLength == startToPoint + pointToEnd:
        return True
    else:
        return False

def GetZCoordinate(point):
    return point.Z

def SortPointByElevation(points):
    return sorted(points, key=GetZCoordinate)

def SortPointByLineDirection(line,lstPoint):
    direction = line.Direction
    vectorZ = direction.Z
    sortedPoints = SortPointByElevation(lstPoint)
    if vectorZ > 0:
        return sortedPoints
    else:
        return list(reversed(sortedPoints))

def SplitPipeByPoint(pipe,pts):
    ele = []
    with Transaction(doc,'Break Curve') as t:
        t.Start()
        result = []
        for pt in pts:
            try:
                ele.append(DB.Plumbing.PlumbingUtils.BreakCurve(doc,pipe.Id,pt))
            except Exception as er:
                result.append(er)
        ele.append(pipe.Id)
        result = [doc.GetElement(Id) for Id in ele]
        t.Commit()
    return result

def SplitDuctByPoint(duct,pts):
    ele = []
    result = []
    with Transaction(doc,'Break Curve') as t:
        t.Start()
        for pt in pts:
            try:
                ele.append(DB.Mechanical.MechanicalUtils.BreakCurve(doc,duct.Id,pt))
            except Exception as er:
                result.append(er)
        ele.append(duct.Id)
        result = [doc.GetElement(Id) for Id in ele]
        t.Commit()
    return result

def ClosestConnectors(ele1, ele2):
	conn1 = ele1.ConnectorManager.Connectors
	conn2 = ele2.ConnectorManager.Connectors
	
	dist = 100000000
	connset = None
	for c in conn1:
		for d in conn2:
			conndist = c.Origin.DistanceTo(d.Origin)
			if conndist < dist:
				dist = conndist
				connset = [c,d]
	return connset

def CreateUnionFitting(ele1,ele2):
    connectors = ClosestConnectors(ele1,ele2)
    result = []
    with Transaction(doc,'Create Union Fitting') as t:
        t.Start()
        try:
            result.append(doc.Create.NewUnionFitting(connectors[0],connectors[1]))
        except Exception as er:
            result.append(er)
        t.Commit()
    return result

#----------------------------Main Logic-----------------------------------------
# Select duct and pipe
filterEle = SelectionFilter(["Ducts","Pipes"])
refEle = selection.PickObjects(ObjectType.Element, filterEle, "Select Model Elements")
selectedEle = []
for sublst in refEle:
    selectedEle.append(doc.GetElement(sublst))


eleLine = []
for ele in selectedEle:
    line = ele.Location.Curve
    eleLine.append(line)

# Get all levels in view
allLevels = AllElementsOfCategoryInView("Levels")
levelElevations = [level.Elevation for level in allLevels]

# Create planes from levels
planeLst = []
z_axis = XYZ(0,0,1)
for elevation in levelElevations:
    plane = Plane.CreateByNormalAndOrigin(z_axis,XYZ(0,0,elevation))
    planeLst.append(plane)

# Get intersection points between line and plane
intersectionPoint = []
for line in eleLine:
    sublst = []
    for plane in planeLst:
        point = IntersectionPlaneAndLine(plane,line)
        if IsPointOnLine(point,line):
            sublst.append(point)
    intersectionPoint.append(SortPointByLineDirection(line,sublst))


#----------------------------------Split Vertical Segment-----------------------------------------------------------------
with TransactionGroup(doc,'Split Vertical Segment') as tg:
    tg.Start()

    newEles = []
    newEles2 = []
    for ele,sub_lst in zip(selectedEle,intersectionPoint):
        if isinstance(ele,Autodesk.Revit.DB.Plumbing.Pipe):
            newEles = SplitPipeByPoint(ele,sub_lst)
            newEles2 = newEles[1:]
        else:
            newEles = SplitDuctByPoint(ele,sub_lst)
            newEles2 = newEles[1:]

        for ele1,ele2 in zip(newEles,newEles2):
            CreateUnionFitting(ele1,ele2)

    print ('Done')
    tg.Assimilate()
1 Like

@Luffy11

so i tested. i could not download the file. I tested ducts and pipes.

i had to change the selection pick object

the script runs without splits at all. ;(

Thank you…

@andreasd811 that’s weird because it still works with me. Can you give me your revit file?

1 Like

@Luffy11 ,

i think it is not view specific(?). it just pipes and ducts

https://www.dropbox.com/scl/fi/ku0uli20rs2kfv8xsyppe/demo.rvt?rlkey=rq25lth68vd11sdmc5ifljrb1&st=rpr6jvxp&dl=0