Results 1 to 3 of 3

Thread: Material duplicate (and delete) problem

  1. #1

    Default Material duplicate (and delete) problem

    Hi,

    I'm using assemblies with maya and maya references. I want the assemblies to use the shaders in the scene. For this reason I exchange the material name in the assembly like this:

    myShadingGroup

    to

    ::myShadingGroup

    This lets the assembly search in the current scene for a material called myShadingGroup, works really fine.
    Now I have a problem: I use references in maya with namespaces. This leads to shading groups called:

    myReference:myShadingGroup

    Of course the assembly will be unable to find the correct shaders because they now have a namespace. Because mulitple references in maya will use the same assembly, there is no way to change the material name in the assembly. In maya I cannot simply rename the shadingGroups because they are locked. Then I had a simple idea:

    Why not create a new material with the correct name in a geometry shader and hope that the assembly uses the new correct one. So I tried it like this:

    The original material name is something like this: myReference:myShadingGroup
    The newName is the same without namespace: myShadingGroup
    Code:
    miMaterial *newMat = mi_api_material_begin(mi_mem_strdup(newName));
    miMaterial *origMaterial = (miMaterial *)mi_db_access(matTag);
    newMat->displace = origMaterial->displace;
    newMat->shader = origMaterial->shader;
    newMat->shadow = origMaterial->shadow;
    newMat->photon = origMaterial->photon;
    miTag newMatTag = mi_api_material_end();
    mi_db_unpin(matTag);
    And it worked! I was happy. But now a problem occurs:
    To clean up my modifications, I collect the new created materials and try to delete them after rendering in an output shader:

    Code:
    for( size_t matId = 0; matId < materialTagList.size(); matId++)
    {
            miTag newMatTag = materialTagList[matId];
            miMaterial *material = (miMaterial *)mi_db_access(newMatTag);
    	material->displace = miNULLTAG;
    	material->shader = miNULLTAG;
    	material->shadow = miNULLTAG;
    	material->photon = miNULLTAG;
    	mi_db_unpin(newMatTag);
    
    	const char *newName = mi_api_tag_lookup(newMatTag);
    	mi_info("Trying to delete material %s tag %d", newName, newMatTag);
    	mi_db_delete(newMatTag);
    	const char *newNameA = mi_api_tag_lookup(newMatTag);
    	mi_info("After delete material %s tag %d", newNameA, newMatTag);
    }
    materialTagList.clear();
    As you can see, I get the miTag, retrieve the material, set the components to miNULLTAG to be sure that the material only and nothing else is deleted and then I delete it from db. But, it still exists. In the last few lines I try to get the name from a theoretically invalid tag. But I get a valid result. If I now try to render again everthing goes wrong with the shaders because the database seems to be corrupt now.

    Maybe this approach is naive, but it was such a nice idea, but it seems my method is wrong, if it is valid at all.
    Any ideas how I can delete my self created materials? Maybe there is something like an db_update or a complete different approach?

  2. #2

    Default

    Haggi, mi_db_delete will delete the scene element however the symbol table entries
    associated with your material are still present. mi_db_delete is a great function however
    mi_api_delete is much more appropriate in your case.

    Gunter

    Quote Originally Posted by haggi View Post
    Hi,

    I'm using assemblies with maya and maya references. I want the assemblies to use the shaders in the scene. For this reason I exchange the material name in the assembly like this:

    myShadingGroup

    to

    ::myShadingGroup

    This lets the assembly search in the current scene for a material called myShadingGroup, works really fine.
    Now I have a problem: I use references in maya with namespaces. This leads to shading groups called:

    myReference:myShadingGroup

    Of course the assembly will be unable to find the correct shaders because they now have a namespace. Because mulitple references in maya will use the same assembly, there is no way to change the material name in the assembly. In maya I cannot simply rename the shadingGroups because they are locked. Then I had a simple idea:

    Why not create a new material with the correct name in a geometry shader and hope that the assembly uses the new correct one. So I tried it like this:

    The original material name is something like this: myReference:myShadingGroup
    The newName is the same without namespace: myShadingGroup
    Code:
    miMaterial *newMat = mi_api_material_begin(mi_mem_strdup(newName));
    miMaterial *origMaterial = (miMaterial *)mi_db_access(matTag);
    newMat->displace = origMaterial->displace;
    newMat->shader = origMaterial->shader;
    newMat->shadow = origMaterial->shadow;
    newMat->photon = origMaterial->photon;
    miTag newMatTag = mi_api_material_end();
    mi_db_unpin(matTag);
    And it worked! I was happy. But now a problem occurs:
    To clean up my modifications, I collect the new created materials and try to delete them after rendering in an output shader:

    Code:
    for( size_t matId = 0; matId < materialTagList.size(); matId++)
    {
            miTag newMatTag = materialTagList[matId];
            miMaterial *material = (miMaterial *)mi_db_access(newMatTag);
    	material->displace = miNULLTAG;
    	material->shader = miNULLTAG;
    	material->shadow = miNULLTAG;
    	material->photon = miNULLTAG;
    	mi_db_unpin(newMatTag);
    
    	const char *newName = mi_api_tag_lookup(newMatTag);
    	mi_info("Trying to delete material %s tag %d", newName, newMatTag);
    	mi_db_delete(newMatTag);
    	const char *newNameA = mi_api_tag_lookup(newMatTag);
    	mi_info("After delete material %s tag %d", newNameA, newMatTag);
    }
    materialTagList.clear();
    As you can see, I get the miTag, retrieve the material, set the components to miNULLTAG to be sure that the material only and nothing else is deleted and then I delete it from db. But, it still exists. In the last few lines I try to get the name from a theoretically invalid tag. But I get a valid result. If I now try to render again everthing goes wrong with the shaders because the database seems to be corrupt now.

    Maybe this approach is naive, but it was such a nice idea, but it seems my method is wrong, if it is valid at all.
    Any ideas how I can delete my self created materials? Maybe there is something like an db_update or a complete different approach?

  3. #3

    Default

    Works! Great, thanks a lot.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •