[Connect | V8] [C# | C++ SDK] Finding Xattributes quickly and selectively, without the detour via "search element"?

To work with Xattributes, you need an ElemendHandle whether you work in managed or native code.

 

But what will be best practice to find some elements in such a case:

  • DGN with some several thousand elements
  • Some 3% elements with Xattributes
  • Some 20% of these have an interesting XAttributeHandlerId

The typical workflow: “scan for elements” -> “test for X-Attributes” -> “find XAttribute with XAttributeHandlerId” -> “analyses X-Attributes” will take its time.

 

Would it not be much faster, to scan through the Xattributes-cache for fitting XAttributeHandlerId?

Parents
  • We use this to find all the elements with a particular xattributeID.

    ScanCriteria                *pScanCriteria = NULL;
                ScanArgs                    scanArgs;
                DgnModelRefP modelRef = ISessionMgr::GetActiveDgnModelP();
                
                memset(&scanArgs, 0, sizeof(scanArgs));
    
                if (NULL != (pScanCriteria = mdlScanCriteria_create()))
                {
                   scanArgs.modelRef = modelRef;
                   
                   mdlScanCriteria_setReturnType(pScanCriteria, MSSCANCRIT_ITERATE_ELMREF, FALSE, FALSE);
                  
                   XAttributeHandlerId id = XAttributeHandlerId(XYZID, 0); //need to use your details here...
                   mdlScanCriteria_setXAttributeTest(pScanCriteria, &id, XAttributeHandle::MATCH_ANY_ID, NULL);
                   scanArgs.id = id;
                   mdlScanCriteria_setElemRefCallback(pScanCriteria, (PFScanElemRefCallback)getElementScanCallback, &scanArgs);
    
                   mdlScanCriteria_setModel(pScanCriteria, modelRef);
    
                   mdlScanCriteria_scan(pScanCriteria, NULL, NULL, NULL);
                   mdlScanCriteria_free(pScanCriteria);
                }

    Then your iterator callback will get each of the elements that meet the xattribute id.  I know it does not avoid the scan thing but is has bee quick enough for us.

    HTH,

    marka

    Answer Verified By: Volker Hüfner 

  • Hi Mark,

    nice to hear from you again :-)

    I tried this mdlScanCriteria_setXAttributeTest() yesterday (Thanks to Jan) but I did not get it linked.

    "xattributes.obj : error LNK2019: unresolved external symbol "int __cdecl mdlScanCriteria_setXAttributeTest(struct scanCriteria *,struct Bentley::Ustn::Element::XAttributeHandlerId *,unsigned int,struct ExtendedAttrBuf *)" (?mdlScanCriteria_setXAttributeTest@@YAHPAUscanCriteria@@PAUXAttributeHandlerId@Element@Ustn@Bentley@@IPAUExtendedAttrBuf@@@Z) referenced in function _FunktionName"

    I tried with SDK MicroStation 08.11.07.171, 08.11.09.459 and AECOsim 08.11.09.750.

    I did some investigations, the function is mention in "mdlbltin.lib" but not as expected in some dll like "stdmdlbltin.dll" where the other "mdlScanCriteria_set...Test()" functions are defined.

    How did you, or @Yongan.Fu get access to this function?

    Here is my (do nothing) snippet, just to verify mdlScanCriteria_setXAttributeTest() could linked. I placed it in an existing project, which uses mdlScanCriteria_set... funktions.

    #if defined (vp_vohu)
    // vohu KLAMMER Scan Test 
    
    Public int mdlScanCriteria_setXAttributeTest
    (
       ScanCriteriaP scP,
       struct Bentley::Ustn::Element::XAttributeHandlerId* handlerId, // Pass NULL to clear
       UInt32 attrId, // Pass XAttributeHandle::MATCH_ANY_ID for any.
       ExtendedAttrBuf* xattrBuf // Can be NULL
    );
    
    DLLEXPORT Int32 FunktionName()
    {
       XAttributeHandlerId h_XAttrID(AB_Date_ID, 12);
       Int32  nRetErfolg = mdlScanCriteria_setXAttributeTest(NULL, &h_XAttrID, XAttributeHandle::MATCH_ANY_ID, NULL);
       return (nRetErfolg);
    }
    
    #endif
    
    

    Mit freundlichen Grüßen / Best regards
    Volker Hüfner

    |  AB_DATE Engineering  Software   |  ab-date.de  |

  • The function is exported from mdlbltin.lib but there is not definition in the header files.  You will have to create your own like we did.  Here is the definition that should work for V8i:

    Public int mdlScanCriteria_setXAttributeTest
    (
    ScanCriteriaP scP,
    void* handlerId, // Pass NULL to clear
    UInt32 attrId, // Pass XAttributeHandle::MATCH_ANY_ID for any.
    ExtendedAttrBuf* xattrBuf // Can be NULL
    );

    HTH,

    marka

  • Hello ,

    I shout Heureka!

    During my experimenting with the second - different from Yongan.Fu's prototype -   parameter in my declaration I stumped over extern "C" and suddenly with: extern "C" Public int mdlScanCriteria_setXAttributeTest(...) both versions linked.

    I guess I have overseen extern "C", because it is normally allover a header-file.

    Thank all of you so much!

    Volker

    Mit freundlichen Grüßen / Best regards
    Volker Hüfner

    |  AB_DATE Engineering  Software   |  ab-date.de  |

Reply Children