Roof Gutter/Soffit by python script

python
#1

Hi
I have to place a gutter on a roof, and because I couldn’t find any dynamo node or package, I had a look in the Revit API. there is a command :

NewGutter(Autodesk.Revit.DB.Architecture.GutterType GutterType, Autodesk.Revit.DB.Reference reference)

so for gutter type I used a set of dynamo nodes:


now I need a python code to create the gutter
I’ve started with this code:

import clr
import math
#Import Revit Nodes
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

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

#The inputs to this node will be stored as a list in the IN variables.
line = UnwrapElement(IN[0])
type = UnwrapElement(IN[1])

output = []

doc = DocumentManager.Instance.CurrentDBDocument
   
TransactionManager.Instance.EnsureInTransaction(doc)

ref = Reference(line)
gutter = doc.Create.Newgutter(type, ref)
output.append(gutter.ToDSType(False))

TransactionManager.Instance.TransactionTaskDone()


OUT = output

unfortunately it doesn’t work.
It is because the reference, please help me to code the reference right
in API there is this syntax :

public Reference(Autodesk.Revit.DB.Element element)

but it didn’t work as I expected
should it be tied to a roof element?

#2

Hi @TeoBlack,

Try changing doc.Create.Newgutter(type, ref) to doc.Create.NewGutter(type, ref) :slight_smile:

1 Like
#3

thank you @MartinSpence , you are right, I have to be more careful with programming “grammar” . unfortunately, this time the issue is still there :slight_smile:

#4

Hehe, ok. Lemme get back to you with this a bit later when I get a chance :slightly_smiling_face:

#5

@MartinSpence thank you mate :slight_smile:

#6

Maybe just to help Martin out, I got this error which has me stumped :slight_smile:

I suspect a follow up question will be, how do you get a reference from a roof edge… Hopefully Martin has an idea for that as well… I could probably get a surface reference…

Apologies,

Mark

#7

Hi Mark

No probs. Everyone is allowed to chip in :slightly_smiling_face:.

It the NewGutter method needs the element of the element type, so try with a all elements of type node, and then extract a single element from the list you get :slightly_smiling_face:

Edit: in order to get the edges of a roof element, we’ll need to get the solid geometry from the roof, and from there extract the edges and turn them into a reference array I believe.

#8

Hmmm… The node output is GutterType rather than Autodesk.Revit.DB.Architecture.GutterType?

image

#9

I agree, so in this case we have to “convert” back (in the python), the rood into the footprint model lines, and pick one (say at index) for the gutter placement reference

#10

Indeed, so explode the roof solid, filter to get the top surface, choose an edge (probably easiest to be the one which aligns to the one we used to set the slope?)

It’s the reference array creation from the edge that I am interested to see :slight_smile:

#11

New gutter from Model Line:

import clr

#Import the Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

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

#Import ToDSType(bool) extensions method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument

#Start scripting here:

gt = UnwrapElement(IN[0])

line = UnwrapElement(IN[1])

ref = Reference(line)

TransactionManager.Instance.EnsureInTransaction(doc)

gutter = doc.Create.NewGutter(gt, ref).ToDSType(False)

TransactionManager.Instance.TransactionTaskDone()

#Assign your output to the OUT variable.
OUT = gutter

I’ll give the roof a go aswell, as that might be a little more interesting :slight_smile:

3 Likes
#12

Arg… I won’t be able to finish this… still needs a bit of sorting to get the right edges, but maybe one of you can work with this :slight_smile:

import clr

#Import the Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

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

#Import ToDSType(bool) extensions method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument

gt = UnwrapElement(IN[0])

roof = UnwrapElement(IN[1])

#Get the roof geometry -> Solid -> Edges
opt = Options()
opt.ComputeReferences = True

#the overloaded method get_Geometry will get the solid
roofSolid = roof.get_Geometry(opt)

#get the edges of the solid as references 
edgeRefs = []
temp = []
for i in roofSolid:
	edges = i.Edges
	for j in edges:
		edgeRefs.append(j.Reference)

gutter = []
TransactionManager.Instance.EnsureInTransaction(doc)

for i in edgeRefs:
	try:
		newGutter = doc.Create.NewGutter(gt, i)
		gutter.append(newGutter.ToDSType(False))
	except:
		gutter.append('No gutters on vertical or sloped edges :-(')

TransactionManager.Instance.TransactionTaskDone()

#Assign your output to the OUT variable.
OUT = gutter
3 Likes
#13

Great work :slight_smile:

It’s very interesting to see the Python approach in that way. I’m happy to use nodes to get the edge, it’s easy to check the right one has been selected.

I do slightly despair that providing the input described in the API failed… It’s a painful learning process!

Thanks,

Mark

#14

@MartinSpence looks good, I’ve tried to use the code with roof script to set the item index of roof line for creating the gutter but it doesn’t work. can you see the issue?

import clr
import math
#Import Revit Nodes
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from clr import StrongBox
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

#The inputs to this node will be stored as a list in the IN variables.
roof = UnwrapElement(IN[0])
type = UnwrapElement(IN[1])
index = IN[2]

gutter = []

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)

opt = Options()
opt.ComputeReferences = True
roofSolid = roof.get_Geometry(opt)

edgeRefs = []
temp = []


for i in roofSolid:
	edges = i.Edges
	for j in edges:
		edgeRefs.append(j.Reference)

ref = edgeRefs.Item[index]
gutter = doc.Create.NewGutter(type, ref)
		gutter.append(gutter.ToDSType(False))

TransactionManager.Instance.TransactionTaskDone()


OUT = output
#15

Hey,

Here’s a working version of your python…
RoofGutterIndex.dyn (6.1 KB)

I am not sure your method is so helpful though, because I don’t know how to check that the Index is the edge you want…

Incidently, because you don’t have the Else statement, the Python doesn’t tell you if the edge is unable to have a gutter (as Martin’s does)

Here’s a workflow as I outlined above…
RoofGutter.dyn (18.0 KB)

Because it is node based, we get the 3D preview in Dynamo and can review which edge is chosen. The big problem I had was maintaining the Reference, it was easy to filter as defined above, but I couldn’t get a Reference from the Edge. So you will see that I am going through some hoops to keep the References and Edges list structures aligned.

Hope that’s useful,

Mark

2 Likes
Autodesk.Revit.DB.Reference to Curve
#16

Excellent solution, Mark :metal::grin:. You are right, it’s much easier to manage using nodes :sweat_smile:

#17

You’re too kind, it’s not excellent, but it does the job :stuck_out_tongue:

I’m sure someone will point out a much more elegant way!

It’s a trade off isn’t it… Python is so concise and precise… Nodes are easy to understand but very verbose…

#18

It doesn’t work for me, I believe it is because of revit version I’m using (2016) :frowning:
Any way thanks Mark, will try to make it in my Revit version

1 Like
#19

I have got to a dead end and don’t understand what is the issue :frowning:

import clr
import math
#Import Revit Nodes
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from clr import StrongBox
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

#The inputs to this node will be stored as a list in the IN variables.
roof = UnwrapElement(IN[0])
type = UnwrapElement(IN[1])
index = IN[2]

gutter = []

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)

opt = Options()
opt.ComputeReferences = True
roofSolid = roof.get_Geometry(opt)

edgeRefs = []
temp = []

for i in roofSolid:
	edges = i.Edges
	for j in edges:
		edgeRefs.append(j.Reference)

ref = edgeRefs.Item[index]
gutter = doc.Create.NewGutter(type, ref)
		gutter.append(gutter.ToDSType(False))

TransactionManager.Instance.TransactionTaskDone()


OUT = gutter

Line Based Roof with slope and gutter.dyn (25.0 KB)

is it because of revit version again?

#20

The warning says: unexpected indent, I guess it’s the line gutter.append(gutter.ToDSType(False)), that should not be indented

1 Like