This is the first of at least two posts on attributes. This first one will cover the basics and subsequent postings will go into some more advanced aspects. Most programs your write will likely only need the information covered in this post.
The attribute functionality of Inventor is something that’s only available through the API; it doesn’t have a user-interface. The basic concept of attributes is very simple; it’s the ability to associate information with Inventor entities. Where it get’s a little more complicated is in understanding when this functionality might apply to your programs and how you can take advantage of it.
First, let’s look at the API for attributes. Every object that supports attributes has the AttributeSets property from which you can access the attributes associated with that particular object. Below is the object model for attributes.
The “Inventor Entity” is any object that supports the AttributeSets property. The AttributesSets object returned by this property is an object collection that lets you access all of the AttributeSet objects associated with the object, and it also lets you create new AttributeSet objects. An AttributeSet is exactly what the name implies; a set of attributes. They provide a way of grouping the attributes associated with an object. Typically, each application that adds an attribute to an object will create their own attribute set so that their attributes aren’t mixed with another application’s attributes.
Creating an Attribute
An AttributeSet object is also a collection object and provides access to the Attribute objects it contains and provides the ability to create new attributes. Below is an example VBA macro that demonstrates this by creating a new attribute set on a selected entity and then adds an attribute to that set.
Public Sub CreateAttribute()
' Get the active document. It can be any type of document.
Dim doc As Document
Set doc = ThisApplication.ActiveDocument
' Get the selected entity.
Dim entity As Object
On Error Resume Next
Set entity = doc.SelectSet.Item(1)
If Err Then
MsgBox "You must select an entity."
Exit Sub
End If
' Get the AttributeSets object from the selected entity.
Dim attribSets As AttributeSets
Set attribSets = entity.AttributeSets
If Err Then
MsgBox "You must select an entity that supports attributes."
Exit Sub
End If
On Error GoTo 0
' Create an attribute set.
Dim attribSet As AttributeSet
Set attribSet = attribSets.Add("SampleSet")
' Create an attribute on the set.
Dim attrib As Inventor.Attribute
Set attrib = attribSet.Add("SampleAttribute", _
kStringType, "A Test")
End Sub
The first portion of the program gets the entity that is currently selected within the active document. Notice that the variable “entity” is declared as Object, indicating that any type of object can be handled. The error handling is used to catch the case where no entity has been selected.
The next section of the program gets the AttributeSets object from the selected entity. Since the program allows you to select anything, the error handling is used to catch the case where the selected object doesn’t support the AttributeSets property.
Finally, we have an AttributeSets object that was obtained from the selected entity. The next section creates an AttributeSet object using the Add method of the AttributeSets object. It supplies the name to use for the AttributeSet. The name must be unique with respect to the other AttributeSet objects associated with that particular AttributeSets object. Typically you would append the set name with your company or application name to make it unique, i.e. “modmachineSampleTest”.
The final section of the program creates an attribute within the attribute set. The creation of the attribute takes three arguments; name, type, and value. The name must be unique with respect to the other attributes within this attribute set. Since it’s likely you’re the only one adding attributes to your set this is easily managed by you. Attributes can be one of four different types; Double, Integer, String, or array of Bytes. In the example above it creates a String attribute with the value of “A Test”.
Getting an Existing Attribute From an Entity
Now that you’ve seen how to create an attribute on an entity, how do you get that attribute back at a later time? There are two ways of accessing attributes. The first uses the objects we’ve already looked at; AttributeSets and AttributeSet. The sample code below illustrates getting the attribute that was just created.
Public Sub GetAttribute()
' Get the active document. It can be any type of document.
Dim doc As Document
Set doc = ThisApplication.ActiveDocument
' Get the selected entity.
Dim entity As Object
On Error Resume Next
Set entity = doc.SelectSet.Item(1)
If Err Then
MsgBox "You must select an entity."
Exit Sub
End If
' Get the AttributeSets object from the selected entity.
Dim attribSets As AttributeSets
Set attribSets = entity.AttributeSets
If Err Then
MsgBox "You must select an entity that supports attributes."
Exit Sub
End If
On Error GoTo 0
' Check to see if it has the "SampleSet" attribute set.
If attribSets.NameIsUsed("SampleSet") Then
' Get the attribute set.
Dim attribSet As AttributeSet
Set attribSet = attribSets.Item("SampleSet")
' Get the attribute on the set.
Dim attrib As Inventor.Attribute
Set attrib = attribSet.Item("SampleAttribute")
MsgBox "Attribute " & attrib.name & " = " & attrib.Value
Else
MsgBox "The entity does not have the expected attribute set."
End If
End Sub
Most of the code in the sample above is the same as the previous sample. However, once it has the AttributeSets object from the selected entity it uses the NameIsUsed property of the AttributeSets object to see if there is an attribute set named “SampleSet”. If there is then it gets the attribute named “SampleAttribute”. Finally it displays the name and value of that attribute.
The approach demonstrated above illustrates how you can get an attribute from an known entity. The problem with this approach is that in many cases you don’t have a reference to the entity the attribute is attached to. For example, you might have attached an attribute to a face so you can use the attribute at a later time to find that face again. Using the technique shown above you would need to iterate over every face in the model until you found the one that had the “SampleSet” attribute set. Not a very efficient way to find the attribute. Another approach of getting attributes is discussed below.
Getting an Existing Attribute Using the Attribute Manager
The other way to find existing attributes is to use the AttributeManager object. This is an object you obtain using the AttributeManager property of the Document object. The most common use of the attribute manager is to query for attributes that exist in the document. For example, the code below will find all entities that have an attribute set called “SampleSet”.
Public Sub GetAttributeUsingManager()
' Get the active document. It can be any type of document.
Dim doc As Document
Set doc = ThisApplication.ActiveDocument
' Get the attribute manager.
Dim attribMgr As AttributeManager
Set attribMgr = doc.AttributeManager
' Find all attribute sets named "SampleSet".
Dim foundEntities As ObjectCollection
Set foundEntities = attribMgr.FindObjects("SampleSet")
MsgBox "Found " & foundEntities.Count & " entities."
End Sub
You can see this is much easier, and faster, than looking through all of the entities to see if they have a particular attribute set.
There are three different Find methods to choose from and you’ll choose one over the other depending on which type of object will be the most convenient for you to use in your program. The three find methods are FindAttributes, FindAttributeSets, and FindObjects. All three of them take the same input arguments and do the same type of search with the only difference being what they return. The FindAttributes method returns a list of Attribute objects as an AttributesEnumerator object. The FindAttributeSets method returns a list of AttributeSet objects as an AttributeSetsEnumerator object. The FindObjects returns a list of entities as an ObjectCollection object.
The three Find methods have three arguments. The first is the name of the attribute set, the second is the name of the attribute, and the third is the value of the attribute. You can use wild cards when searching. For example if I had added the following attribute sets to several different entities, SampleSet1, SampleSet2, SampleSet3, and SampleSet4, the following query would find and return all four attribute sets. Notice the asterisk wild card at the end of “SampleSet”
' Find all attribute sets named "SampleSet".
Dim foundSets As AttributeSetsEnumerator
Set foundSets = attribMgr.FindAttributeSets("SampleSet*")
The following query will find all attribute sets named “SampleSet” that contain an attribute named “TableType”.
' Find all attribute sets named "SampleSet".
Dim foundSets As AttributeSetsEnumerator
Set foundSets = attribMgr.FindAttributeSets("SampleSet", _
"TableType")
This last one find all attribute sets that have an attribute whose value is “ACME Fastener”.
' Find all attribute sets named "SampleSet".
Dim foundSets As AttributeSetsEnumerator
Set foundSets = attribMgr.FindAttributeSets("*", "*", _
"ACME Fastener")
As discussed above, the various find methods return different types of objects. Frequently you may have a reference to one type of object but also need the associated objects. We’ve already seen how how you can walk down the object model from an entity to get an associated AttributeSet object and from the AttributeSet object to get the Attribute objects. You can also walk up the object model. If you start with an Attribute object you can use its Parent property to get the AttributeSet object it is associated with. You can use the Parent property of the AttributeSet object to get the parent AttributeSets object. And finally, you can use the AttributeSets object’s Parent property to get the entity the attribute set is associated with.
Why Use Attributes?
A common question when first learning about attributes is “why/how would you use them?”. Attributes don’t do anything by themselves but only serve as a tool to enable other things. Because of this they are used in many different ways for many unique applications. Here are a some examples that illustrate how attributes can be used. They also demonstrate why you would choose one of the find methods of the AttributeManager object over another.
Probably the most common use of attributes is for naming an entity so you can find it later. For example, you might be automating the creation of an assembly and need to find the entities that will be used as input when creating constraints to position the parts in the assembly. One approach is to add an attribute set to the entity so you can use one of the AttributeManager find method find it later. In this case it’s the entity that’s of interest and the attribute is just serving as the mechanism to find the entity and using the FindObjects method makes sense because it directly returns the object so you can easily use it to create the constraint.
Another common example of the use of attributes is adding additional information to an entity that’s important for your application. For example you might write a program to create a custom table in a drawing. In this case each row of the table represents something unique to your application is not something that Inventor is aware of. You can use the API to create a custom table with the data you want to display but you can also add an attribute set to the custom table that contains additional information that will be useful to you to understand where the data in the table came from so you can easily update it. In this case it’s probably the AttributeSets object that’s the most interesting since it gives you easy access to the attributes to allow you to query them to determine the table information. Using the FindAttributeSets method makes more sense in this case.
Here’s an example where Inventor takes advantage of attributes. I talked this in a previous post, http://modthemachine.typepad.com/my_weblog/2009/04/controlling-layers-in-your-flat-pattern-export.html. In this example, you add attributes to the edges of a flat pattern and the translator will use the attributes to determine which layer to create the corresponding geometry on.
Another example is face colors. You can right-click on a face in a part and select the Properties command to change the color of that face. Internally, Inventor remembers the color you selected by adding an attribute to that face that has the name of the color.