At the beginning of 2017 I had discovered a bug related to the model/attribute association process. Let me begin the discussion by clarifying what I mean by association and how it differs from modeling information.
Association Vs. ModelEntityItems
In the attribute system you can model various information including:
Basic Data (ints, doubles, strings)
Date/Time Information (this is being added as I write this)
References to existing information (through Attribute References - for example you can refer to an attribute that represents a function)
Model Information (a reference to part of the geometric domain)
Groups of various information
This information is modeled by various Item objects that are contained within an attribute object.
In addition the attribute system provides a mechanism for associating the information contained within an attribute to parts of the geometric model (as well as auxiliary geometry contained in the geometric model). An association is conceptually different from the Model Entity Item. It represents a bi-directional relationship between the attribute and the model entity. For example, I can model an operation that creates an model edge between 2 vertices by an attribute that has 2 model entity items (one representing each vertex). This is not an association in that the model vertices don't know that they are being referred to by the items. Now consider the case of an attribute that represents a wall boundary condition for a CFD problem. The attribute may not contain any items at all - its mere existence represents the concept of the wall BC. When it is associated with a model face, the face can now answer the question "Am I a wall?". So an association effects both the attribute and model entity. You can ask ask attribute what model entities are you associated with and you can ask the model entity, what attributes do you have?
When the time came to be represent the association process, it was decided to use the same mechanism used to represent a Model Entity Item within an attribute. It initially made sense; however, it introduced a conceptual issue. In the case of an association, it seems best to think of it as a set of model entities. It doesn't make sense to add a model entity twice (going back to the Wall BC example, adding the face to the attribute a second time does not gain you anything). However, you might think of a situation where you might want to have the same model entity added to an item in an attribute. This is why the Model Entity Item (like the other items) have a vector like interface.
However, the Model Entity Item (in order to be used for modeling associations) behaves differently from all other Items and can cause problems. When you append a model entity to this item it first looks to see if there are any available "slots" in the vector to store it before it tries to append.
To demonstrate this consider 2 items (an int item (I) and a model entity item (M). Lets assume both are of length 4 and they are extensible. Also assume they have no defaults so all 4 values are unset. If I call append on I, the result is an item of 5 values with the first 4 not set. If I do something similar to M, I get an item with 4 values (first value is now set and the remaining 3 are not).
In order to model the set behavior requirement for associations, the item's behavior has to differ in another important aspect - it can't insert the same model entity more than once!
I propose that we create a new class to deal with model associations that provides the desired set behavior. Its interface would consist of:
numberOfValues() (or size())
requiredNumberOfValues() (or minSize())
maxNumberOfValues() (or maxSize())
begin() and end() const iterators
getAsVector() - returns the set as a vector
We could simplify things further by just returning the underlying set as a const reference (this would get rid of the interator methods)
In terms of the definition for the association - this could be stored in the Attribute definition explicitly instead of needing its own class
OK - so if you agree with the above design, I have a conceptual question. As you know SMTK consists of three resources (meshes, models, attributes). One could suggest that instead of saying an attribute is associated with a model entity, it could be associated with a part of a resource. This would mean you could associated an attribute to part of mesh or even to another attribute. Another suggestion would be to take this even further, that is to save an association is a bi-directional relationship between any two resource components (so a mesh set could be associated with a model entity, or a model entity could be associated with an attribute etc..
I don't want to support something just be complete so I would only entertain this extension if someone can come up with good use cases showing the need for this.
Questions/Comments (john 06-Jan-3017)
Just to make sure I got it:
Does the new/proposed class replace the ModelEntityItem currently used to represent associations in the Attribute class?
And there are no proposed changes to smtk::model?
One thing that is convenient for testing export scripts is that we always get the model entities back in the same order from the ModelEntityItem returned by Attribute::associations(). That might be tricky with the new class.