@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 …