Clash Detection

Dear all,

Lately i been enhancing the workflow that i shared before.

Last time i faced an issue to do the clash detection within Revit using dynamo due to running time, but thanks to BimorohNodes that they enhanced the process of intersection method between elements. below i will share with you the process of clash detecting scriPt. The script is enable you to detect the clashes between host model and linked models or host model elements.

What you need:
1- Dynamo. 1.3.
Packages:
MEPover.
Data-Shapes.
BimorphNodes.
RevitPythonWrapper.
Visual Style Select.

2- Revit 2016 – 2018.

Dynamo Script.

Part-1: Read the linked models and make selection form, so the user pick which model to run versus the host model. We will add ability also to run the clash detection for the elements in the host model only. Check the figure below.
Tip. Make sure to keep the Run model of the dynamo as manual.

Part-2: Collect host model elements. Check figure below.

Python code for the needed Nodes:

Library importing:

import clr
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
import os

appdata_path = os.getenv('appdata')
dynamo_path = os.path.join(appdata_path, 'Dynamo')

module_path = None
for root, subfolders, files in os.walk(dynamo_path):
    if 'RevitPythonWrapper' in subfolders:
        extra_path = os.path.join(root, 'RevitPythonWrapper', 'extra')
        module_path = os.path.join(extra_path, 'rpw.zip')

OUT = module_path  or 'Could Not Find Module. Make sure it\'s installed properly'

Collect elements in model:

x = IN[1]
import sys
sys.path.append(IN[0])

import rpw

l = []
for i in x:
    try:
        col = rpw.db.Collector(of_category= i, is_not_type=True)
        s = col.elements
        l.append(s)
    except:
        pass
        
OUT = l

Part-3: Collect the elements from the picked model. Check figure below.

Python code for the needed Nodes:

Collect Elements:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

import System

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN

_linkDoc = IN[0]
_category = IN[1]
result = []
for i in _category:
    try:
        errorReport = None
        filter = ElementCategoryFilter(System.Enum.ToObject(BuiltInCategory, i.Id))
        result.append(FilteredElementCollector(_linkDoc).WherePasses(filter).WhereElementIsNotElementType().ToElements())
    except:
        pass
        # if error accurs anywhere in the process catch it
        #import traceback
        #errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
    OUT = result
else:
    OUT = errorReport

Part-4: Get previous parts together . Notice I added if statement to check which model you will pick (Linked models or host model). Check figures below.

Python code for the needed Nodes:

If Statement:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN

cond = IN[0]
x = IN[1]
y = IN[2]

#Assign your output to the OUT variable.
o = []
if cond:    
    OUT = y
else:
    OUT = x

Part-5: Check the intersection between the elements to detect the clashes. Check figure below.

Part-6: Create 3D view for each element. Check figures below.

Python code for the needed Nodes:
Create Views:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import *

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN

d = []
v = IN[1]
s = 0
for k in IN[0]:
    elements = []
    for i in k:
        elements.append(UnwrapElement(i))
    elements.append(UnwrapElement(k))
    viewName = v[s]
    offset = float(IN[2])
    s = 1+s
    #get ViewFamilyType for a 3D View
    collector = FilteredElementCollector(doc)
    viewTypeColl = collector.OfClass(ViewFamilyType)
    for i in viewTypeColl:
        if i.ViewFamily == ViewFamily.ThreeDimensional:
            viewType = i
        else:
            continue
    # "Start" the transaction
    TransactionManager.Instance.EnsureInTransaction(doc)
    
    #define bounding box enclosing all elements
    bboxMin, bboxMax = [], []
    i = elements[0]
    bboxMin.append(i.get_BoundingBox(doc.ActiveView).Min)
    bboxMax.append(i.get_BoundingBox(doc.ActiveView).Max)
    minX, minY, minZ, maxX, maxY, maxZ = [], [], [], [], [], []
    for i, j in zip(bboxMin, bboxMax):
        minX.append(i.X)
        minY.append(i.Y)
        minZ.append(i.Z)
        maxX.append(j.X)
        maxY.append(j.Y)
        maxZ.append(j.Z)
    bboxMinX = min(minX)
    bboxMinY = min(minY)
    bboxMinZ = min(minZ)
    bboxMaxX = max(maxX)
    bboxMaxY = max(maxY)
    bboxMaxZ = max(maxZ)
    #create a bounding box
    bbox = BoundingBoxXYZ()
    bbox.Min = XYZ((bboxMinX - offset), (bboxMinY - offset), (bboxMinZ - offset))
    bbox.Max = XYZ((bboxMaxX + offset), (bboxMaxY + offset), (bboxMaxZ + offset))
    #create 3d View
    view = View3D.CreateIsometric(doc, viewType.Id)
    d.append(view)
    view.Name = viewName
    view.SetSectionBox(bbox)

# "End" the transaction
TransactionManager.Instance.TransactionTaskDone()

#Assign your output to the OUT variable
OUT = d

Part-7 Make the 3D-View in Revit as shaded. Check figures below.

Part-8: Color the element in the 3D-view. Check figures below.

Python code for the needed Nodes:

Override:

import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import *


doc = DocumentManager.Instance.CurrentDBDocument

def overridecolor(element, color, fillpatternid, view):
    gSettings = OverrideGraphicSettings()
    gSettings.SetProjectionFillColor(color)
    gSettings.SetProjectionFillPatternId(fillpatternid)
    gSettings.SetCutFillColor(color)
    gSettings.SetCutFillPatternId(fillpatternid)
    view.SetElementOverrides(element.Id, gSettings)
    return element

fillpatterns = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
solidfillid = [f.Id for f in fillpatterns if f.Name == 'Solid fill'][0]

for j in IN[1]:
    for i in IN[2]:
        
        if isinstance(IN[0],list):
            color = UnwrapElement(IN[0])
        else:
            color = [UnwrapElement(IN[0])]
        
        adskcolor = [Autodesk.Revit.DB.Color(c.Red, c.Green, c.Blue) for c in color]
        view = UnwrapElement(j)
        elements = UnwrapElement(i)
        
        TransactionManager.Instance.EnsureInTransaction(doc)
        
        for e,c in zip(elements,adskcolor):
            overridecolor(e,c,solidfillid,view)
        
        TransactionManager.Instance.TransactionTaskDone()

OUT = elements

Last thing every time you run the script you need to make sure to delete the previous created views or choose different name for the new views, otherwise Revit will give an error that views already created with the same names. The deleting for the views can be automated as well. Since the script made with input form you can run it from dynamo player without opening dynamo.
Each view includes the clashed elements and if you still can’t detect the clash visually you can run the interference check as the colored element versus the linked element. With this way you will make sure to detect the clash and understand it. Check figures below.

Future consideration:

1- Automate solving the clashes that need to be joined.
2- Show clash details within the view.
3- Categories the views to avoid naming issue.

Dynamo Script:
Clash Detection.dyn (50.5 KB)

Regards,
Mohammad Nawar

27 Likes

Nice work :+1:

Actually thank you for the brilliant nodes :pray:

1 Like

A post was split to a new topic: Bimorph Element.Intersect node error

Hi @carolina.machado

Actually i have updated this script so better to visit the link below you will find everything. Enjoy!

https://www.bim-hex.com/single-post/2018/04/09/Best-practice-for-Clash-Detection

5 Likes

Thank you @Mohammad_Nawar !

@Mohammad_Nawar

I received your latest script from you website, however I’m running into some issues. First I cannot not select the link as shown in your video. I only have the option of pressing run as you can see below. After I run it I get an error which basically says there are no user inputs. So it’s not picking up the linked model. See second pic. Any ideas. Thanks and Cheers!

Hi @KFSam

You are right it’s not reading any of the linked models (showing empty list) but as a first assumption is it the get documents node working ? or collecting any ? . please send snapshot

@Mohammad_Nawar

Yep, that seems to be working. I have linked my walls into a project that has pipe and duct.

Ok ! i think i need to have a look for a sample of your file to solve the issue. I thought the node it’s not reading the linked model but it shows the opposite (since get document node can read the linked model UI.Multipleinputform ++ node also should show the linked models) i’m not sure the issue with the models or the graph so it would be better to have a look on your models.

Hi I would like to use elements of this script, but instead of running clash detection I would like to make 3d views from elements in a linked model using a list of elements from a CSV file. Any thoughts?

Hi @kmclean

Just to clear the things Revit is not able to do actions over any element from the linked models and it will fail to make any 3D view. However as a first thought i would collect the surrounded host element and create view from it in this case the view will include both elements (linked and host)

@KFSam

Thank you for sharing the models i have tested the script and no error shown and worked as it should be please check the pictures below. Also i will send you the script to make sure you have the latest update and if still you are facing any issue please watch the video from the website.

image

image

MANY THANKS, @Mohammad_Nawar

1 Like

Still getting a handle on this. I get this error. Not sure what i’m doing wrong

Hey @vanman

You have the old script please use the attached script and do let me know the if you still facing issue. also make sure that you have installed all required packages.
Clash Detection.v2.dyn (92.4 KB)

Note. Soon I will publish enhanced workflow for this script.

1 Like

Is this now a dynamo 2.0 graph? I get a file corrupted error opening in 1.3

Yeah its valid with Dynamo version 2

1 Like

This is awesome. Would be great to select Model Categories from the link instance separately from Model categories in the document to compare. Unless All categories in document picks up link categories too. I’ve been trying to get model categories from the link instance but struggling

Good news I am working on something similar and I will publish it soon

however in the meantime you can do as follow @vanman

2 Likes