mdlKISolid_bodyToElements is returning success but no elements

Hi.

I am getting the body from element descriptor as follows:

int iStatus = mdlKISolid_elementToBody(kBody, pElemDescr, m_pDgnModelRef);

Later, using mdlKISolid_bodyToElements() API as follows to get the elements from body. But this API neither crashing or returning a fail error code. Instead it is returning success but there is no elements. 

try
{
            iStatus = BSIERROR;
            int iStatusLocal = mdlKISolid_bodyToElements(pElemDescr, kBody, FALSE, -1, NULL, m_pDgnModelRef);
           mdlKISolid_free(kBody);
           if (BSISUCCESS == iStatusLocal)
                     iStatus = BSISUCCESS;
}
catch (...)
{
         iStatus = GOTEXCEPTION;
}

Any other way to get the elements? Any better suggestion. 

Thanks in advance.

Sampath.

  • Hi Bency,

    please read and follow this forum best practices! Without knowing product and a version (build number) you use, it's hard to answer you question.

    Also, please user Insert > Insert code tool every time you post a code snippet. To read code formatted as a plain text is confusing (plus the tool is able to colorize C++ and C# code nicely).

    Any other way to get the geometry?

    What is your intention? What exactly do you need? Pure geometry (faces, vertices, edges)? And what type of element do you expect?

    Any better suggestion. 

    The simplest way I know is to use IElementGraphicsProcessor, but without knowing what version do you use and also what element type(s) you want to process (solid, SmartSolid, parametric solid...), it's hard to guess more.

    With regards,

      Jan

  • Thanks jan for quick response.

    I need smart solid. If i use mdlKISolid_satDataFromElement() this API, all the Smart Surfaces in the dgn file are getting properly. But this is an undocumented API and there are lots of crash for other dgn files and even the Bentley help suggested not to use this API.

    I am working on Microstation V8i (08.11.09.357) and SDK MicroStation V8i SDK 08.11.09.292.

  • I need smart solid.

    I guess not, because you wrote that you call the function to get the geometry. SmartSolid is an "MicroStation element", stored in DGN as a cell with extra information attached. It's the reason why I ask what exactly from geometry do you need.

    I am working on Microstation V8i (08.11.09.357) and SDK MicroStation V8i SDK 08.11.09.292.

    Why do you use different SDK than MicroStation? For MicroStation 08.11.09.357 (which is very old version btw), the same SDK build .357 was released. Probably not big issue in this case, but it's a general recommendation to always use the same SDK as MicroStation.

    Any other way to get the geometry?

    My previous answer is still valid: See IElementGraphicsProcessor, which is part of new C++ MicroStationAPI, available I guess from V8i SS3 (?). I have no experience with this mechanism in V8i, but it's widely used in CE (and in some scenarios it's the only way). It allows to decompose any MicroStation graphic element into components, depending on class configuration.

    With regards,

      Jan

  • How is pElemDescr declared? You've passed a variable called pElemDescr into both mdlKISolid_elementToBody and mdlKISolid_bodyToElements, but one takes an MSElementDescr* for an existing element and the other takes an MSElementDescr** to allocate and return a new element. So if pElemDescr is declared as MSElementDecr* pElemDescr = nullptr; you'd do this: mdlKISolid_bodyToElements(&pElemDescr, ...).

    -B

    * kBody passed to mdlKISolid_elementToBody looks suspicious as well...if this is a KIBODY** then it can't be passed to mdlKISolid_bodyToElements/mdlKISolid_free that require a KIBODY*...



  • MSElementDescr* pElemDescr = NULL;
    
    ProcessElementByBodies(&pElemDescr);
    
    
    //Defination
    void ProcessElementByBodies(MSElementDescr** pElemDescr)
    {
        int iStatus = BSIERROR; 
        KIBODY* kBody = NULL;
        iStatus = getBody(m_pElemDescr, &kBody);
    
        if (iStatus == BSISUCCESS && NULL != kBody)
        {
            try
            {
                iStatus = BSIERROR;
                int iStatusLocal = mdlKISolid_bodyToElements(pElemDescr, kBody, FALSE, -1, &m_pElemDescr->el, m_pDgnModelRef); 
                mdlKISolid_free(kBody);
                if (BSISUCCESS == iStatusLocal)
                iStatus = BSISUCCESS;
            }
            catch (...)
            {
                iStatus = GOTEXCEPTION;
            }
        }
    }

  • MSElementDescr** pElemDescr = NULL; // <- Incorrect

    MSElementDescr* pElemDescr = NULL; // <- Correct

    ProcessElementByBodies(&pElemDescr);

    Look at your usage of kBody as well as it appears you haven't done much with C++ pointers...



  • Sorry. Its a typo. 


    MSElementDescr* pElemDescr = NULL; This is what there in my code.

    This is the getBody() implementation : 

    int getBody(MSElementDescr*  pElemDescr,KIBODY** kBody)
    {	
    	int	iStatus = BSIERROR;
    	try
    	{
    		iStatus = mdlKISolid_elementToBody(kBody, pElemDescr, m_pDgnModelRef);
    	}
    	catch (...)
    	{
    		iStatus = GOTEXCEPTION;
    	}
    	return iStatus;
    }

    I hope you understood, how i use the kBody now. 

    BTW, i am not facing any syntactical errors or crashes with my code. Issue is with the Microstation API itself. mdlKISolid_bodyToElements() is getting success but there are no elements in it. 

    Instead of using that API, if i use mdlKISolid_satDataFromElement(), i am able to get the sat data and graphics properly. But as i said earlier, this is an undocumented API and giving crashes to other dgn files and not encouraging to use it. 

    Regards

    Sampath.

  • I have no experience with this mechanism [IElementGraphicsProcessor] in V8i

    It works well. 

    using mdlKISolid_bodyToElements() API as follows to get the elements from body

    Prefer Jan's recommendation to use IElementGraphicsProcessor.

    Why?

    • It's designed to be universal
    • You don't have to get involved in the type-unsafe mdlKISolid_api
    • You can obtain much more information than just solid-to-elements
    • Less memory-management required
    • Object-oriented: more classes, fewer untyped pointers and pointer-to-pointers
    • Future-proof: IElementGraphicsProcessor is available, with few changes, in CONNECT, whereas the mdlKISolid_api doesn't exist in CONNECT

     
    Regards, Jon Summers
    LA Solutions

  • I wrote a simplest test code snippet without any error check. It works well for my attached test.dgn. FYI.

    void kiSolidTest()
    {
    	MSElementDescrP inEdP=NULL, outEdP=NULL;
    	KIBODY*  kBody=NULL;
    	mdlAssoc_getElementDescr (&inEdP, NULL, 16904L, ACTIVEMODEL, FALSE);
    	mdlKISolid_elementToBody(&kBody, inEdP, ACTIVEMODEL);
    	mdlKISolid_bodyToElement(&outEdP, kBody, FALSE, -1, NULL, ACTIVEMODEL);
    	mdlElmdscr_add (outEdP);
    	mdlElmdscr_freeAll (&outEdP);
    	mdlElmdscr_freeAll (&inEdP);
    	mdlKISolid_freeBody(&kBody);
    }

    8712.test.dgn



  • Hi Yong.

    Its almost similar code what i have written, but the smart surfaces are not converting to elements. 

    Regards

    Sampath