Multiple Spot Coordinates

Hello,

I’m trying to tag a floor in my view with multiple Spot Coordinates.

I haven’t found this in any other post except here: Spot coordinates

But that doesn’t work for multiple points.
It’s giving me this error:
Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 20, in
AttributeError: ‘List[object]’ object has no attribute ‘ToXyz’

I know @fluffyhugger mentioned how you could make it work for multiple inputs, but I’m not good enough at Python to get it to work.

Any help would be appreciated.
Thanks!
Lynn

Hi @quagliatol

Could you drop here rvt file and dyn file?

Because of the complication of the script and file, it’ll be kind of hard to make an example file. :confused:

Unfortunately it’s something that’s needed to help. :frowning:

I was hoping we could figure it out as a general Python question.

Here’s the code:

Inputs p, o and n would need to have a list of points (instead of a single point) as inputs.

Sorry it would take me a while to replicate this in a new project and Dynamo script!

Well I tried to get the Python code to work with multiple points.

# editted code originally from https://forum.dynamobim.com/t/spot-coordinates/27910/9

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

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

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

doc = DocumentManager.Instance.CurrentDBDocument

v = UnwrapElement(IN[2])
r = UnwrapElement(IN[0])

inpoints = UnwrapElement(IN[1])
inbends = UnwrapElement(IN[3])
inends = UnwrapElement(IN[4])

TransactionManager.Instance.EnsureInTransaction(doc)

# make points XYZ

pointsxyz = []
bends = []
ends = []

for a in inpoints:
	g = a.ToXyz()
	pointsxyz.append(g)

for b in inbends:
	h = b.ToXyz()
	bends.append(h)

for c in inends:
	i = c.ToXyz()
	ends.append(i)

# floor edit

re = Reference(r)

# annotate
	
outanno = []

for d, e, f in zip(pointsxyz, bends, ends):
	outanno.append(doc.Create.NewSpotCoordinate(v, re, d, e, f, d, True))

TransactionManager.Instance.TransactionTaskDone()

OUT = outanno

Please excuse the awfully-formatted Python.

I think this should work but it’s giving me this error:

Exception: Error occurred when creating Spot Dimension!

If anyone knows how to fix this, please let me know!

I would suggest giving more meaningful names to your variables. It looks like the code is minified, which makes it very hard to follow and debug.

If I may elaborate on behalf of @Kulkul and @jacob.small , most people asking here for help are field professionals and understandably can’t share the files on which they working (I’ve been there myself). But what many people don’t really think about is that in order to help, there has to be a complete problem definition. Because the root of the it is not always where one think it is. That’s why to help there has to be the whole outline. A small screenshot of a section of a script is not enough to go about. So for the future, just make a sample that replicates your issue and share that.

Dear colleagues if I got anything wrong, please correct me.

For this specific problem, it seems to be issue of Reference . If you replicate the code with singular input it says:

image

FamilyInstance.GetReferenceByName doesn’t work on system families. I myself really don’t know how to solve it.

1 Like

@quagliatol since nobody rushes to explain why Recerence method doesn’t work, here’s some workaround for floors and system families and for the matter any geometry in general.

Create a generic model family with small circle as model line and make is invisible. Load it in to your project. Now you have a geometrie instance that has coordinates and is invisible but can be spotted. Place it at desired place and elevation and use the original script. To make the script work on multiple inputs wrap it in a costume node (File -> New -> Custom node..). Make something like the following:

image

Now to make it work just make sure you feed all inputs as 1 dimensional lists (so just items 1,2,3…n). I had to use List.Combine as shown below to make it work. And it did. Hope it helps.

image

2 Likes

Hi @quagliatol,

The Reference needs to be a geometric reference, which you need to get from the floor object. See below for a, quick and dirty, example for a single Floor object:

image

Python script:

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:###---#
floor = UnwrapElement(IN[0])
refPts = [i.ToXyz() for i in IN[1]]
view = doc.ActiveView

opts = Options()
opts.ComputeReferences = True

floorSolid = floor.get_Geometry(opts)
plFaces = [i.Faces for i in floorSolid][0]
upFace = None
for i in plFaces:
	normal = i.FaceNormal
	if normal.Z == 1:
		upFace = i

ref = upFace.Reference
		
#Transaction start:
TransactionManager.Instance.EnsureInTransaction(doc)
spotElev = []
for i in refPts:
	spotElev.append(doc.Create.NewSpotElevation(view, ref, i, i, i, i, False))
#Transaction end:
TransactionManager.Instance.TransactionTaskDone()

OUT = spotElev
1 Like