[CONNECT C++] EXTENDED_ELM used for different elements. How to tell what they are?

I have a Connect DGN with two types of elements that both return a 106 element type (EXTENDED_ELM).  

One is a Prosteel3D component and the other is a Table.

Is there a good way to work out which is which?

And I guess Extended Elements could cover many other types of elements too? 

I am using MicroStation Connect Update 14 to read a file containing OpenBuilding Update 7 elements.  

Cheers.

Parents
  • Hi Stirling,

    please respect the best practices and always specify (e.g. using recommended subject format) used product, its version and used API / language. Often it's quite complicate to provide right answer or even a simple guess without knowing these information.

    I have a Connect DGN with two types of elements that both return a 106 element type (EXTENDED_ELM).  

    To use element type information is not recommended, it's treated as "old style" in CONNECT Edition. It's fine in many cases, but typically fails (as in your case) when working with new elements (parametric solid) or with discipline specific objects.

    And I guess Extended Elements could cover many other types of elements too? 

    Yes, type 106 (extended graphic) and type 107 (extended nongraphic) are used to store different types of elements.

    Is there a good way to work out which is which?

    It's not clear from your post what API do you use and how do you retrieve the elements (scanning, modification tool...).

    But in general, the recommended way to identify "type of object" as seen by a user, is to check relevant ElementHandler. When you will search this forum for "type 106" and "type 107", you will find many discussions how to do it in C++ and NET.

    With regards,

      Jan

  • Yes probably assuming like a programmer assumes the users understand a program.

    Scanning a DGN using the old school mdlScan_ functions.  Is there a better way? I am exporting a DGN file into a new format.

    I did look in the existing posts and did not find anything relevant.  Not to say it is not there but I did not see anything. 

    I finally found I can call "Handler::GetTypeName(WStringR string, UInt32 desiredLength) to get what is displayed in MicroStation info.  That may be good enough.  When I transfer on to OpenBuilding, OpenRoads etc I guess I will get more options.

    Cheers

  • Element Collections

    Scanning a DGN using the old school mdlScan_ functions.  Is there a better way?

    The MicroStationAPI provides element collections for the C++ developer: read this article.  Reading between the lines of responses here by Bentley Systems staff, those collections call the scan functions internally.

    In general, the collections are easier to use than the scanner.  There is one remaining use for the scanner, when you want to perform a range test on graphic elements.

    Element Handlers

    EXTENDED_ELM used for different elements. How to tell what they are?
    The recommended way to identify "type of object" as seen by a user, is to check relevant ElementHandler

    For example, here's a test for a TextTable element...

    TextTablePtr    TextTableHelper::GetTableSeed  (DgnModelP  model)
    {
      TextTablePtr  seed;
      const UInt32  nElements = model->GetElementCount (DgnModelSections::GraphicElements);
      if (1 == nElements)
      {
        PersistentElementRefList const*  elemList = model->GetGraphicElementsP ();
        if (nullptr != elemList)
        {
          for (PersistentElementRefP const& elemRef: *elemList)
          {
            ElementHandle    eh {elemRef, model};
            TextTableHandler*  handler = dynamic_cast<TextTableHandler*>(eh.GetDisplayHandler());
            if (nullptr != handler)
            {
              seed  = handler->ExtractTextTable (eh);
            }
          }
        }
      }
      return seed;
    }
    

    In some cases you may find a shortcut to the dynamic_cast<TextTableHandler*>(eh.GetDisplayHandler()) idiom. Look at ElementHandle::GetITextQuery().

     
    Regards, Jon Summers
    LA Solutions

    Answer Verified By: Stirling Hamersley 

  • Scanning a DGN using the old school mdlScan_ functions.  Is there a better way?

    It depends on specific context.

    But it has been discussed several times that in CE, the recommended way is to simple iterate model collection (or graphic element cache only) and to implement of "scan criteria". The only exception, when to use scan API, is when range criteria is used.

    I used to use this approach both in C++ and NET code and it's convenient and very fast.

    I am exporting a DGN file into a new format.

    If you are interested in geometry only, IElementGraphicsProcessor can help you.

    I did look in the existing posts and did not find anything relevant.  Not to say it is not there but I did not see anything. 

    Hmm ... I found many discussions. It's true not always code is discussed, but they provide very good insight about the difference between element type (old API) and new approach based on ElementHandlers.

    I finally found I can call "Handler::GetTypeName(WStringR string, UInt32 desiredLength) to get what is displayed in MicroStation info.  That may be good enough.

    No, it's wrong (e.g. it's localization dependent, and can be even changed by a user). Plus, it's pretty slow.

    The right way is to try to cast (see e.g. this discussion) general ElementHandler to specific handler. When it's not null, it's the type. But, because of structures like mentioned IElementGraphicsProcessor, often there is even no need to know exact element type, because API handles different types automatically.

    [EDITED] See Jon's code snippet how to cast, it's the right way.

    With regards,

      Jan

  • One more note related to casting: To stay away from technical /language aspects and details about casting, CE API approach is based on encapsulation of data persistence (e.g. in DGN format) and related functionality into classes:

    • Element is represented by its handle (ElementHandle or EditElementHandle)
    • Functionality is provided by ElementHandler plus specialized interfaces (e.g. ITextQuery...). It means for every "user element", as represented in MicroStation, exists ElementHandler, plus the element can optionally offer further functionality.
    • Every handle can provide its relevant ElementHandler. It's possible to obtain Handler, DisplayHandler etc. that are common classes.
    • The mentioned dynamic cast of generic Handler to specific Handler, as demonstrated in Jon's code, is like asking whether specific functionality is supported.

    With regards,

      Jan

  • Thanks for the details.  I have quite a few detailed classes developed and based on the original C libraries to provide powerful yet simple methods of quickly filtering and processing and modifying models using limited lines of code. Naturally they were heavily dependent on scan criteria and element descriptors.

    I am looking to changing over the using the new class structures.

    How do the new methods compare with regard to overheads for filtering given that I assume more of that has to be handled externally?

    For example to only return elements of a specific criteria I will need to iterate all elements and compare.  That may include checking the availability of a handler or returning the type, checking a cell name etc. 

    Do you think the low level functions will eventually become deprecated? 

  • Naturally they were heavily dependent on scan criteria and element descriptors.

    It's not in conflict with CE API at all. It has to be distinguished between obsolete (or deprecated) and not recommended features. Both scan criteria and element descriptors are 100% supported, but new features can be (like e.g. parametric solids) implemented in a different way, using new approach and API, not fully supported in "classic APIs".

    I am looking to changing over the using the new class structures.

    Fortunately "classic" and "new" can be (and maybe sometimes has to be) combined into a hybrid code. To move between element descriptors (should be abandoned) and new ElementHandles and their handlers, when necessary, is possible.

    If you did not attend Migration workshop, I recommend to check MicroStationCONNECT_MigrationWorkshop.pptx, delivered with MicroStation SDK. Directions and conceptual changes are mentioned there (e.g. nesting is bad, stay away from complex elements, MSElement, MSElementDescriptor...).

    How do the new methods compare with regard to overheads

    What overhead do you mean? Do you expect the internal code (element scanner) is a kind of magic, so it does not need to iterate a cache and to compare element types? Of course element scanning is highly optimized low-level code, so it's fast. On the other hand its API is general, so it has to evaluate a lot settings and conditions, whereas simple iteration can be optimized exactly to particular application needs.

    That may include checking the availability of a handler or returning the type, checking a cell name etc. 

    Do not assume, measure! Only benchmark can provide answer what approach is the best. My experience is that simple iteration is often faster, but in fact, the scanning itself is always so fast (exceptions exist), that there is no difference for a user between iteration and scan criteria API. But I think simple iteration can be maintained easier and optimized better (again, exceptions exist).

    Even when I am not sure about C++, what I know is that, probably in all OOP languages, operations with classes are heavily optimized, because to be able to check at runtime the class and from what class(es) it's inherited, is native feature of the language itself. So even when it looks weird, to e.g. cast a class is very fast, for sure several times faster than to compare string (which is one from the slowest thing at all).

    Do you think the low level functions will eventually become deprecated? 

    I do not think it will be deprecated anytime soon. It makes no sense.

    But as discussed, it's not usable for new features, and in such case it should be replaced or implemented as hybrid (when legacy code is used). It's possible to use scan API and MSElementDescr, filter type 106 elements, create element handle, obtain element handler and to test real object type, stored in 106 element.

    I am looking to changing over the using the new class structures.

    It's not about to go from element descriptors to handlers only, in some situations completely new approach is available (or even mandatory). E.g. to obtain element graphics, to scan and work with element descriptors was standard. Now to use IElementGraphicsProcessor is recommended, and for some objects it's the only way.

    Completely new approach, that can be also used for scanning, is to use ECQuery. It can replace scan criteria API and also model/cache iteration completely. But it's not direct replacement, it's an alternative. I am not sure about performance, I guess it's probably a bit slower, even when heavily optimized at low level (but I have not done any benchmarks yet). On the other hand it allows to define searching and criteria in a different way.

    With regards,

      Jan

    Answer Verified By: Stirling Hamersley 

Reply Children
No Data