# Place Fabrication hanger by points in Dynamo

**URL:** <https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868>\
**Category:** Revit\
**Tags:** dynamo\
**Created:** [July 20, 2022, 11:25am UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868 "2022-07-20T11:25:38Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![arukaroor](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@arukaroor](https://forum.dynamobim.com/u/arukaroor)\
**Post date:** [July 20, 2022, 11:25am UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/1 "2022-07-20T11:25:38Z")

</div>

Hello, I have multiple points and i need to place a fabrication hanger to those points. I couldn’t find any nodes to convert point to fabrication element.  
Also need to change the size of the hanger too. But when i check the parameters in revit properties no option shown there.  
Anybody tell me how can i do these in Dynamo. (I am a beginner in dynamo)

 ![Screenshot 2022-07-20 165429](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/d/1/d1714e1a844c35f77d959c41be223f70a4bf9e72.png)

---

<div class="post-metadata">

**Author:** ![c.poupin](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/c.poupin/32/89152_2.png) [@c.poupin](https://forum.dynamobim.com/u/c.poupin)\
**Post date:** [August 2, 2022, 3:35pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/2 "2022-08-02T15:35:43Z")

</div>

Hello @arukaroor and welcome  
Please read the forum rules if you haven’t.

> [@How to get help on the Dynamo forums](https://forum.dynamobim.com/t/how-to-get-help-on-the-dynamo-forums/4677):
>
> One of the main goals of the Dynamo community is to help others. One way to do that is by answering your questions. But to get the right answer, you’ll first have to ask your question in the right way. Although people are generally very helpful, there are things you can do to improve your chances of getting good and quick answers. Below you will find some suggestions on how to achieve that. Do not think of these suggestions as rules and especially do not take them as a guarantee of getting an an…

I’m not sure if there are custom nodes can do this, I know you are a beginner but you can do it with Python if you have some programming knowledge.  
_unfortunately the Fabrication Part is not the easiest part of the Revit API_

here an example  
 ![hangers3](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/c/3/c3e952e2a3518a854968479585141f8eba4adf5b.gif)

Python code

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

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

def getConnectors(elem):
	lstCon = []
	conectors = elem.ConnectorManager.Connectors
	lstCon = [con for con in conectors]
	return lstCon[0], lstCon[1]

def getServiceButton(lstServiceFab, famName):	
	for servicFab in lstServiceFab:
		countGroup = servicFab.GroupCount
		for x in range(countGroup):
			countButton = servicFab.GetButtonCount(x)
			for y in range(countButton):
				fabServiceButton = servicFab.GetButton(x,y)
				if fabServiceButton.Name == famName:
					return fabServiceButton

fabPart = UnwrapElement(IN[0])
lstPoints = IN[1]
famName = IN[2]
outHanger = []
error = []
fabConf = FilteredElementCollector(doc).OfClass(FabricationConfiguration).FirstElement()
lstServ = fabConf.GetAllLoadedServices()
button = getServiceButton(lstServ, famName)
if button is not None:
	TransactionManager.Instance.EnsureInTransaction(doc)
	for pts in lstPoints:
		#convert dynamoPt to RevitPt
		rvtPt = pts.ToXyz()
		curveFabPart = fabPart.Location.Curve
		conectA, conectB = getConnectors(fabPart)
		interResult = curveFabPart.Project(rvtPt)
		if interResult.Distance < 0.05 :
			distaceA = rvtPt.DistanceTo(conectA.Origin)
			distaceB = rvtPt.DistanceTo(conectB.Origin)
			try:
				newhanger = FabricationPart.CreateHanger(doc, button, fabPart.Id, conectA, distaceA, True)
				outHanger.append(newhanger)
			except:
				try:
					newhanger = FabricationPart.CreateHanger(doc, button, fabPart.Id, conectB, distaceB, True)
					outHanger.append(newhanger)
				except Exception as ex:	
					error.append([ex, distaceA, distaceB])
	
	TransactionManager.Instance.TransactionTaskDone()
else:
	error = "ERROR, No hanger has been loaded with this name : '{}'".format(famName)
OUT = fabConf, button, outHanger, error

```

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/4/7/4787554a26a9de902a61a2ab460a8ff485032c25.png)

the api doc

> **[CreateHanger Method](https://www.revitapidocs.com/2021.1/aafc60d9-fd3e-59e1-1278-eda915ce1848.htm)**
>
> Online Documentation for Autodesk's Revit API: 2015, 2016, 2017, 2017.1, 2018

---

<div class="post-metadata">

**Author:** ![Evan.Pond](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/evan.pond/32/98460_2.png) [@Evan.Pond](https://forum.dynamobim.com/u/Evan.Pond)\
**Post date:** [August 2, 2022, 4:14pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/3 "2022-08-02T16:14:01Z")

</div>

What do you mean by you have points to place hangers? You have coordinates? A model element that needs changed to a hanger?

As mentioned MEP Fab parts are hard to work with in revit but I’m guessing you have already figured that out.  
Hanger size is not an available instance parameter in the revit properties. By Dynamo can pull it up.  
Element.Parameters is a useful node to figure out what you have to work with.  
Also Parameter.ParameterByName needs to be used with Fab parts a lot instead of Element.GetParameterValue ByName but not always.

 ![Capture](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/3/d/3de9508fb02499812ef0580541ef90f53eb6656d.jpeg)

---

<div class="post-metadata">

**Author:** ![arukaroor](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@arukaroor](https://forum.dynamobim.com/u/arukaroor)\
**Post date:** [August 4, 2022, 4:33pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/4 "2022-08-04T16:33:28Z")

</div>

Thank you Mr.c.poupin for your support. Sorry for late reply.

I am not familiar with any programing language. But I have copied this example code in Dynamo and run the script as you shown in the image.  
In my understanding this code will place hanger at (given input) distance, and it will work with only one element at a time. Correct me if I am wrong.  
When I connect multiple pipes, this script shows some warnings(see the attached image).  
Actually my requirement is that I need to place hangers at a specific distance in a pipe/duct run (a pipe run may be contain multiple pipes/fittings/couplings/solder joints/welded joints etc).  
Is there any way to update this script for placing the hangers at a distance of 5’-0" by selecting a long pipe run and considering start and end points (P1 & P2) as marked in the image.

 ![Screenshot 2022-08-04 220204](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/a/6/a649fb327aca2e1e920b9cef611551b2f845b2f6.png)  
Sorry for my poor English.

---

<div class="post-metadata">

**Author:** ![arukaroor](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@arukaroor](https://forum.dynamobim.com/u/arukaroor)\
**Post date:** [August 4, 2022, 4:59pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/5 "2022-08-04T16:59:17Z")

</div>

Thank you for your reply Mr.Evan.Pond  
_A model element that needs changed to a hanger?_ : Exactly.  
I didn’t see a way place the hanger and change the size parameter for fabrication part in dynamo.

---

<div class="post-metadata">

**Author:** ![c.poupin](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/c.poupin/32/89152_2.png) [@c.poupin](https://forum.dynamobim.com/u/c.poupin)\
**Post date:** [August 5, 2022, 11:45am UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/6 "2022-08-05T11:45:23Z")

</div>

Here is a variant for multi conduit, nevertheless you will have to determine the points per conduits (list with sub list of points)

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/2/d/2d63380c6265ae70a8f48b415612b99f09dc5151.png)

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

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

def getConnectors(elem):
	lstCon = []
	conectors = elem.ConnectorManager.Connectors
	lstCon = [con for con in conectors]
	return lstCon[0], lstCon[1]

def getServiceButton(lstServiceFab, famName):	
	for servicFab in lstServiceFab:
		countGroup = servicFab.GroupCount
		for x in range(countGroup):
			countButton = servicFab.GetButtonCount(x)
			for y in range(countButton):
				fabServiceButton = servicFab.GetButton(x,y)
				if fabServiceButton.Name == famName:
					return fabServiceButton

toList = lambda x : x if hasattr(x, ' __iter__') else [x]

lst_fabPart = toList(UnwrapElement(IN[0]))
group_lst_Points = IN[1]
famName = IN[2]
outHanger = []
error = []
fabConf = FilteredElementCollector(doc).OfClass(FabricationConfiguration).FirstElement()
lstServ = fabConf.GetAllLoadedServices() #GetAllServices()
button = getServiceButton(lstServ, famName)
if button is not None:
	TransactionManager.Instance.EnsureInTransaction(doc)
	for lstPoints, fabPart in zip(group_lst_Points, lst_fabPart):
		for pts in lstPoints:
			#convert dynamoPt to RevitPt
			rvtPt = pts.ToXyz()
			curveFabPart = fabPart.Location.Curve
			conectA, conectB = getConnectors(fabPart)
			interResult = curveFabPart.Project(rvtPt)
			if interResult.Distance < 0.05 :
				distaceA = rvtPt.DistanceTo(conectA.Origin)
				distaceB = rvtPt.DistanceTo(conectB.Origin)
				try:
					newhanger = FabricationPart.CreateHanger(doc, button, fabPart.Id, conectA, distaceA, True)
					outHanger.append(newhanger)
				except:
					try:
						newhanger = FabricationPart.CreateHanger(doc, button, fabPart.Id, conectB, distaceB, True)
						outHanger.append(newhanger)
					except Exception as ex:	
						error.append([ex, distaceA, distaceB])
	
	TransactionManager.Instance.TransactionTaskDone()
else:
	error = "ERROR, No hanger has been loaded with this name : '{}'".format(famName)
OUT = fabConf, button, outHanger, error

```

---

<div class="post-metadata">

**Author:** ![arukaroor](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@arukaroor](https://forum.dynamobim.com/u/arukaroor)\
**Post date:** [August 5, 2022, 3:34pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/7 "2022-08-05T15:34:27Z")

</div>

When I to run the new script, its showing some waring in the python script. Am I doing anything wrong?  
Please se the attached script.

[Hanger-Python.dyn](https://forum.dynamobim.com/uploads/short-url/7mvt1wkolxEEadtKek3zSr629jp.dyn) (16.5 KB)

 ![Untitled-05.08.22](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/a/3/a3c87be56953ff7aa532ec0ffed2c768e6fddf81.png)

---

<div class="post-metadata">

**Author:** ![c.poupin](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/c.poupin/32/89152_2.png) [@c.poupin](https://forum.dynamobim.com/u/c.poupin)\
**Post date:** [August 5, 2022, 8:13pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/8 "2022-08-05T20:13:13Z")

</div>

Set the lacing of the `Curve.PointAtParameter` node to “Cross”

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/2/9/291279202daa6247b26f5b7fc8f00b3fccb949a5.jpeg)

---

<div class="post-metadata">

**Author:** ![arukaroor](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@arukaroor](https://forum.dynamobim.com/u/arukaroor)\
**Post date:** [August 6, 2022, 2:55pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/9 "2022-08-06T14:55:59Z")

</div>

I have tried the lacing already. Still it shows warning in python code. Also It would be better if we can provide hanger distance in code block as input. I mean, if the pipes total length is 10’ , the hangers should be placed at given input distance. Instead of providing the total number and steps in code block[0.2…0.7…0.2] a single input (hanger distance) would be work better.

Sorry to disturb you again.  
 ![Untitled](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/8/3/83b2d77b6869ded762df7debc6bf30b1d774e490.png)

---

<div class="post-metadata">

**Author:** ![c.poupin](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/c.poupin/32/89152_2.png) [@c.poupin](https://forum.dynamobim.com/u/c.poupin)\
**Post date:** [August 6, 2022, 8:47pm UTC](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/10 "2022-08-06T20:47:43Z")

</div>

> [@arukaroor](#):
>
> I have tried the lacing already. Still it shows warning in python code.

You have an error in your graph, show the graph in this post

> [@Place Fabrication hanger by points in Dynamo](https://forum.dynamobim.com/t/place-fabrication-hanger-by-points-in-dynamo/78868/6):
>
> Here is a variant for multi conduit, nevertheless you will have to determine the points per conduits (list with sub list of points) import sys import clr clr.AddReference('ProtoGeometry') from Autodesk.DesignScript.Geometry import \* clr.AddReference('RevitAPI') import Autodesk from Autodesk.Revit.DB import \* from Autodesk.Revit.DB.Fabrication import \* clr.AddReference('RevitServices') import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Trans…
