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.

Parents
  • 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;
            }
        }
    }

  • 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 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

  • A couple things to try:

    1) Pass TRUE to create the preferred SmartSurface representation (FALSE to create surface geometry was a V7 format legacy option so that even older versions that did not yet include a solid kernel could still render the smart surfaces/solids).

    2) Use mdlKISolid_elementToBody2 instead of mdlKISolid_elementToBody and make sure you have mdlKISolid_elementToBody2 return the body to uor transform. mdlKISolid_elementToBody tries to return the body transformed to world coordinates which can be a problem since this may scale or move the body outside the solid kernel's 1 km size box making it invalid.

    If using mdlKISolid_elementToBody2 corrects the issue with mdlKISolid_bodyToElement not creating any elements, we'll discuss what to do with that body-to-uor transforms to get those elements at the correct location/scale next.

    NOTE: mdlKISolid_elementToBody is actually documented as being deprecated in V8i:

    /*---------------------------------------------------------------------------------**//**
    * @description This function converts an element to a brep which can be a solid
    * (type 19 elements), a sheet (type 18 elements, shapes, spline surfaces, filled
    * ellipses etc.) or a wire (curves, line strings etc). If the input element is
    * a smart element, the embedded brep is returned. For all other elements, the
    * kernel in which the body is created depends on the workmode. The bodies need to
    * be deleted by the calling application after they are manipulated. This function is
    * deprecated, use mdlKISolid_elementToBody2 instead.
    * @param bodyPP OUT is the body created by the function.
    * @param edP IN is the MicroStation element.
    * @param modelRef IN indicates the model containing the element.
    * @return SUCCESS/ERROR depending on whether operation is successful or not
    * @alinkjoin usmthmdlKISolid_bodyToElement usmthmdlKISolid_bodyToElementsC
    * @group "MDL Solids API"
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    nativeCode StatusInt mdlKISolid_elementToBody
    (
    KIBODY **bodyPP, /* OUT body */
    MSElementDescr *edP, /* IN element */
    DgnModelRefP modelRef /* IN model ref */
    );



  • Would you mind to upload your test DGN file here ?

    Another thing to notice: I use mdlKISolid_bodyToElement, not your mdlKISolid_bodyToElements.



  • Text.dgn

    Please find the attached dgn file. It has only one smart surface (Text "B"). 

  • I think i understood the problem. The API is correct, but the range of the object is more and its becoming invalid. 

    Answer Verified By: Bency Gregorioz 

  • mdlKISolid_elementToBody is actually documented as being deprecated in V8i

    Yes, but it's easy to miss that note.  You could reinforce that statement by moving the function declaration to, say, mdlKISolid_deprecated.fdf.

    You've done something similar with the text API, which unhesitatingly focusses the developer's attention.

     
    Regards, Jon Summers
    LA Solutions

  • I think i understood the problem. The API is correct, but the range of the object is more and its becoming invalid. 
    If using mdlKISolid_elementToBody2 corrects the issue with mdlKISolid_bodyToElement not creating any elements, we'll discuss what to do with that body-to-uor transforms to get those elements at the correct location/scale next.

    Not sure if this means using mdlKISolid_elementToBody2 worked, but just in case, to follow up on my previous comment...here's how to account for the bodyTransform when creating elements from a body in local (solid kernel) coordinates.

    MSElementDescrP inEdP=NULL, outEdP=NULL;
    KIBODY* kBody=NULL;
    Transform bodyTransform;
    	
    mdlAssoc_getElementDescr(&inEdP, NULL, 16904L, ACTIVEMODEL, FALSE);
    mdlKISolid_elementToBody2(&kBody, &bodyTransform, inEdP, ACTIVEMODEL, 0L, FALSE);
    
    mdlKISolid_bodyToElement(&outEdP, kBody, TRUE, -1, NULL, ACTIVEMODEL);
    mdlKISolid_beginCurrTrans(ACTIVEMODEL);
    mdlElmdscr_transform(outEdP, &bodyTransform);
    mdlKISolid_endCurrTrans();
    mdlElmdscr_add(outEdP);
    
    mdlElmdscr_freeAll(&outEdP);
    mdlElmdscr_freeAll(&inEdP);
    mdlKISolid_freeBody(&kBody);



  • Yes, but it's easy to miss that note.  You could reinforce that statement by moving the function declaration to, say, mdlKISolid_deprecated.fdf.

    ...

    Future-proof: IElementGraphicsProcessor is available, with few changes, in CONNECT, whereas the mdlKISolid_api doesn't exist in CONNECT

    Seems sufficiently reinforced?



Reply Children
No Data