AttributeError: object has no attribute

Hi,
I’m trying to scale down the length of my vector and so I have a python script that takes a vector as an input and normalize the vector and multiply it to a scale factor.
I have an error notification from my python script that says the following:
Screenshot 2024-03-01 120009

Although i know that in the revit api docs, there is a method GetLength() for Vector (see GetLength Method (revitapidocs.com))

I’m not sure where the mistake lies, but here is my python script…

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitServices')
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

vector = IN[0]

#Normalize Vector
def normalize_vector(vector):
    length = vector.GetLength()
    if length > 0:
        return vector.Normalize()

#scale down the vector to 10 cm
def scale_vector(vector, scale_factor):
    return vector.Multiply(scale_factor)

normalized_vector = normalize_vector(vector)
scaled_vector = scale_vector(normalized_vector, 0.1)
OUT = 0

The problem is that the vector object is of type Autodesk.DesignScript.Geometry.Vector rather than the expected Autodesk.Revit.DB.UV or Autodesk.Revit.DB.XYZ type.

To fix this, you need to convert the vector to the appropriate Revit vector type before using GetLength() .

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitServices')
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

vector = IN[0]

# Convert DesignScript Vector to Revit XYZ
revit_vector = XYZ(vector.X, vector.Y, vector.Z)

# Normalize Vector
def normalize_vector(vector):
    length = vector.GetLength()
    if length > 0:
        return vector.Normalize()

# Scale down the vector to 10 cm
def scale_vector(vector, scale_factor):
    return vector.Multiply(scale_factor)

normalized_vector = normalize_vector(revit_vector)
scaled_vector = scale_vector(normalized_vector, 0.1)

OUT = scaled_vector

Also dont you want the scaled vector in the output?
Added that.

Edit: Here is a dynamo primer link about conversion. I just had to relearn that yesterday :wink:

3 Likes

My guess is an Autocomplete or ChatGPT lead you astray here.

For length of a Dynamo vector you can use the Dynamo property, length = vectorObject.Length.

1 Like

Thank you for the insights!

haven’t quiet fully comprehend until now that Dynamo’s geometry and the geometry from the Revit API are two separate things :sweat_smile:

how does this work for other types such as elements?

I wanted to recreate the Element.Geometry node but it also results in the same error

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitServices')
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

workspace = UnwrapElement(IN[0])

OUT = workspace.Geometry

I’m still pretty new at coding python in dynamo…
is there a documentation for dynamo that i can refer to so i’d know which properties or methods are there? or is it just what’s available in the library?

UnwrapElement deals with converting from a Dynamo element to a Revit API one. :slight_smile:

In this case you’re not providing a Revit API call, but you converted to a Revit object (hence the unwrap element line). If you don’t unwrap you can use the Dynamo Revit element property like that, but if you are going to unwrap you need to use element.get_Geometry(options).

To see what you can use on a given object try OUT = dir(object) which will pull all methods for an object. From there you can call for the documentation via OUT = object.Method.__doc__ where method is something from the dir(object) output.

2 Likes

Thank you this helped me a lot!

I’m not quiet sure the part where you mention calling OUT = object.Method.__doc__ to read the documentation

I might be understanding it incorrectly but do you mean like this way?

object = IN[0]

solid_object = object.Solids
    
OUT = dir(solid_object[0])
object = IN[0]

OUT = object.Method.__doc__

most likely not correct :confused: because it’s returning this:
image

You usually shouldn’t have consecutive Python nodes as it is extremely inefficient.

The intent is to use these methods to assist in authoring the code, often one after the other.

# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

object = IN[0] #get an object however you like - in this case I'm bringing it in from the Dynamo environment

whatCanYouDo = dir(object) #get a list of what you can do with the object using your current imports

OUT = whatCanYouDo #return the list of what you can do with the object into the Dynamo environment

#############################################
#### after running the above, change the ####
#### "Method" here to one of the items   ####
#### in the output, and uncomment the    ####
#### line to learn about it, such as the ####
#### inputs, or any other documentation  ####
#############################################
#documentation = object.Method.__doc__
#OUT = documentation, whatCanYouDo

So run that code, find something you like about the object, and then modify the documentation = object.Method.__doc__ line to be documentation = object.**SomethingFromTheCurrentOutput**.__doc__, and uncomment the last two lines

1 Like