<div><div style="font-size:inherit"><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div>To export all vertex groups and their associated data (vertex indices and weights) to XML in Blender (2026), you can iterate through an object's </div><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">vertex_groups</code> and its mesh vertices.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Blender Python XML Export for Vertex Groups<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">The following script creates a standalone XML file that lists every vertex group for the selected object, including the weight for every vertex assigned to each group.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="font-family:"google sans","helvetica neue",sans-serif;color:rgb(10,10,10);font-weight:400;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"><div><div style="border:1px solid;border-radius:16px 16px 4px 4px;overflow:auto hidden;padding:12px 16px 0px"><div><div style="font-weight:500;font-size:20px;line-height:26px">python</div></div><div dir="ltr" style="font-size:14px;line-height:22px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>
<span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">xml</span>.<span style="color:rgb(180,89,8)">etree</span>.<span style="color:rgb(180,89,8)">ElementTree</span> <span style="color:rgb(147,52,230)">as</span> ET

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">export_vertex_groups_xml</span>(<span style="color:rgb(180,89,8)">filepath</span>):
    <span style="color:rgb(128,134,139);font-style:italic"># Create XML root</span>
    <span style="color:rgb(180,89,8)">root</span> = ET.Element(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">BlenderVertexGroupExport</span><span style="color:rgb(24,128,56)">"</span>, date=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">2026-01-27</span><span style="color:rgb(24,128,56)">"</span>)
    
    <span style="color:rgb(128,134,139);font-style:italic"># Target the active mesh object</span>
    <span style="color:rgb(180,89,8)">obj</span> = bpy.context.active_object
    <span style="color:rgb(147,52,230)">if</span> <span style="color:rgb(147,52,230)">not</span> obj <span style="color:rgb(147,52,230)">or</span> obj.type != <span style="color:rgb(24,128,56)">'</span><span style="color:rgb(24,128,56)">MESH</span><span style="color:rgb(24,128,56)">'</span>:
        print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Please select a Mesh object.</span><span style="color:rgb(24,128,56)">"</span>)
        <span style="color:rgb(147,52,230)">return</span>

    <span style="color:rgb(180,89,8)">obj_node</span> = ET.SubElement(root, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Object</span><span style="color:rgb(24,128,56)">"</span>, name=<a href="http://obj.name">obj.name</a>)
    <span style="color:rgb(180,89,8)">groups_node</span> = ET.SubElement(obj_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">VertexGroups</span><span style="color:rgb(24,128,56)">"</span>)

    <span style="color:rgb(128,134,139);font-style:italic"># 1. Map group indices to names for easier lookup</span>
    <span style="color:rgb(180,89,8)">group_map</span> = {g.index: <a href="http://g.name">g.name</a> <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">g</span> <span style="color:rgb(147,52,230)">in</span> obj.vertex_groups}

    <span style="color:rgb(128,134,139);font-style:italic"># 2. Iterate through all vertices in the mesh</span>
    <span style="color:rgb(128,134,139);font-style:italic"># Each vertex has a 'groups' collection of VertexGroupElements</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">v</span> <span style="color:rgb(147,52,230)">in</span> obj.data.vertices:
        <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">g_element</span> <span style="color:rgb(147,52,230)">in</span> v.groups:
            <span style="color:rgb(180,89,8)">group_name</span> = group_map.get(g_element.group, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Unknown</span><span style="color:rgb(24,128,56)">"</span>)
            
            <span style="color:rgb(128,134,139);font-style:italic"># Find or create the specific Group node in XML</span>
            <span style="color:rgb(180,89,8)">group_node</span> = groups_node.find(<span style="color:rgb(24,128,56)">f</span><span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">./Group[@name='</span>{group_name}<span style="color:rgb(24,128,56)">']</span><span style="color:rgb(24,128,56)">"</span>)
            <span style="color:rgb(147,52,230)">if</span> group_node <span style="color:rgb(147,52,230)">is</span> <span style="color:rgb(147,52,230)">None</span>:
                <span style="color:rgb(180,89,8)">group_node</span> = ET.SubElement(groups_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Group</span><span style="color:rgb(24,128,56)">"</span>, {
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">name</span><span style="color:rgb(24,128,56)">"</span>: group_name,
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">index</span><span style="color:rgb(24,128,56)">"</span>: str(g_element.group)
                })
            
            <span style="color:rgb(128,134,139);font-style:italic"># Add the vertex index and its weight (0.0 to 1.0)</span>
            ET.SubElement(group_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Vertex</span><span style="color:rgb(24,128,56)">"</span>, {
                <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">id</span><span style="color:rgb(24,128,56)">"</span>: str(v.index),
                <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">weight</span><span style="color:rgb(24,128,56)">"</span>: <span style="color:rgb(24,128,56)">f</span><span style="color:rgb(24,128,56)">"</span>{g_element.weight:.4f}<span style="color:rgb(24,128,56)">"</span>
            })

    <span style="color:rgb(128,134,139);font-style:italic"># Save to file</span>
    <span style="color:rgb(180,89,8)">tree</span> = ET.ElementTree(root)
    ET.indent(tree, space=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span>)
    tree.write(filepath, encoding=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">utf-8</span><span style="color:rgb(24,128,56)">"</span>, xml_declaration=<span style="color:rgb(147,52,230)">True</span>)
    print(<span style="color:rgb(24,128,56)">f</span><span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Vertex groups exported to: </span>{filepath}<span style="color:rgb(24,128,56)">"</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Usage: Update path as needed</span>
export_vertex_groups_xml(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">C:/path/to/vertex_groups.xml</span><span style="color:rgb(24,128,56)">"</span>)</code></pre></div></div></div></div></div><br></div><div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 1:38 PM John Carlson <<a href="mailto:yottzumm@gmail.com">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-size:inherit"><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="auto">Note, W index is 0 in quaternions.  Could be critical!</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">John</div><div dir="auto"><br></div><div dir="auto">To export Non-Linear Animation (NLA) with detailed </div><strong style="font-weight:700">X, Y, Z coordinates</strong> (and other channels) as XML in Blender (2026), you must iterate through the <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">fcurves</code> of each action linked to an NLA strip.<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">In <a href="https://blenderartists.org/t/list-all-keyframes-of-an-action/632353" style="font-weight:500;outline:0px" target="_blank">Blender</a>, transform data is stored in <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">fcurves</code>. Each curve has a <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">data_path</code>(e.g., <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">"location"</code>) and an <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">array_index</code> (0 for X, 1 for Y, 2 for Z).<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">XML Export Script with Keyframe Data<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This script iterates through all objects, their NLA tracks, and every individual keyframe point within those tracks.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="font-family:"google sans","helvetica neue",sans-serif;color:rgb(10,10,10);font-weight:400;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"><div><div style="border:1px solid;border-radius:16px 16px 4px 4px;overflow:auto hidden;padding:12px 16px 0px"><div><div style="font-weight:500;font-size:20px;line-height:26px">python</div></div><div dir="ltr" style="font-size:14px;line-height:22px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>
<span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">xml</span>.<span style="color:rgb(180,89,8)">etree</span>.<span style="color:rgb(180,89,8)">ElementTree</span> <span style="color:rgb(147,52,230)">as</span> ET

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">export_nla_detailed_xml</span>(<span style="color:rgb(180,89,8)">filepath</span>):
    <span style="color:rgb(180,89,8)">root</span> = ET.Element(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">BlenderNLAExport</span><span style="color:rgb(24,128,56)">"</span>, date=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">2026-01-27</span><span style="color:rgb(24,128,56)">"</span>)

    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">obj</span> <span style="color:rgb(147,52,230)">in</span> bpy.context.scene.objects:
        <span style="color:rgb(147,52,230)">if</span> <span style="color:rgb(147,52,230)">not</span> (obj.animation_data <span style="color:rgb(147,52,230)">and</span> obj.animation_data.nla_tracks):
            <span style="color:rgb(147,52,230)">continue</span>
            
        <span style="color:rgb(180,89,8)">obj_node</span> = ET.SubElement(root, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Object</span><span style="color:rgb(24,128,56)">"</span>, name=<a href="http://obj.name" target="_blank">obj.name</a>)
        
        <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">track</span> <span style="color:rgb(147,52,230)">in</span> obj.animation_data.nla_tracks:
            <span style="color:rgb(180,89,8)">track_node</span> = ET.SubElement(obj_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Track</span><span style="color:rgb(24,128,56)">"</span>, name=<a href="http://track.name" target="_blank">track.name</a>)
            
            <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">strip</span> <span style="color:rgb(147,52,230)">in</span> track.strips:
                <span style="color:rgb(147,52,230)">if</span> <span style="color:rgb(147,52,230)">not</span> strip.action:
                    <span style="color:rgb(147,52,230)">continue</span>
                    
                <span style="color:rgb(180,89,8)">strip_node</span> = ET.SubElement(track_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Strip</span><span style="color:rgb(24,128,56)">"</span>, {
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">name</span><span style="color:rgb(24,128,56)">"</span>: <a href="http://strip.name" target="_blank">strip.name</a>,
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">action</span><span style="color:rgb(24,128,56)">"</span>: <a href="http://strip.action.name" target="_blank">strip.action.name</a>,
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">start</span><span style="color:rgb(24,128,56)">"</span>: str(strip.frame_start),
                    <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">end</span><span style="color:rgb(24,128,56)">"</span>: str(strip.frame_end)
                })

                <span style="color:rgb(128,134,139);font-style:italic"># Iterate through F-Curves for X, Y, Z and other data</span>
                <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">fcu</span> <span style="color:rgb(147,52,230)">in</span> strip.action.fcurves:
                    <span style="color:rgb(180,89,8)">channel_node</span> = ET.SubElement(strip_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Channel</span><span style="color:rgb(24,128,56)">"</span>, {
                        <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">path</span><span style="color:rgb(24,128,56)">"</span>: fcu.data_path,
                        <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">index</span><span style="color:rgb(24,128,56)">"</span>: str(fcu.array_index) <span style="color:rgb(128,134,139);font-style:italic"># 0=X, 1=Y, 2=Z</span>
                    })
                    
                    <span style="color:rgb(128,134,139);font-style:italic"># Extract every keyframe point (Time, Value)</span>
                    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">kp</span> <span style="color:rgb(147,52,230)">in</span> fcu.keyframe_points:
                        ET.SubElement(channel_node, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Keyframe</span><span style="color:rgb(24,128,56)">"</span>, {
                            <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">frame</span><span style="color:rgb(24,128,56)">"</span>: str(round(<a href="http://kp.co" target="_blank">kp.co</a>[<span style="color:rgb(180,89,8)">0</span>], <span style="color:rgb(180,89,8)">4</span>)),
                            <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">value</span><span style="color:rgb(24,128,56)">"</span>: str(round(<a href="http://kp.co" target="_blank">kp.co</a>[<span style="color:rgb(180,89,8)">1</span>], <span style="color:rgb(180,89,8)">4</span>)),
                            <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">interpolation</span><span style="color:rgb(24,128,56)">"</span>: kp.interpolation
                        })

    <span style="color:rgb(128,134,139);font-style:italic"># Save with formatting</span>
    <span style="color:rgb(180,89,8)">tree</span> = ET.ElementTree(root)
    ET.indent(tree, space=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span>)
    tree.write(filepath, encoding=<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">utf-8</span><span style="color:rgb(24,128,56)">"</span>, xml_declaration=<span style="color:rgb(147,52,230)">True</span>)
    print(<span style="color:rgb(24,128,56)">f</span><span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Detailed NLA XML exported to: </span>{filepath}<span style="color:rgb(24,128,56)">"</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Usage</span>
export_nla_detailed_xml(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">C:/path/to/animation_data.xml</span><span style="color:rgb(24,128,56)">"</span>)
</code></pre></div></div><div style="border:1px solid;border-radius:4px 4px 16px 16px;margin-top:3px;overflow:hidden;padding:12px 16px"><div style="font-size:12px">Use code with caution.</div><button style="margin:0px;background:none;color:inherit;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Key Technical Notes<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><ul style="margin:0px;padding:0px;font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:700">Coordinate Mapping:</strong> In the <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">keyframe_points</code> property, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px"><a href="http://kp.co" target="_blank">kp.co</a>[0]</code> is the frame number (time), and <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px"><a href="http://kp.co" target="_blank">kp.co</a>[1]</code> is the actual value (e.g., location in meters or rotation in radians).</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:700">Array Indices:</strong><ul style="margin:0px;padding:0px;font-family:'google sans','helvetica neue',sans-serif;font-size:16px;line-height:24px"><li style="margin:0px 0px 12px;padding:0px;list-style:circle"><strong style="font-weight:700">Location/Scale:</strong> <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">0</code> = X, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">1</code> = Y, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">2</code> = Z.</li><li style="margin:0px 0px 12px;padding:0px;list-style:circle"><strong style="font-weight:700">Rotation (Quaternion):</strong> <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">0</code> = W, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">1</code> = X, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">2</code> = Y, <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">3</code> = Z.</li></ul></li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:700">Local vs. Global:</strong> NLA strips store <strong style="font-weight:700">local</strong> action data. If you move an NLA strip in the timeline, the <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px"><a href="http://kp.co" target="_blank">kp.co</a>[0]</code>values do <em style="font-weight:inherit;font-style:italic">not</em> change automatically. To get the "world" frame, you must add the strip's <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">frame_start</code> to the keyframe's time.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:700">Baking for Complex Data:</strong> If your animation uses <strong style="font-weight:700">Constraints</strong> or <strong style="font-weight:700">Drivers</strong>, the keyframes won't exist in the <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">fcurves</code> directly. You must use Bake Action first to convert these into raw keyframes before running the script.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></li></ul><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Would you like to include <strong style="font-weight:700">bone hierarchy data</strong> in the XML as well, or is object-level transform data sufficient?</div></div></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 1:19 PM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-size:inherit"><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">1. Object Parent/Child Hierarchy<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">To traverse the parenting structure (e.g., a car body with child wheels), use a recursive function that accesses <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">object.children</code>.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="font-family:"google sans","helvetica neue",sans-serif;color:rgb(10,10,10);font-weight:400;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"><div><div style="border:1px solid;border-radius:16px 16px 4px 4px;overflow:auto hidden;padding:12px 16px 0px"><div><div style="font-weight:500;font-size:20px;line-height:26px">python</div></div><div dir="ltr" style="font-size:14px;line-height:22px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">traverse_objects</span>(<span style="color:rgb(180,89,8)">obj</span>, <span style="color:rgb(180,89,8)">depth</span>=<span style="color:rgb(180,89,8)">0</span>):
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span> * depth + <a href="http://obj.name" target="_blank">obj.name</a>)
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">child</span> <span style="color:rgb(147,52,230)">in</span> obj.children:
        traverse_objects(child, depth + <span style="color:rgb(180,89,8)">1</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Start from root objects in the scene (objects without parents)</span>
<span style="color:rgb(180,89,8)">roots</span> = [o <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">o</span> <span style="color:rgb(147,52,230)">in</span> bpy.context.scene.objects <span style="color:rgb(147,52,230)">if</span> <span style="color:rgb(147,52,230)">not</span> o.parent]
<span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">root</span> <span style="color:rgb(147,52,230)">in</span> roots:
    traverse_objects(root)
</code></pre></div></div><div style="border:1px solid;border-radius:4px 4px 16px 16px;margin-top:3px;overflow:hidden;padding:12px 16px"><div style="font-size:12px">Use code with caution.</div><button style="margin:0px;background:none;color:inherit;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">2. Collection Hierarchy<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">To traverse the organizational structure of collections in the Outliner, use a similar recursive approach on <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">collection.children</code>.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:20px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"></div><div style="font-family:"google sans","helvetica neue",sans-serif;color:rgb(10,10,10);font-weight:400;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:inherit"><div><div style="border:1px solid;border-radius:16px 16px 4px 4px;overflow:auto hidden;padding:12px 16px 0px"><div><div style="font-weight:500;font-size:20px;line-height:26px">python</div></div><div dir="ltr" style="font-size:14px;line-height:22px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">traverse_collections</span>(<span style="color:rgb(180,89,8)">col</span>, <span style="color:rgb(180,89,8)">depth</span>=<span style="color:rgb(180,89,8)">0</span>):
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span> * depth + <a href="http://col.name" target="_blank">col.name</a>)
    <span style="color:rgb(128,134,139);font-style:italic"># Perform actions on objects within this collection</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">obj</span> <span style="color:rgb(147,52,230)">in</span> col.objects:
        print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span> * (depth + <span style="color:rgb(180,89,8)">1</span>) + <span style="color:rgb(24,128,56)">f</span><span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Object: </span>{<a href="http://obj.name" target="_blank">obj.name</a>}<span style="color:rgb(24,128,56)">"</span>)
    
    <span style="color:rgb(128,134,139);font-style:italic"># Recurse into sub-collections</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">child</span> <span style="color:rgb(147,52,230)">in</span> col.children:
        traverse_collections(child, depth + <span style="color:rgb(180,89,8)">1</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Start from the Scene's Master Collection</span>
traverse_collections(bpy.context.scene.collection)</code></pre></div></div></div></div></div><br></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 1:16 PM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Well, just asked Google, duh!</div><div dir="auto"><br></div><div dir="auto"><div style="font-size:inherit"><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">The most prominent top-level data-block types, which can be accessed directly from <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data</code>, include:<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><ul style="margin:0px;padding:0px;font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.objects</code></strong>: Contains all Object instances in the scene (meshes, cameras, lights, etc.).</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.scenes</code></strong>: Contains all Scenes.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.collections</code></strong>: Contains all Collections (used to organize objects).</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.meshes</code></strong>: Contains mesh data-blocks.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.materials</code></strong>: Contains material data-blocks.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.images</code></strong>: Contains loaded images.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.armatures</code></strong>: Contains armature data.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.curves</code></strong>: Contains curve data.</li><li style="margin:0px 0px 12px;padding:0px;list-style:outside"><strong style="font-weight:bolder"><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.worlds</code></strong>: Contains world data.<span style="white-space:nowrap"> </span></li></ul></div><br></div><div dir="auto"><div style="font-size:inherit"><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);margin-top:0px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div>Traversing all hierarchies in Blender—spanning objects, bone chains, animation data, and node trees—requires a recursive Python approach using the </div><code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy</code> module to navigate <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data</code> and parent-child relationships.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Here is a comprehensive guide on how to traverse these hierarchies, categorized by data type.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">1. Scene Object Hierarchy (Parents & Children)<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">To traverse all objects, including their child objects (recursive structure), use the following script.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-weight:400;font-size:inherit;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div style="border:1px solid;border-radius:8px;overflow:hidden;padding:0px"><div style="font-weight:500;font-size:20px;line-height:26px;height:34px;border-bottom:1px solid;padding:0px 4px 0px 16px">python<button style="margin:0px;background:none;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div><div dir="ltr" style="font-size:14px;line-height:22px;padding:2px 16px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">traverse_objects</span>(<span style="color:rgb(180,89,8)">obj</span>, <span style="color:rgb(180,89,8)">level</span>=<span style="color:rgb(180,89,8)">0</span>):
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span> * level + <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Object:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://obj.name" target="_blank">obj.name</a>, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Type:</span><span style="color:rgb(24,128,56)">"</span>, obj.type)
    
    <span style="color:rgb(128,134,139);font-style:italic"># Traverse children</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">child</span> <span style="color:rgb(147,52,230)">in</span> obj.children:
        traverse_objects(child, level + <span style="color:rgb(180,89,8)">1</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Start traversal from root objects (objects with no parent)</span>
<span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">obj</span> <span style="color:rgb(147,52,230)">in</span> bpy.context.scene.objects:
    <span style="color:rgb(147,52,230)">if</span> obj.parent <span style="color:rgb(147,52,230)">is</span> <span style="color:rgb(147,52,230)">None</span>:
        traverse_objects(obj)
</code></pre></div></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">2. Armature Bone Hierarchy (Rigging)<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Bones exist within armature data. You must iterate through the <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bones</code>collection, focusing on root bones (those without a parent) and navigating down.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-weight:400;font-size:inherit;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div style="border:1px solid;border-radius:8px;overflow:hidden;padding:0px"><div style="font-weight:500;font-size:20px;line-height:26px;height:34px;border-bottom:1px solid;padding:0px 4px 0px 16px">python<button style="margin:0px;background:none;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div><div dir="ltr" style="font-size:14px;line-height:22px;padding:2px 16px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">traverse_bones</span>(<span style="color:rgb(180,89,8)">bone</span>, <span style="color:rgb(180,89,8)">level</span>=<span style="color:rgb(180,89,8)">0</span>):
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  </span><span style="color:rgb(24,128,56)">"</span> * level + <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Bone:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://bone.name" target="_blank">bone.name</a>)
    <span style="color:rgb(128,134,139);font-style:italic"># Traverse children</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">child</span> <span style="color:rgb(147,52,230)">in</span> bone.children:
        traverse_bones(child, level + <span style="color:rgb(180,89,8)">1</span>)

<span style="color:rgb(128,134,139);font-style:italic"># Assumes an Armature object is selected</span>
<span style="color:rgb(180,89,8)">arm_obj</span> = bpy.context.active_object
<span style="color:rgb(147,52,230)">if</span> arm_obj <span style="color:rgb(147,52,230)">and</span> arm_obj.type == <span style="color:rgb(24,128,56)">'</span><span style="color:rgb(24,128,56)">ARMATURE</span><span style="color:rgb(24,128,56)">'</span>:
    <span style="color:rgb(128,134,139);font-style:italic"># Use bone.parent is None to find root bones</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">bone</span> <span style="color:rgb(147,52,230)">in</span> arm_obj.data.bones:
        <span style="color:rgb(147,52,230)">if</span> bone.parent <span style="color:rgb(147,52,230)">is</span> <span style="color:rgb(147,52,230)">None</span>:
            traverse_bones(bone)
</code></pre></div></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">3. Animation Hierarchy (Actions & Keyframes)<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Animations are stored in <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">bpy.data.actions</code> and linked to objects via <code dir="ltr" style="font-size:14px;line-height:22px;border:1px solid;border-radius:4px;padding:2px 4px">animation_data</code>. To traverse keyframes within an action:<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-weight:400;font-size:inherit;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div style="border:1px solid;border-radius:8px;overflow:hidden;padding:0px"><div style="font-weight:500;font-size:20px;line-height:26px;height:34px;border-bottom:1px solid;padding:0px 4px 0px 16px">python<button style="margin:0px;background:none;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div><div dir="ltr" style="font-size:14px;line-height:22px;padding:2px 16px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(128,134,139);font-style:italic"># Traverse all actions in the blend file</span>
<span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">action</span> <span style="color:rgb(147,52,230)">in</span> bpy.data.actions:
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Action:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://action.name" target="_blank">action.name</a>)
    <span style="color:rgb(128,134,139);font-style:italic"># Traverse F-Curves (animation channels)</span>
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">fcurve</span> <span style="color:rgb(147,52,230)">in</span> action.fcurves:
        print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  FCurve:</span><span style="color:rgb(24,128,56)">"</span>, fcurve.data_path, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Array Index:</span><span style="color:rgb(24,128,56)">"</span>, fcurve.array_index)
        <span style="color:rgb(128,134,139);font-style:italic"># Traverse keyframe points</span>
        <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">keyframe</span> <span style="color:rgb(147,52,230)">in</span> fcurve.keyframe_points:
            print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">    Keyframe:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://keyframe.co" target="_blank">keyframe.co</a>)
</code></pre></div></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:28px;font-weight:600;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">4. Node Hierarchy (Shader/Geometry Nodes)<span style="white-space:nowrap"><button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;line-height:24px;color:rgb(10,10,10);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Nodes are structured within tree structures. You can traverse node trees in material nodes or geometry nodes.<span style="white-space:nowrap"> <button style="margin:0px 6px 0px 0px;border:medium;border-radius:10px;height:20px;padding:0px;width:28px;outline:0px"><span style="display:inline-block"></span></button></span></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div style="font-family:"google sans","helvetica neue",sans-serif;font-weight:400;font-size:inherit;font-style:normal;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div style="border:1px solid;border-radius:8px;overflow:hidden;padding:0px"><div style="font-weight:500;font-size:20px;line-height:26px;height:34px;border-bottom:1px solid;padding:0px 4px 0px 16px">python<button style="margin:0px;background:none;border:medium;padding:4px;font-style:inherit;font-weight:inherit;font-size:inherit;line-height:inherit;font-family:inherit;outline:0px"></button></div><div dir="ltr" style="font-size:14px;line-height:22px;padding:2px 16px"><pre><code><span style="color:rgb(147,52,230)">import</span> <span style="color:rgb(180,89,8)">bpy</span>

<span style="color:rgb(147,52,230)">def</span> <span style="color:rgb(180,89,8)">traverse_nodes</span>(<span style="color:rgb(180,89,8)">node_tree</span>):
    <span style="color:rgb(147,52,230)">if</span> node_tree <span style="color:rgb(147,52,230)">is</span> <span style="color:rgb(147,52,230)">None</span>: <span style="color:rgb(147,52,230)">return</span>
    print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Node Tree:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://node_tree.name" target="_blank">node_tree.name</a>)
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">node</span> <span style="color:rgb(147,52,230)">in</span> node_tree.nodes:
        print(<span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">  Node:</span><span style="color:rgb(24,128,56)">"</span>, <a href="http://node.name" target="_blank">node.name</a>, <span style="color:rgb(24,128,56)">"</span><span style="color:rgb(24,128,56)">Type:</span><span style="color:rgb(24,128,56)">"</span>, node.type)
        <span style="color:rgb(128,134,139);font-style:italic"># Check for node groups</span>
        <span style="color:rgb(147,52,230)">if</span> node.type == <span style="color:rgb(24,128,56)">'</span><span style="color:rgb(24,128,56)">GROUP</span><span style="color:rgb(24,128,56)">'</span> <span style="color:rgb(147,52,230)">and</span> node.node_tree:
            traverse_nodes(node.node_tree)

<span style="color:rgb(128,134,139);font-style:italic"># Example: Traversing active object's material nodes</span>
<span style="color:rgb(180,89,8)">obj</span> = bpy.context.active_object
<span style="color:rgb(147,52,230)">if</span> obj <span style="color:rgb(147,52,230)">and</span> obj.material_slots:
    <span style="color:rgb(147,52,230)">for</span> <span style="color:rgb(180,89,8)">slot</span> <span style="color:rgb(147,52,230)">in</span> obj.material_slots:
        <span style="color:rgb(147,52,230)">if</span> slot.material <span style="color:rgb(147,52,230)">and</span> slot.material.use_nodes:
            traverse_nodes(slot.material.node_tree)
</code></pre></div></div></div></div><div style="color:rgb(10,10,10);font-family:"google sans","helvetica neue",sans-serif;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><br style="font-size:inherit"></div></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 1:06 PM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Aaron, it would be helpful to me to get the top-level Blender objects that hold the scene:</div><div dir="auto"><br></div><div dir="auto">The object hierarchy.</div><div dir="auto">The actions, key frames and animations.</div><div dir="auto">The node graph roots (materials)</div><div dir="auto">Anything else you can think of relevant to X3D.</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto"><br></div><div dir="auto">John </div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 12:17 PM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">I am now considering traversing the Blender object hierarchy and exporting “Blender XML,” such that I can translate Blender object structures directly to XML.  Then I will work towards translating X3D XML to Blender XML for loading using Blender XML examples, and write a Blender XML import for Blender.  <span style="font-family:-apple-system,sans-serif">Maybe I should use JSON?  What extension should I use?</span></div><div dir="auto"><br></div><div dir="auto">Somehow this seems very brittle.</div><div dir="auto"><br></div><div dir="auto">H**k,</div><div dir="auto"><br></div><div dir="auto">John</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 11:16 AM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">I’m totally on board with that for X3D encodings in general, but I’m currently narrowing down to using an X3D Python “encoding,” not a binding.</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 27, 2026 at 10:39 AM Bergstrom, Aaron <<a href="mailto:aaron.bergstrom@und.edu" target="_blank">aaron.bergstrom@und.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div>
<p class="MsoNormal">All,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I keep a python dictionary that I pass a node type to in the form of a string, and it returns an x3d.py node object.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I keep a custom version of x3d.py to which I’ve added CGE, X_ITE, and X3DOM (sort of) node classes, so I can also export experimental nodes such as a CGE Skin, X_ITE material extensions, or X3DOM CommonSurfaceShader.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The dictionary includes all of the X3D 4.0 node types, as well as a variety of pending 4.1 nodes and browser specific nodes as described above.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">It basically looks like this:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#569cd6">def</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">
</span><span style="font-size:10.5pt;font-family:Consolas;color:#dcdcaa">instantiateNodeFromString</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">(</span><span style="font-size:10.5pt;font-family:Consolas;color:#9cdcfe">x3dType</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">):<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">   
</span><span style="font-size:10.5pt;font-family:Consolas;color:#9cdcfe">x3dNodeMapping</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">
</span><span style="font-size:10.5pt;font-family:Consolas;color:#d4d4d4">=</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"> {<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#6a9955">####################################### A</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'AcousticProperties'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">AcousticProperties</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'Analyser'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">Analyser</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'Anchor'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">Anchor</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'AnisotropyMaterialExtension'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">AnisotropyMaterialExtension</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,
</span><span style="font-size:10.5pt;font-family:Consolas;color:#6a9955"># X_ITE - glTF extension</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u><u></u></span></p>
<p class="MsoNormal">***snip***<u></u><u></u></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'VolumeData'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">VolumeData</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'VolumeEmitter'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">VolumeEmitter</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'VolumePickSensor'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">VolumePickSensor</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#6a9955">####################################### W</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'WaveShaper'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">WaveShaper</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'WindPhysicsModel'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">WindPhysicsModel</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">,<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:#ce9178">'WorldInfo'</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">:</span><span style="font-size:10.5pt;font-family:Consolas;color:#4ec9b0">WorldInfo</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">    }<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u> <u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">   
</span><span style="font-size:10.5pt;font-family:Consolas;color:#c586c0">return</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">
</span><span style="font-size:10.5pt;font-family:Consolas;color:#9cdcfe">x3dNodeMapping</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">[</span><span style="font-size:10.5pt;font-family:Consolas;color:#9cdcfe">x3dType</span><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc">]()<u></u><u></u></span></p>
<p class="MsoNormal" style="line-height:14.25pt;background:#1f1f1f"><span style="font-size:10.5pt;font-family:Consolas;color:#cccccc"><u></u> <u></u></span></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Aaron<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> <br>
<b>Sent:</b> Tuesday, January 27, 2026 1:30 AM<br>
<b>To:</b> Don Brutzman <<a href="mailto:don.brutzman@gmail.com" target="_blank">don.brutzman@gmail.com</a>><br>
<b>Cc:</b> Bergstrom, Aaron <<a href="mailto:aaron.bergstrom@und.edu" target="_blank">aaron.bergstrom@und.edu</a>>; X3D Ecosystem public discussion <<a href="mailto:x3d-ecosystem@web3d.org" target="_blank">x3d-ecosystem@web3d.org</a>><br>
<b>Subject:</b> Re: Loading into X3DPSAIL (for Maya and Blender)<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">I think that Aaron was writing something that converted class names into X3D Python classes (and to scene graph objects?), but I haven’t heard much about it or if he imports X3D directly into Maya or some X3DPSAIL derivative (and then to
 Maya).  I am will to work on something that generates a XML Python loader (from X3DUOM), just realize I haven’t decided on a single loader class or multiple loader classes.  Opinions? At least I can take a first crack at it.   I probably won’t use AI at all. 
 I’ll study the structure of the Java version, but I do prefer ElementTree over DOM for this use case.<u></u><u></u></p>
</div>
</div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Likely, it will be an adjunct to X3DPSAIL.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I think the best test for reliability is to do roundtrip testing on the archive, which will also test XML output.<u></u><u></u></p>
</div>
</div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">John <u></u><u></u></p>
<div></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div>
<div>
<p class="MsoNormal">On Mon, Jan 26, 2026 at 6:01 PM Don Brutzman <<a href="mailto:don.brutzman@gmail.com" target="_blank">don.brutzman@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
</div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">Yes "X3DLoaderDOM.java (load DOM into scenegraph)" was difficult to write, requires manual coding and time-consuming to debug.  It works and the generator for it is checked into open source as a key part of X3DJSAIL.<u></u><u></u></p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
<a href="https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/X3DLoaderDOM.html" target="_blank">https://www.web3d.org/specifications/java/javadoc/org/web3d/x3d/jsail/X3DLoaderDOM.html</a><u></u><u></u></li><li class="MsoNormal">
(on <a href="http://web3d.org" target="_blank">web3d.org</a> but direct access is blocked, library not is version control since it is large and changeable; copy attached)<u></u><u></u></li></ul>
<div>
<p class="MsoNormal">The PythonX3dSmokeTests.py program builds a lot of snippets of python scene graph.  The same approach might be used to walk any X3D tree and construct a python scene graph.  If such code works, and is reliable, we can promote that code
 and integrate it as part of the x3d.py distribution.<u></u><u></u></p>
</div>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
<a href="https://www.web3d.org/x3d/stylesheets/python/examples/PythonX3dSmokeTests.py" target="_blank">https://www.web3d.org/x3d/stylesheets/python/examples/PythonX3dSmokeTests.py</a><u></u><u></u></li></ul>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222">all the best, Don</span><span style="color:#222222"><u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222">-- </span><span style="color:#222222"><u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222">X3D Graphics, Maritime Robotics, Distributed Simulation</span><span style="color:#222222"><u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222">Relative Motion Consulting 
<a href="https://RelativeMotion.info" target="_blank">https://RelativeMotion.info</a></span><span style="color:#222222"><u></u><u></u></span></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div>
<div>
<p class="MsoNormal">On Mon, Jan 26, 2026 at 2:54 PM John Carlson <<a href="mailto:yottzumm@gmail.com" target="_blank">yottzumm@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
</div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">Thanks for fixing the TODO to add XML!<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I have tried to add Python code which loads JSON into an X3DPSAIL scene graph and failed.  I have zero confidence in my ability to load stuff into in memory scene graphs, preferring to load things into DOM first.  This applies to much of
 my work, including JSON validation with X3D XML schema.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I am attempting to load JSON into a CGE scene graph, but there’s no real evidence that it works yet.  I have a mostly working DOM solution.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I realize X3DLoaderDOM.java (load DOM into scenegraph) is a lot of work, and if this was mostly <span style="font-family:"Arial",sans-serif">automated, please tell us how if it’s not a national secret.  If we have that, then Python might
 be a lot easier!</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">My overall plan is to push JSON things into DOM for loading, but Aaron might have a good solution for all encodings!<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I am reminded how Xj3D translated XML into a VRML scene graph.  Not ideal, but.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">My priorities are first CGE, then Blender import.  I realize my priorities change a lot.   If we had a way to export into Blender from X3DPSAIL, this would make working on X3DPSAIL import much more attractive.  Easier said than done.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">John<u></u><u></u></p>
</div>
</blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div>
<p class="MsoNormal"><u></u> <u></u></p>
<div></div></div></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><div>
<div>
<p class="MsoNormal">On Mon, Jan 26, 2026 at 3:51 PM Don Brutzman <<a href="mailto:don.brutzman@gmail.com" target="_blank">don.brutzman@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
</div></div></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div></div></blockquote></div></div></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div>
<div>
<p class="MsoNormal">Regarding C/C++/C# open source, no such library has yet been shared.  As with our autogenerated Java and Python libraries, these are strong candidates for autogeneration once proper design patterns are written.  Once written, library testing
 using the X3D Example Archives would be essential for success and straightforward to perform.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Regarding X3D loaders in Python for X3DPSAIL, none has been written yet.  Please be aware that .x3d files are written in valid XML.  Refreshed TODO list:<u></u><u></u></p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
Python X3D Package x3d.py, X3D Python Scene Access Interface Library (X3DPSAIL)<u></u><u></u></li><li class="MsoNormal">
The x3d.py Python X3D Package supports programmers with Python interfaces and objects for standards-based X3D programming, all as open source.<u></u><u></u></li><li class="MsoNormal">
<a href="https://www.web3d.org/x3d/stylesheets/python/python.html#TODO" target="_blank">https://www.web3d.org/x3d/stylesheets/python/python.html#TODO</a><u></u><u></u></li></ul>
</div>
</div></blockquote></div></div></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="margin-left:30.0pt;margin-right:0in">
<div>
<h3><span style="font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html#TODO" target="_blank"><span style="font-family:"Segoe UI Emoji",sans-serif">🔖</span></a> TODO<u></u><u></u></span></h3>
</div>
<div>
<h3><span style="font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none"><u></u><u></u></span></a></span></h3>
</div>
<div>
<p><span style="font-size:13.5pt;font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">Lots! Much progress continues. For a release-summary
 log, please see <u><span style="color:blue">history log for this page</span></u>.<u></u><u></u></span></a></span></p>
</div>
</blockquote></div></blockquote></div></div></blockquote></div></blockquote></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><div>
<div>
<ul type="disc">
<ul type="circle">
<li class="MsoNormal" style="color:black">
<i><span style="font-size:13.5pt;font-family:"Times New Roman",serif"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">TODO:</span><span style="color:black;font-style:normal;text-decoration:none"> clean
 up <u><span style="color:blue">x3d.html</span></u> documentation autogenerated by <u><span style="color:blue">pydoc</span></u>.<u></u><u></u></span></a></span></i></li><li class="MsoNormal" style="color:black">
<i><span style="font-size:13.5pt;font-family:"Times New Roman",serif"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">TODO:</span><span style="color:black;font-style:normal;text-decoration:none"> We
 need a "Getting Started" tutorial on this page. This is a good opportunity... who wants to help?!<u></u><u></u></span></a></span></i></li><li class="MsoNormal" style="color:black">
<i><span style="font-size:13.5pt;font-family:"Times New Roman",serif"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">TODO:</span><span style="color:black;font-style:normal;text-decoration:none"> <span style="background:#fff2cc">utility
 support for loaders from XML (.x3d or .xml), ClassicVRML (.x3dv), VRML97 (.wrl), and JSON (.json or .x3dj) files.</span><u></u><u></u></span></a></span></i></li><li class="MsoNormal" style="color:black">
<i><span style="font-size:13.5pt;font-family:"Times New Roman",serif"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">TODO:</span><span style="color:black;font-style:normal;text-decoration:none"> distribution
 support for <u><span style="color:blue">Jupyter Notebook</span></u> (initial example works), <u><span style="color:blue">Apache Zeppelin</span></u> notebook, <u><span style="color:blue">Anaconda</span></u> distribution of Python, and other data-science platforms.<u></u><u></u></span></a></span></i></li></ul>
</ul>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">To facilitate library review,
 I was recently able to autogenerate Python documentation for x3d.py using the pydoc tool.</span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
<span style="font-size:12.0pt;font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none"><u><span style="color:blue">https://www.web3d.org/x3d/stylesheets/python/x3d.html</span></u></span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext;text-decoration:none"><u></u><u></u></span></a></span></li></ul>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Please note that each X3D node has the following methods listed.<u></u><u></u></span></a></p>
</div>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal"><span style="font-size:13.5pt;font-family:"Times New Roman",serif;color:black"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:black;text-decoration:none">Methods defined here:<br>
</span><strong><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext;text-decoration:none">HTML5</span></strong><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext;text-decoration:none">(self, indentLevel=0)<br>
Provide HTML5 output serialization using modified XML encoding with no singleton self-closing elements.<br>
<strong><span style="font-family:"Calibri",sans-serif">JSON</span></strong>(self, indentLevel=0, syntax='JSON')<br>
Provide <u><span style="color:blue">X3D</span></u> output serialization using JSON encoding (usable for .json file suffix).<br>
<strong><span style="font-family:"Calibri",sans-serif">VRML</span></strong>(self, indentLevel=0, VRML97=False)<br>
Provide <u><span style="color:blue">X3D</span></u> output serialization using VRML encoding (usable for .x3dv or .wrl file suffix).<br>
<span><strong><span style="font-family:"Calibri",sans-serif">XML</span></strong></span>(self, indentLevel=0, syntax='XML')<br>
Provide Canonical <u><span style="color:blue">X3D</span></u> output serialization using XML encoding (usable for .x3d file suffix).<u></u><u></u></span></a><a name="m_7174372409175664263_m_-6125563780163143884_m_8242586863700093592_m_-1626106878899190018_m_1853299307438569576_m_-6958278905113018921_m_4157171645680770130_m_7678997691515119019_m_-108059092678371"></a></span></p>
</blockquote>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Am thinking the HTML5 method is no longer needed, this was written when X3DOM had trouble with self-closing
 elements.<u></u><u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Thanks for all efforts that might improve x3d.py.<u></u><u></u></span></a></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">all the best, Don</span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">-- </span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">X3D Graphics, Maritime Robotics, Distributed Simulation</span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">Relative Motion Consulting 
<u><span style="color:blue">https://RelativeMotion.info</span></u></span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">On Sun, Jan 25, 2026 at 4:18 AM John Carlson <<u><span style="color:blue">yottzumm@gmail.com</span></u>>
 wrote:<u></u><u></u></span></a></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">I guess I didn't send this earlier.<u></u><u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">I did see the standards progress page.  For C/C++/C#, are any libraries open source?  I’m thinking COIN
 3D, OpenInventor,  H3D.   Maybe others.  I see there’s an ISO documentation for each language, but apparently the standard isn’t open source????  I’m looking for opportunities for X3DJSONLD serialization. OpenInventor (COIN 3D) looks super complex.<u></u><u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">For X3DPSAIL, can you point me at an example of loading XML or DOM into a scenegraph? Maybe I missed
 something????  I’m looking for something like CreateX3DFromString()???   I realized I can create Python from XML, just like my tools can go from JSON to DOM to Python; but my toolchain isn’t Python.   Running stylesheets in Python would be a great example.<u></u><u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Looking here:<u></u><u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u><span style="color:blue">https://www.web3d.org/x3d/stylesheets/python/examples/PythonX3dSmokeTests.py</span></u><u></u><u></u></span></a></p>
</div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
</div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u></u> <u></u></span></a></p>
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">On Sun, Jan 25, 2026 at 12:19 AM Don Brutzman <<u><span style="color:blue">don.brutzman@gmail.com</span></u>>
 wrote:<u></u><u></u></span></a></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Standards planning status appears on the following page.<u></u><u></u></span></a></p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
<a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u><span style="color:blue">X3D Standards Progress | Web3D Consortium</span></u><u></u><u></u></span></a></li><li class="MsoNormal">
<a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none"><u><span style="color:blue">https://www.web3d.org/x3d/progress</span></u><u></u><u></u></span></a></li></ul>
<div>
<p class="MsoNormal"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:windowtext;text-decoration:none">Scroll past overview prose to find links to each version completed, in progress and planned.<u></u><u></u></span></a></p>
</div>
</div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none"><u></u> <u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">all the best, Don</span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"><a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank"><span style="color:#222222;text-decoration:none">-- </span><span style="font-family:"Calibri",sans-serif;color:#222222;text-decoration:none"><u></u><u></u></span></a></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New";color:#222222"></span></p></div></div></div></div></div></blockquote></div></div></div></div></blockquote></div></blockquote></div></div></blockquote></div></blockquote></div></div></div></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div>