Home
Reply
Contributor
Tina
Posts: 9

Problem about attributes

Hi, everyone.


I have a problem about the user-defined attributes.I create a body,then want to attach three parameters to this body(sunch as: double par[10],cstring name,int num) as attributes.I have read through the documentation about the ATTRIB class,but I do not know how to attach this three parameters together to this body?


Can you please help me?


Thanks,
Tina

Spatial Employee
asdf
Posts: 93

Re: Problem about attributes

Hi Nina

 

There are several ways to attach whatever data you want to an ACIS model, each with some benefits and some difficulties.  I will outline the three broad approaches I know.  If you have further questions after that, please reply to the post with them

 

1)  The easiest way to use ACIS attributes is to use the prewritten generic attributes.  This is broadly documented in http://doc.spatial.com/index.php/Generic_attributes. You can attach a named integers, positions, reals, etc.  With this approach you would need multiple attributes to store the data you describe, but you wouldn't have to write any attribute classes yourself.  On the other hand, you would need to attach a lot of attributes per entity which isn't optimal.

 

2)  You could write your own attribute class.  ATTRIB, by itself, is a base class.  There are many callbacks you may need to think about and override if you do this.  The basics are outlined at http://doc.spatial.com/index.php/Attribute_Notification_Methods.  Basically, an attribute needs to know what to do if its owner is transformed, copied, replaced, etc.  There are trivial things to do in this situation (basically just lose() the attribute) but that might not be what your application needs.

 

There are a lot of details involved in writing your own ENTITY (including your ATTRIB which is derived from ENTITY).  But your application will perform better and the code will probably be more cohesive if all the data is in one attribute.

 

3) A third option which just occurred to me as I was writting the first two is to use a dictionary or map of some kind, where the keys are entity pointers and the values in the dictionary are whatever data you want to store.  A particularly sophisticated variation of this approach would be to use SPACOLLECTION (c.f. http://doc.spatial.com/index.php/SPACOLLECTION) for the keys.  A SPACOLLECTION is a list of ENTITY's that is notified when anything happens to any of the ENTITYs it points to.  A SPACOLLECTION has a LIST_HEADER (the guts of ENTITY_LIST) in it, so it doesn't allow repetitive ENTITY pointers.

 

The code for this suggestion would like something like the following

 

struct my_data

{

// whatever particular data you want 

};

 

class my_map

{

  SPACOLLECTION m_keys;

  std::vector<my_data> m_data;

public:

   void add( ENTITY* e, my_data const& d)

 {

      if( -1 != m_keys.lookup( e ) )

      // m_keys.lookup(e) returns the index of e in the list, or -1 if it isn't in the list.

      // should throw an error if you try to add something that's already in the list.

      {

           throw new std::string("oops: don't add same entity more than once");

      }

      else // because of the throw, the else is redundant.  we can assume -1==m_keys.lookup(e); if we reach this code

      {

          m_keys.add_ent(e);

          m_data.push_back( d );

          ASSERT( m_keys.iteration_count() == m_data.size() );

      } 

 }

 

 my_data const& lookup( ENTITY* e)

 {

      int idx = m_keys.lookup(e);

      if( -1 == idx )

      {

           throw new std::string("oops.  no data attached to this entity");

      }

      else

      {

            ASSERT( idx < m_data.size() );

           return m_data[idx];

      }

  }

};

 

After writing this message, I am starting to think (3) might be pretty easy to deal with.  If you add data for an ENTITY and the entity is deleted, it will be removed from the SPACOLLECTION (resulting in a null or a tombstone in the entity list ).  The associated data wouldn't be deleted in this case but it would be when the list was cleared.  You could also use std::map, but it wouldn't know when you deleted the changes or entity underneath.

 

Depending upon the particulars of what you want to do, and how much coding and learning ACIS architecture you are up for any of them could work.  If you are not actually doing any editing of the 3d model, a straight std::map or a hash map would work nicely.  If you are editing the model and would need entity changes to be tracked by the data, you could do that with 3) or with 2).  Writing your own ATTRIB is nontrivial but it still may be the best way to do it depending upon what you need.  After you read the docs I linked to in this message, you may have more information about the details of what you would need to do. 

 

best regards.  please let us (this forum) or support services know if you have further difficulty.

 

Eric Zenk

 

 

Contributor
Tina
Posts: 9

Re: Problem about attributes

Thank you for your help.It help me a lot.

 

Tina

Spatial Employee
asdf
Posts: 93

Re: Problem about attributes

I just noticed that the code segment for using SPACOLLECTION is incorrect, because SPACOLLECTION is an entity, so it cannot be put on the stack.  Rather, the map should have a SPACOLLECTION*; the constructor should make a new SPACOLLECTION, and the destructor should clear the list and lose it.  Sorry for the error in the code sample.  what I previously posted won't compile as is; I think the idea is still reasonable though, with the corrections just noted.

 

Eric

Contributor
Tina
Posts: 9

Re: Problem about attributes

Thank you very much.

 

Tina