Shaft BoundaryCurves

Hi all,

i’m trying to retrieve the geometry / boundarycurves of shafts.
The geometry seems to be empty, i assum this is a consequents of them being void types?
In the revit api there is the ShaftOpening.BoundaryCurves wich works in pyrevit for me to retrieve the boundarie curves. But it fails in Dynamo any ideas on what i’m doing wrong here, because i don’t really see it at this point :slight_smile: .

Thx for the help!

error given on the node:
Warning: NameError : name 'shaft_cruves' is not defined [' File "<string>", line 18, in <module>\n']
below my code and some screen shots:

Load the Python Standard and DesignScript Libraries

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

link = IN[0]

shafts = FilteredElementCollector(link).OfCategory(BuiltInCategory.OST_ShaftOpening).ToElements()
# Place your code below this line
shaft_curves =[]

for shaft in shafts:
    shaft_curves.append(shaft.BoundaryCurves)

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

Check the spelling of the final line - shaft_curves != shaft_cruves

1 Like

thx @jacob.small,
my disclecatie wasn’t helping me out there :wink:

1 Like

hi @jacob.small ,

i’m trying to use the retrieved line to create new shaft of lines from them.
I’m no expert at this but i’m not managing to convert the autodesk.revit.DB.curve(line) to a Autodesk.DesignScript.Geometry.Curve.

Is it possible at all to convert these?

what i’m also finding strange is that it seems to retrieve a lot of lines for some shaft, while they are rectangual in the model itself. any ideas on why this is?

i also found this code from the spings elementsketch node.
But this one only works on the shaft in the current model not the linked one:

#Copyright(c) 2016, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com

import clr
import math

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

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

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

def tolist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]

elements = UnwrapElement(tolist(IN[0]))
getModel = IN[1]

accepted_mc = "Autodesk.Revit.DB.ModelLine, Autodesk.Revit.DB.ModelArc, Autodesk.Revit.DB.ModelEllipse, Autodesk.Revit.DB.ModelHermiteSpline, Autodesk.Revit.DB.ModelNurbSpline"

def almost_eq(line, mc):
	line2 = mc.Location.Curve
	xyz1 = line.Evaluate(0.5, True)
	if not line2.IsBound:
		xyz2 = line2.Center
		try: xyz1 = line.Center
		except: pass
	else:
		xyz2 = line2.Evaluate(0.5, True)
	if xyz1.DistanceTo(xyz2) <= 0.0001:
		return True
	else:
		return False

def clean1(l1):
	for i in xrange(len(l1) ):
		l1[i] = [x for x in l1[i] if x != None]
	return l1

def getSketch(el1):
	try:
		sk1 = doc.GetElement(ElementId(el1.Id.IntegerValue - 1) )
	except:
		sk1 = None
	if not getModel and sk1 is not None and sk1.GetType().ToString() == 'Autodesk.Revit.DB.Sketch':
		profile = sk1.Profile
	else:
		t1 = SubTransaction(doc)
		t1.Start()
		deleted = doc.Delete(el1.Id)
		t1.RollBack()
		
		profile, mc = CurveArrArray(), []
		for d in deleted:
			test_el = doc.GetElement(d)
			el_type = test_el.GetType().ToString()
			if el_type == "Autodesk.Revit.DB.Sketch":
				profile = test_el.Profile
				if not getModel:
					break
			elif getModel and el_type in accepted_mc :
				mc.append(test_el)

	ordered_mc = [ [None] * i.Size for i in profile] if getModel else []
	curves = [ [None] * i.Size for i in profile]
	for i in xrange(profile.Size):
		for j in xrange(profile[i].Size):
			curves[i][j] = profile[i][j].ToProtoType()
			if getModel:
				for k in xrange(len(mc)):
					if almost_eq(profile[i][j], mc[k]):
						ordered_mc[i][j] = mc[k].ToDSType(True)
						del mc[k]
						break
						
	return curves, clean1(ordered_mc)

TransactionManager.Instance.EnsureInTransaction(doc)
result = map(getSketch, elements)
TransactionManager.Instance.TransactionTaskDone()
OUT = [r[0] for r in result], [r[1] for r in result]

Convert the Revit curves to Dynamo curves using the .ToProtoType() method.

Thx at @jacob.small for the help.

i figured the code out and now i have clear contours of the shaft.
I not only need to use the .ToProtoType() methode, wich was purely for dynamo.

I was also on the wrong path whit using the shaftopening.BoundaryCurves methode.
it seems that using this methode i get both the boundarycurves and the symbolic lines from the shaft.
And the later we really don’t needed ofc.

So for those people looking for the solution to retrieve clean shaft countours from shaft linked or in current model ( depending on wich doc u input into the node):

Dynamo / python:

# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

link = IN[0]

shafts = FilteredElementCollector(link).OfCategory(BuiltInCategory.OST_ShaftOpening).ToElements()
# Place your code below this line
shaft_curves =[]

for shaft in shafts:
    sketch = link.GetElement(shaft.SketchId)
    profile = sketch.Profile
    curves = []
    for profile_curve in profile:
        for curve in profile_curve:
            curves.append(curve.ToProtoType())
    shaft_curves.append(curves)
 
# Assign your output to the OUT variable.
OUT = shaft_curves