I used the Python Script by @viktor_kuzev from the topic (Group closest parallel lines which are equal in length) and it worked out well for majority of the lines.
But a few lines [orange and violet] although parallel (to the eye) are not being grouped appropriately.
I tried changing the code to check if reversing the direction would work but it didn’t.
What would you suggest I should try next?
Test_Revit2019.rvt (2.2 MB)
hello @AmolShah
try this
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
import random
def nearCond(lstelemb, elema):
check = False
midpta = elema.Location.Curve.Evaluate(0.5, True)
for elemb in lstelemb:
midptb = elemb.Location.Curve.Evaluate(0.5, True)
if midpta.DistanceTo(midptb) < margin:
check = True
break
return check
def colorRamdom(elements, view):
TransactionManager.Instance.EnsureInTransaction(doc)
rvtcolor = Color(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
gSettings = OverrideGraphicSettings()
gSettings.SetProjectionFillColor(rvtcolor)
gSettings.SetProjectionLineColor(rvtcolor)
gSettings.SetCutLineColor(rvtcolor)
gSettings.SetCutFillColor(rvtcolor)
for element in elements:
view.SetElementOverrides(element.Id, gSettings)
TransactionManager.Instance.TransactionTaskDone()
margin = IN[0] #test at 0.5
collCond = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Conduit).WhereElementIsNotElementType().ToElements()
finalgroups = []
filterPassId = []
for conda in collCond:
if conda.Id not in filterPassId:
filterPassId.append(conda.Id)
vecta = conda.Location.Curve.Direction
templst = [conda]
for condb in collCond:
if conda.Id != condb.Id:
vectb = condb.Location.Curve.Direction
if vecta.IsAlmostEqualTo(vectb, 0.15) or vecta.IsAlmostEqualTo(vectb.Negate(), 0.15) :
if nearCond(templst, condb):
templst.append(condb)
filterPassId.append(condb.Id)
finalgroups.append(templst)
colorRamdom(templst, doc.ActiveView)
OUT = finalgroups
you can delete the colorRamdom function if you don’t use it
3 Likes
Hi @c.poupin,
Thank you so much for taking time to help me solve this problem.
It works perfectly as intended on the file I shared.
However, it threw some unexpected results when I tested it on the other file shared below!
Test_Revit2019_2.rvt (2.4 MB)
corrected script
the margin is the max margin between conduits
#written by Cyril.P
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
import random
def nearCond(lstelemb, elema):
global margin
check = False
curva = elema.Location.Curve
midpta = elema.Location.Curve.Evaluate(0.5, True)
for elemb in lstelemb:
curvb = elemb.Location.Curve
if curvb.Project(midpta).Distance < margin:
check = True
break
return check
def getConduitParallal(collCond, conda):
outLst = []
curva = conda.Location.Curve
vecta = conda.Location.Curve.Direction
midptfun = lambda x : x.Location.Curve.Evaluate(0.5, True)
midpta = midptfun(conda)
for condb in collCond:
if conda.Id != condb.Id :
vectb = condb.Location.Curve.Direction
if vecta.IsAlmostEqualTo(vectb, 0.15) or vecta.IsAlmostEqualTo(vectb.Negate(), 0.15) :
outLst.append(condb)
if outLst:
#sort element by distance
outLst.sort(key = lambda x : curva.Project(midptfun(x)).Distance )
return outLst
def colorRamdom(elements, view):
TransactionManager.Instance.EnsureInTransaction(doc)
rvtcolor = Color(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
gSettings = OverrideGraphicSettings()
gSettings.SetProjectionFillColor(rvtcolor)
gSettings.SetProjectionLineColor(rvtcolor)
gSettings.SetCutLineColor(rvtcolor)
gSettings.SetCutFillColor(rvtcolor)
for element in elements:
view.SetElementOverrides(element.Id, gSettings)
TransactionManager.Instance.TransactionTaskDone()
margin = IN[0] #max margin between conduits
collCond = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Conduit).WhereElementIsNotElementType().ToElements()
finalgroups = []
filterPassId = []
for conda in collCond:
if conda.Id not in filterPassId:
filterPassId.append(conda.Id)
vecta = conda.Location.Curve.Direction
templst = [conda]
elemsParall = getConduitParallal(collCond, conda)
for condb in elemsParall:
if nearCond(templst, condb):
templst.append(condb)
filterPassId.append(condb.Id)
finalgroups.append(templst)
colorRamdom(templst, doc.ActiveView)
OUT = finalgroups
2 Likes
Works like a charm.
Thank you 