2
$\begingroup$

I am searching of ways to serialize Blender Cycles materials to files using Python. But as of now I've found no such ways.

Maybe by writing the data of the materials to files but how can I do that? Even the slightest of contributions are appreciated.

If only there was a way to serialize materials to JSON/Binary/XML.

Perhaps someone here can lead me to light.

Maybe in the way Blender stores the materials?

$\endgroup$
  • $\begingroup$ To read the values and connections this should be a great starting point. $\endgroup$ – p2or Dec 14 '15 at 15:29
  • $\begingroup$ There's a node exporter if i recall correctly.try to look it up $\endgroup$ – Chebhou Dec 14 '15 at 16:07
  • 2
    $\begingroup$ @Chebhou This one: blenderartists.org/forum/…? $\endgroup$ – p2or Dec 14 '15 at 16:20
  • $\begingroup$ Meanwhile, I have found one way, but that's not what I asked in the question - To save the materials in a blender file and write an add-on to import only the materials from it. But I do hope someone pops with a better script only way $\endgroup$ – Farhan Anam Dec 15 '15 at 8:34
4
$\begingroup$

There is the rna_xml module, which produces pretty verbose xml

from rna_xml import rna2xml

rna2xml(root_node="MyRootName",
        root_rna=bpy.data.materials['Material'].node_tree)

produces (not full output). There is also an rna2xml routine. To output to a file use rna2xml(fw=f.write, ...) where f is a file.

<MyRootName>
  <inputs>
  </inputs>
  <links>
    <NodeLink is_valid="TRUE"
              from_node="ShaderNodeBsdfDiffuse::Diffuse BSDF"
              to_node="ShaderNodeOutputMaterial::Material Output"
              is_hidden="FALSE">
      <from_socket>
        <NodeSocketShader name="BSDF"
                          identifier="BSDF"
                          is_output="TRUE"
                          hide="FALSE"
                          enabled="TRUE"
                          link_limit="4095"
                          is_linked="TRUE"
                          show_expanded="FALSE"
                          hide_value="FALSE"
                          node="ShaderNodeBsdfDiffuse::Diffuse BSDF"
                          type="SHADER"
                          bl_idname="NodeSocketShader">
        </NodeSocketShader>
      </from_socket>
      <to_socket>
        <NodeSocketShader name="Surface"
                          identifier="Surface"
                          is_output="FALSE"
                          hide="FALSE"
                          enabled="TRUE"
                          link_limit="1"
                          is_linked="TRUE"
                          show_expanded="FALSE"
                          hide_value="FALSE"
                          node="ShaderNodeOutputMaterial::Material Output"
                          type="SHADER"
                          bl_idname="NodeSocketShader">
        </NodeSocketShader>
      </to_socket>
    </NodeLink>
  </links>
  <nodes>
    <ShaderNodeOutputMaterial type="OUTPUT_MATERIAL"
                              location="300 300"
                              width="140"
                              width_hidden="42"
                              height="100"
                              dimensions="178.889 116.333"
                              name="Material Output"
                              label=""
                              parent="NONE"
                              use_custom_color="FALSE"
                              color="0.608 0.608 0.608"
                              select="TRUE"
                              show_options="TRUE"
                              show_preview="FALSE"
                              hide="FALSE"
                              mute="FALSE"
                              show_texture="FALSE"
                              shading_compatibility="{NEW_SHADING}"
                              bl_idname="ShaderNodeOutputMaterial"
                              bl_label="Material Output"
                              bl_description=""
                              bl_icon="NONE"
                              bl_static_type="OUTPUT_MATERIAL"
                              bl_width_default="140"
                              bl_width_min="100"
                              bl_width_max="320"
                              bl_height_default="100"
                              bl_height_min="30"
                              bl_height_max="30"
                              is_active_output="TRUE">
      <inputs>
        <NodeSocketShader name="Surface"
                          identifier="Surface"
                          is_output="FALSE"
                          hide="FALSE"
$\endgroup$
0
$\begingroup$

As mentioned by @batFINGER you can use rna2xml to serialize node trees to an xml file. Then if you want to deserialize the node tree you can use rna2xml.xml2rna function.

Here is a snippet of code describing the whole procedure.Be aware though that you might get Read-only attributes error when importing the xml, in that case you can simply delete the attributes of the root node that pose a problem.

Cheers

EDIT: Actually this blender module is useful to serialize structures that have a pre-determined content but it is in no way useful to serialize whole materials and node trees from scratch. One easy way to get around that issue is to have another scene in the same .blend file with all the materials. Those can be accessed across all scenes with bpy.data.materials[<key>]. One could decide to augment the RNA serializer offered by Blender but I decided that it would take too much time for my current project.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.