Dimension to wall finished face

Hi

I’m trying to dimension to the finished face of 2 parallel walls.

If I use the walls as the elements in ‘Dimension.ByElements’ it will do it to the centre line. I don’t want to extract curves and dimension to those as the dimension will not be hosted to the actual walls. I though i could get the face references of the walls and use those but I am getting an error:

“Warning: One or more of the input types are not matching. Couldn’t find a version of ByElements that takes arguments of type (Revit.Elements.Views.FloorPlanView,__array,__array,string,string)”

Any thoughts?

1 Like

@Vikram_Subbaiah @Kulkul any thoughts on this?

You can use the awesome code shared by @viktor_kuzev here:

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

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

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

doc=DocumentManager.Instance.CurrentDBDocument

line = UnwrapElement(IN[0]).GeometryCurve
elements= IN[1]
dim=0

elementsRef=ReferenceArray()
opt=Options()
opt.ComputeReferences=True
opt.IncludeNonVisibleObjects=True
opt.View=doc.ActiveView

for element in elements:
	elementsRef.Append(element)
	
TransactionManager.Instance.EnsureInTransaction(doc)

dim= doc.Create.NewDimension(doc.ActiveView, line, elementsRef).ToDSType(True)

TransactionManager.Instance.TransactionTaskDone()

OUT=dim

Looks like the difference between Revit.GeometryReference.ElementFace and Autodesk.Revit.DB.Reference (when converting a wall surface to a reference through the clockwork node did the trick)

Thanks @Ewan_Opie

But I can’t get the clockwork node to work. I tried both faces (which I think is correct) and also surfaces. Error messgae is:

Warning: One or more of the input types are not matching. Couldn’t find a version of __func_3204925d04934b8bb42bfb0d8041837b that takes arguments of type (__array)

Did you manage to get it to work? I’m on revit 2018 with Dynamo 1.3.3.

Im running 2018 D1.3.3
My input to the clockwork node had a flattened list of two surfaces displaying as “Surface” in the node preview. Is that what you have in the Face.SurfaceGeometry node?

It would appear that there is a difference between the surface extracted from a geometry and a selected model face. Though they both appear to be Autodesk.DesignScript.Geometry.Surfaces… :thinking: I will investigate further in the morning.

image

Hi @Paul_Wintour
The error I was encountering related to remaking the surface from a face, rather than extracting the surface directly. :man_facepalming:
Try using the Topology.Faces node directly from the wall elements themselves. This will return the wall faces as surfaces. It should work then. :grinning:


1 Like

Yep that was the problem. I was getting geometry then using typology. I needed to use typology on the element. Thanks!

So becuase they are DB.references and not elements, I need to use the Python script rather than the ‘Dimension.ByElements’ node?

And if I want to use a line rather than an element as the dimension position reference, I though I could just change the script from:

line = UnwrapElement(IN[0]).GeometryCurve

to

line = IN[0]

But this didn’t work. Do you know what I need to do to modify it?

@Ewan_Opie

The Python script creating the dimensions has an input of type ‘Autodesk.Revit.DB.Reference’. Do you know how you can extract this from a level and grid?

I believe I can use the ‘GetPlaneReference’ method for levels but not sure about grids. There is a ‘Grid.ElementCurveReference’ but the Python script doesn’t like that.

I want to combine face geometry (landings, risers, etc) with levels/grids to create one dimension string.

@Ewan_Opie

any idea why this is failing? I’m getting an error message:

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed. Traceback (most recent call last): File “”, line 32, in TypeError: expected Line, got Line

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

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

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

doc=DocumentManager.Instance.CurrentDBDocument

line = IN[0]
elements= IN[1]
dim=0

elementsRef=ReferenceArray()
opt=Options()
opt.ComputeReferences=True
opt.IncludeNonVisibleObjects=True
opt.View=doc.ActiveView

for element in elements:
	elementsRef.Append(element)
	
TransactionManager.Instance.EnsureInTransaction(doc)

dim= doc.Create.NewDimension(doc.ActiveView, line, elementsRef).ToDSType(True)

TransactionManager.Instance.TransactionTaskDone()

OUT=dim

This explanation @awilliams has provided should hopefully explain what’s going on with the error.

I’m back at the PC tmw morning, so can test/post revisions to the code then (unless you have sorted it by then :wink:)

EDIT: @Paul_Wintour give this shot.

Thanks @Ewan_Opie & @awilliams, that worked!

1 Like

@Ewan_Opie @awilliams

Sorry but how would I go about amending this so that it takes a list of lines (3 lines one for each dimension) and 3 lists of elements to be dimensioned?

I thought I could create a custom node and just change the lacing but that doesn’t work. How does lacing working with Python nodes within a custom node? Is this possible or is it best to modify the Python itself?

Thanks

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

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

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

doc=DocumentManager.Instance.CurrentDBDocument

line = IN[0].ToRevitType()
elements= IN[1]
dim=0

elementsRef=ReferenceArray()
opt=Options()
opt.ComputeReferences=True
opt.IncludeNonVisibleObjects=True
opt.View=doc.ActiveView

for element in elements:
	elementsRef.Append(element)
	
TransactionManager.Instance.EnsureInTransaction(doc)

dim= doc.Create.NewDimension(doc.ActiveView, line, elementsRef).ToDSType(True)

TransactionManager.Instance.TransactionTaskDone()

OUT=dim
1 Like

For this, the Python would need to be re-written to handle lists.

@Daniel_Woodcock1 :+1: has provided this super example here:

A slight tweak as per below is required to get this working for Autodesk.Revit.DB.Reference elements such as these wall faces.

import clr

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

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]

view = doc.ActiveView
dimLines = tolist(UnwrapElement(IN[0]))
linesToDim = tolist(UnwrapElement(IN[1]))

refArrays = []

outList = []

for lineList in linesToDim:
    rArr = ReferenceArray()
    for l in lineList:
        rArr.Append(l)
    refArrays.append(rArr)

TransactionManager.Instance.EnsureInTransaction(doc)
for l,r in zip(dimLines,refArrays):
    try:
        outList.append(doc.Create.NewDimension(view,l.GeometryCurve,r))
    except Exception,e:
        outList.append(e.message)
    
TransactionManager.Instance.TransactionTaskDone()

OUT = outList
1 Like

The Revit API didn’t had access to wall layers, can this dimensioning be done from core to core?

Since Revit 2016, you have access to the layers.

CompoundStructure Class

Thank @Ewan_Opie. That mostly worked but I did have to tweak it by removing GeometryCurve and replacing it with ToRevitType. All good now. Thanks.

import clr

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

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]

view = doc.ActiveView
dimLines = tolist(UnwrapElement(IN[0]))
linesToDim = tolist(UnwrapElement(IN[1]))

refArrays = []

outList = []

for lineList in linesToDim:
    rArr = ReferenceArray()
    for l in lineList:
        rArr.Append(l)
    refArrays.append(rArr)

TransactionManager.Instance.EnsureInTransaction(doc)
for l,r in zip(dimLines,refArrays):
    try:
        outList.append(doc.Create.NewDimension(view,l.ToRevitType(),r))
    except Exception,e:
        outList.append(e.message)
    
TransactionManager.Instance.TransactionTaskDone()

OUT = outList
1 Like