Here is my result with Dynamo 3.1 (.Net8)
I attach the dyn for test
compute_line_intersection_forum_DYN3_v0.2.dyn (33.4 KB)
Unfortunately, Tuneup is not currently available on dynamo3.
Here is my result with Dynamo 3.1 (.Net8)
I attach the dyn for test
compute_line_intersection_forum_DYN3_v0.2.dyn (33.4 KB)
Unfortunately, Tuneup is not currently available on dynamo3.
A little elf told me that this is something being reviewed already, but there is no eta at this time.
The dyn file is outdated a bit, could you upload last version, please?
need to open the file with Dynamo3 or more, if you open this dyn in Dynamo2.x the Ironpython3 node disappear (old dynamo bug)
finally someone helped me in a forum, with this masterpiece.
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)
tg.Assimilate()
(some module settings and it should also work in dynamo)