mdlModelRefList_getCount gives unexpected results

I am working with Microstation SS3 and using this code:

fObjP = mdlDgnFileObj_getMasterFile();   
refListP = mdlDgnFileObj_getModelRefList(fObjP);
modelCnt = mdlModelRefList_getCount(refListP);

The results of this always return either 1 or 2. Some files that have 4 models (as shown in the Models dialog in Microstation) only return 2. Some files that have only 1 model return 2. Most files return 1 and correctly match what the Models dialog shows. But I am getting a mismatch for around 10% of my sample files.

Is the mismatch a sign of file corruption? Or is there something I am not understanding about how this function works?

  • Hi Ken,

    just a quick thought: mdlDgnFileObj_getModelRefList returns a list of loaded models. This term is not explained in MDL API documentation, but I guess it's not equal to the number of models in the design file. Some model are not necessarily loaded automaticaly, usually because they are not required for MicroStation operation.

    What information do you need to obtain? There is mdlDgnFileObj_getModelCount function available or you can iterat through all models and to get details about them (including e.g. hidden models).

    With regards,

      Jan

  • Some files that have only 1 model return 2.

    Not all models are visible DGN models that a user can edit.  There is a non-model cache (a.k.a. control element cache) and maybe some others, depending on the state of the DGN file.

     
    Regards, Jon Summers
    LA Solutions

  • mdlDgnFileObj_getModelCount is accurately reporting what shows in the Model’s dialog, so that’s good.

    But if I use that count to try to iterate through all the models to look at the reference attachments it will throw an exception using this code. The modelCnt = mdlModelRefList_getCount(refListP) function works ok with this code.

        
        refListP = mdlDgnFileObj_getModelRefList(fObjP);
         modelCnt = mdlDgnFileObj_getModelCount(fObjP);

        for(cnt = 0; cnt < modelCnt; cnt++)
        {
            modelRefP = mdlModelRefList_get(refListP, cnt);
            mdlModelRefIterator_create (&iterator, modelRefP, MRITERATE_PrimaryChildRefs, 0);
        
            while (NULL != (modelRef = mdlModelRefIterator_getNext (iterator)))
            {
                mdlModelRef_getDisplayName (modelRef, mdlName, MAX_MODEL_DISPLAY_LENGTH, NULL);                         
                mdlRefFile_getParameters(refFile, REFERENCE_ATTACHNAME, modelRef);
            }
        }

  • Hi Ken,

    I have to repeat my question: What do you want to achieve / what information do you want to obtain?

    The current discussion looks to me more like a learning / investigation what MDL functions does. I see no problem with that, but my feeling is this is not the primary goal and you need to do something (not expressed as MDL functions).

    From your code I guess you want to take all models in the opened design file and to obtain all direct reference attachments at these models. Is it correct?

    it will throw an exception using this code.

    Where the exception is thrown? And what type of exception?

    From "exception handling" perspective your code is buggy, because there is not a single check for values returned by the functions (the only exception is while condition). In such code it's easy to continue towards to exception with NULL or not valid value returned from previous function, but not tested for its validity.

    But if I use that count to try to iterate through all the models to look at the reference attachments

    In your original question you wrote mdlDgnFileObj_getModelRefList returns not expected results. So why do you use it again in your code? In my opinion we both with Jon expressed our doubts this function can be used to obtain simple direct access to models in active design file.

    The documentation states clearly DgnModelRefList contains loaded models. Do you ensure the model in active design files are all loaded before you will work with them?

    Also your code is bad because you don't do any check what type of model do you receive from mdlModelRefIterator_getNext. As Jon wrote, there are several different types of models, some from them are internal. I assume normal MDL functions work fine any type of model, but you should always access models accessible to users.

    I recommend to use mdlDgnFileObj_traverseModelIndex to iterate through models in the active design file and for every received model to evaluate whether it's "user's model" (not hidden, a proper type like design or sheet...). I used this approach several times in the past and it works fine.

    With regards,

      Jan

    P.S. Please use Insert code tool every time you post a code snippet. To post the code as normal text is so ugly...