Usage of mdlMaterial_functions

Hi Folks,

Is there any body used mdlMaterial_functions in mdl programming.
Iam trying to use the material functions to assign or attach materails to the the building faces.
I found source code examples nowhere. Could you please any one share yours knowledge or any source codes ?.

Thanks in Advance

Nataraju

Parents
  • Nataraju:
    Is there any body used mdlMaterial_functions in MDL programming?

    You're right — there aren't any substantial examples.

    Getting and assigning materials is largely a matter of getting and chasing pointers. I'm not an expert in materials, so maybe someone else can chime in. Here's something to get you started:

    1. Get the material table for the current model
    2. Find the material you need
    3. Assign the material to a level or element
    
    MaterialNode    *pNode = NULL;
    DgnModelRefP	modelRef = ACTIVEMODEL;
    //Initialise materials for your MDL
    mdlMaterial_initialize ();
    mdlMaterial_getTable (&pNode, modelRef);
    if (NULL != pNode)
    {
       MaterialNode    *pCurrent = pNode;
       while (pCurrent)
       {
         //Do something with pCurrent
         pCurrent = pCurrent->next;
       }
       //	To Clean up the material Node when done use :
       mdlMaterial_deleteNode (&pNode, pNode, modelRef);
    }
    //Free materials for your MDL
    mdlMaterial_cleanup ();
    
    

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Now, when there are new types of materials, I'm not sure, whether these functions will work.

    I found this on old forum (discussion.bentley.com):

    KIBODY* sphereP;
    MSElementDescr* edP;
    ULong elmFilePos;

    // create a new element
    mdlKISolid_beginCurrTrans(MASTERFILE);
    mdlKISolid_makeSphere(&sphereP, radius);
    mdlKISolid_bodyToElement(&edP, sphereP, TRUE, -1, 0, MASTERFILE);
    mdlKISolid_freeBody(sphereP);
    mdlKISolid_endCurrTrans();

    // Write it to the design file
    elmFilePos = mdlElmdscr_add(edP);

    // create a material attachment linkage
    {
    MaterialLinkageData data;
    LinkageHeader linkHdr;
    memset(&linkHdr, 0, sizeof(linkHdr));
    linkHdr.primaryID = LINKAGEID_Material;
    linkHdr.user = 1;
    strcpy(data.name, "Blue");
    data.nameSize = strlen(data.name);
    printf("appendUsingDescr\n");
    if (mdlLinkage_extractUsingDescr (&data, edP, LINKAGEID_Material, 0, NULL, NULL, NULL, FALSE))
    mdlLinkage_deleteUsingDescr (&edP, LINKAGEID_Material, 0, NULL, NULL, NULL, FALSE);
    if (mdlLinkage_appendUsingDescr(&edP, &linkHdr, &data,
    LINKAGEID_Material, NULL, FALSE) == SUCCESS)
    printf("success\n");
    else
    printf("no success\n");
    printf("end\n");
    }

     

  • I was able to attach a material to an element descriptor using the code posted by Dan Paul, with the following changes:

    1. After setting linkHdr.user, call mdlLinkage_setWords(&linkHdr, sizeof(MaterialLinkageData) / sizeof(short)).
    2. Pass zero instead of LINKAGEID_Material to mdlLinkage_appendUsingDescr(), otherwise it returns an error of MDLERR_DATADEFNOTFOUND.
    3. No need to call mdlLinkage_extractUsingDescr() or mdlLinkage_deleteUsingDescr().
    4. Call mdlElmdscr_rewrite() after the call to mdlLinkage_appendUsingDescr(), or move the call to mdlElmdscr_add() after mdlLinkage_appendUsingDescr().
    5. If the material being used is not already applied to another object in the scene, the material doesn't appear in the view until either the material editor is opened, or if it is already open, until it is refreshed. A call to mdlMaterial_cleanup() seemed to fix this.

    Saxon Druce

     

  • Saxon:
    1. After setting ...
    2. Pass zero ...
    3. No need to call mdlLinkage_extractUsingDescr() or mdlLinkage_deleteUsingDescr().
    4. Call mdlElmdscr_rewrite() ...
    5. A call to mdlMaterial_cleanup() ...

    The material library is tortuous, so congrats. on navigating a path through the maze.

    1.  
    2.  
    3. No need to call mdlLinkage_extractUsingDescr() or mdlLinkage_deleteUsingDescr().
      They are there simply to illustrate how to remove a material if you want to replace an existing material with another. In this example you have a new element, so those calls don't do anything.
    4. Call mdlElmdscr_rewrite() ....
      You have to update the element in the file for your change to be persistent.
    5. A call to mdlMaterial_cleanup() ....
      Your material functions should be bracketted by mdlMaterial_initialize/mdlMaterial_cleanup. If writing C++, then encapsulate those calls in a class.

    Resource Acquisition Is Initialisation

    Put matched calls from the MDL API into a C++ struct or class constructor/destructor. That way, you can't forget the second of the matched pair:

    
    //	Class definition/implementation in MaterialAPI.h
    #include <material.fdf>
    struct CMaterialAPI
    {
        	CMaterialAPI	()	{	mdlMaterial_initialize ();	};
        	~CMaterialAPI	()	{	mdlMaterial_cleanup ();		};
    };
    //	Usage in myApp.cpp
    #include "MaterialAPI.h"
    {
         CMaterialAPI material_raii;	//	Calls mdlMaterial_initialize
          ... your code that uses mdlMaterial_xxx
    } //	Destructor called when CMaterialAPI goes out of scope: calls mdlMaterial_cleanup
    
    

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

Reply
  • Saxon:
    1. After setting ...
    2. Pass zero ...
    3. No need to call mdlLinkage_extractUsingDescr() or mdlLinkage_deleteUsingDescr().
    4. Call mdlElmdscr_rewrite() ...
    5. A call to mdlMaterial_cleanup() ...

    The material library is tortuous, so congrats. on navigating a path through the maze.

    1.  
    2.  
    3. No need to call mdlLinkage_extractUsingDescr() or mdlLinkage_deleteUsingDescr().
      They are there simply to illustrate how to remove a material if you want to replace an existing material with another. In this example you have a new element, so those calls don't do anything.
    4. Call mdlElmdscr_rewrite() ....
      You have to update the element in the file for your change to be persistent.
    5. A call to mdlMaterial_cleanup() ....
      Your material functions should be bracketted by mdlMaterial_initialize/mdlMaterial_cleanup. If writing C++, then encapsulate those calls in a class.

    Resource Acquisition Is Initialisation

    Put matched calls from the MDL API into a C++ struct or class constructor/destructor. That way, you can't forget the second of the matched pair:

    
    //	Class definition/implementation in MaterialAPI.h
    #include <material.fdf>
    struct CMaterialAPI
    {
        	CMaterialAPI	()	{	mdlMaterial_initialize ();	};
        	~CMaterialAPI	()	{	mdlMaterial_cleanup ();		};
    };
    //	Usage in myApp.cpp
    #include "MaterialAPI.h"
    {
         CMaterialAPI material_raii;	//	Calls mdlMaterial_initialize
          ... your code that uses mdlMaterial_xxx
    } //	Destructor called when CMaterialAPI goes out of scope: calls mdlMaterial_cleanup
    
    

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

Children
No Data