MSCE: Tag Set, Name and Type are reset

When creating a cell, most of the times tags are associated.

I know that tags are old-fashioned but we have to keep it this way.

For some reason, in some cases, the Set, Name and Type of the tag are cleared while its actual value remains.

I haven't figured out when and why these attributes are reset but I know for sure it's not done programmatically.

For instance, we design a floor-map from the contents of our database.

This map consists, among others, of rows that contains racks. (see image)

Each row has a few tags reporting some database attributes.

It appears that at the end of the drawing, the tags of all rows are resets except for the last row drawn.

Maybe it has something to do with the tag attributes that are set to TAG_PROP_DISPOFF. I couldn't figure out what the other attributes TAG_PROP_* stand for.

The tags are created as follows (this is only part of the code; it should be the significant part):

long CellCreator::createCell()
{
  // Create cell with its various elements
  ....

  // Add to file
  long file_pos;
  file_pos = mdlElmdscr_add(descr);

  // Determine tags to add
  // Done if there are no tags
  // getTagSetName() and getTags() are virtual methods of this class
  WString  tag_set_name;
  CellTags tags;
  tag_set_name = getTagSetName();
  tags = getTags();
  if (tag_set_name.empty() || tags.empty())
    return (file_pos);

  // Ricreate set
  DgnTagDefinition*  tag_def;
  CellTags::iterator tag_it;
  int                nr_tags;
  int                index;
  nr_tags = (int)tags.size();
  tag_def = new DgnTagDefinition[nr_tags];
  memset(tag_def, 0, sizeof(DgnTagDefinition) * nr_tags);
  index = 0;
  for (tag_it = tags.begin(); tag_it != tags.end(); tag_it++)
  {
    wcscpy(tag_def[index].name, tag_it->first.GetWCharCP());
    tag_def[index].propsMask = TAG_PROP_DISPOFF;
    tag_def[index].value.SetTagValue((long)0);
    index++;
  }
  mdlTag_deleteSetDef(tag_set_name.GetWCharCP(), 0, ACTIVEMODEL);
  mdlTag_createSetDef(tag_set_name.GetWCharCP(), NULL, 0, tag_def, nr_tags, ACTIVEMODEL);
  delete[] tag_def;

  // Determine cell ID
  ElementId element_id;
  cell = new MSElement();
  mdlElement_read(cell, ACTIVEMODEL, file_pos);
  element_id = mdlElement_getID(cell);
  delete cell;

  // Prepare tags
  DgnTagSpec tag_spec;
  UShort     tag_attr;
  memset(&tag_spec, 0, sizeof(DgnTagSpec));
  wcscpy(tag_spec.set.setName, tag_set_name.GetWCharCP());
  tag_spec.set.modelRef = ACTIVEMODEL;
  tag_attr = TAG_PROP_DISPOFF;

  // Create tags
  DgnTagValue value;
  MSElementP  tag;
  tag = new MSElement();
  for (tag_it = tags.begin(); tag_it != tags.end(); tag_it++)
  {
    wcscpy(tag_spec.tagName, tag_it->first.GetWCharCP());
    value = tag_it->second;
    mdlTag_create(tag, NULL, &tag_spec, &tag_attr, &value, &element_id, NULL, NULL, NULL, NULL, NULL);
    mdlElement_add(tag);
  }
  delete tag;

  // Done
  return (file_pos);

} // createCell

We use MSCE version 10.16 with corresponding MSSDK

  • I couldn't figure out what the other attributes TAG_PROP_* stand for

    From header file ../include/DgnPlatform/DgnPlatform.r.h...

    enum TagProperty
    {
    TAG_PROP_DISPOFF = (0x0001 << 0),
    TAG_PROP_DEF     = (0x0001 << 1),
    TAG_PROP_CONF    = (0x0001 << 2),
    TAG_PROP_CONST   = (0x0001 << 3),
    };
    
    • TAG_PROP_DISPOFF sets the tag display off
    • TAG_PROP_DEF indicate that the tag definition has a default value for the tag. Used if user does not supply a value
    • TAG_PROP_CONF user must confirm
    • TAG_PROP_CONST tag value is constant and user cannot change it

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    Thanks for the reply. At least now I know what these attributes mean.

    I guess TAG_PROP_DEF and TAG_PROP_CONF are not relevant for my case.

    I tried creating tags with the 4 possible combinations of the other 2 attributes but unfortunately the result is the same: most of the times the Set and Name of the tag are cleared while the value remains unchanged.

  • in some cases, the Set, Name and Type of the tag are cleared

    Please clarify that statement. 

    Your code uses pointers to MSElement.  Why not use the smart pointers (ElementHandle, EditElementHandle, ElementAgenda) provided by the MicroStationAPI?

    Your code uses CellTags. Is that your class?

    Code like this is a laborious way to find an Element ID...

    ElementId element_id;
      cell = new MSElement();
      mdlElement_read(cell, ACTIVEMODEL, file_pos);
      element_id = mdlElement_getID(cell);
      delete cell;

    You can use an ElementRef to find an element quickly using the file position as an index, then get its ID.  No need for memory allocation/deallocation.

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    thanks again for your reply. I really appreciate it that you're trying to help me.

    First of all, CellTags is indeed 'my' class. It's just a map of tag-name/values.

    typedef std::map<WString, DgnTagValue> CellTags;

    I know my code is quite laborious but since I'm porting a lot of code from V8i to CE, I prefer not to rewrite everything. We're talking about more than 1 million lines of code in 100+ MDL applications.

    The point is that when drawing, for some reason the tag set, name and type of a cell are sometimes cleared as shown in the images I attached in the original question.

  • the tag set, name and type of a cell are sometimes cleared

    Do the tag elements continue to exist in your DGN model?  A tag is associated with its host: the tag stores the host element ID.  If the association is lost, then the host ID may have been invalidated.

    Check the cell element ID (your tags' host element) before and after the tags are 'cleared'.  If the cell ID has changed after a rewrite that could explain the problem.  The tag elements could still exist but are now orphans.

     
    Regards, Jon Summers
    LA Solutions

    Answer Verified By: Robert Kock 

  • I adjusted my code so that it logs the ElementID of the cell before adding the tags (directly after 'mdlElement_getID').

    After all cells were created, I checked the ID with the one reported within the 'properties' dialog (as in the image attached to the original question).

    These IDs are the same.

    By the way, I checked ElementHandle::GetElementId as well and it returns the same result.

  • I found it!!!

    When creating the tag set definition, I deleted the existing one.

    Instead, I should create the definition only in case it doesn't exist yet (when mdlTag_getSetDef returns an error).

    Thank you so much for your help.