| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | # ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Contributor(s): Campbell Barton | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # <pep8 compliant> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import bpy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  | def build_property_typemap(skip_classes): | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     property_typemap = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for attr in dir(bpy.types): | 
					
						
							|  |  |  |         cls = getattr(bpy.types, attr) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |         if issubclass(cls, skip_classes): | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         ## to support skip-save we cant get all props | 
					
						
							|  |  |  |         # properties = cls.bl_rna.properties.keys() | 
					
						
							|  |  |  |         properties = [] | 
					
						
							|  |  |  |         for prop_id, prop in cls.bl_rna.properties.items(): | 
					
						
							|  |  |  |             if not prop.is_skip_save: | 
					
						
							|  |  |  |                 properties.append(prop_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |         properties.remove("rna_type") | 
					
						
							|  |  |  |         property_typemap[attr] = properties | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return property_typemap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def print_ln(data): | 
					
						
							|  |  |  |     print(data, end="") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  | def rna2xml(fw=print_ln, | 
					
						
							|  |  |  |             root_node="", | 
					
						
							|  |  |  |             root_rna=None,  # must be set | 
					
						
							|  |  |  |             root_rna_skip=set(), | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |             root_ident="", | 
					
						
							|  |  |  |             ident_val="  ", | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |             skip_classes=(bpy.types.Operator, | 
					
						
							|  |  |  |                           bpy.types.Panel, | 
					
						
							|  |  |  |                           bpy.types.KeyingSet, | 
					
						
							|  |  |  |                           bpy.types.Header, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |             pretty_format=True, | 
					
						
							|  |  |  |             method='DATA'): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |     from xml.sax.saxutils import quoteattr | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |     property_typemap = build_property_typemap(skip_classes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def number_to_str(val, val_type): | 
					
						
							|  |  |  |         if val_type == int: | 
					
						
							|  |  |  |             return "%d" % val | 
					
						
							|  |  |  |         elif val_type == float: | 
					
						
							|  |  |  |             return "%.6g" % val | 
					
						
							|  |  |  |         elif val_type == bool: | 
					
						
							|  |  |  |             return "TRUE" if val else "FALSE" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise NotImplemented("this type is not a number %s" % val_type) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def rna2xml_node(ident, value, parent): | 
					
						
							|  |  |  |         ident_next = ident + ident_val | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # divide into attrs and nodes. | 
					
						
							|  |  |  |         node_attrs = [] | 
					
						
							|  |  |  |         nodes_items = [] | 
					
						
							|  |  |  |         nodes_lists = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value_type = type(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |         if issubclass(value_type, skip_classes): | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # XXX, fixme, pointcache has eternal nested pointer to its self. | 
					
						
							|  |  |  |         if value == parent: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value_type_name = value_type.__name__ | 
					
						
							|  |  |  |         for prop in property_typemap[value_type_name]: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             subvalue = getattr(value, prop) | 
					
						
							|  |  |  |             subvalue_type = type(subvalue) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-25 11:54:58 +00:00
										 |  |  |             if subvalue_type in {int, bool, float}: | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                 node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type))) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |             elif subvalue_type is str: | 
					
						
							|  |  |  |                 node_attrs.append("%s=%s" % (prop, quoteattr(subvalue))) | 
					
						
							| 
									
										
										
										
											2012-08-25 11:54:58 +00:00
										 |  |  |             elif subvalue_type is set: | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |                 node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}"))) | 
					
						
							|  |  |  |             elif subvalue is None: | 
					
						
							|  |  |  |                 node_attrs.append("%s=\"NONE\"" % prop) | 
					
						
							|  |  |  |             elif issubclass(subvalue_type, bpy.types.ID): | 
					
						
							|  |  |  |                 # special case, ID's are always referenced. | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                 node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name))) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     subvalue_ls = list(subvalue) | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     subvalue_ls = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if subvalue_ls is None: | 
					
						
							|  |  |  |                     nodes_items.append((prop, subvalue, subvalue_type)) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     # check if the list contains native types | 
					
						
							|  |  |  |                     subvalue_rna = value.path_resolve(prop, False) | 
					
						
							|  |  |  |                     if type(subvalue_rna).__name__ == "bpy_prop_array": | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                         # check if this is a 0-1 color (rgb, rgba) | 
					
						
							|  |  |  |                         # in that case write as a hexidecimal | 
					
						
							|  |  |  |                         prop_rna = value.bl_rna.properties[prop] | 
					
						
							|  |  |  |                         if (prop_rna.subtype == 'COLOR_GAMMA' and | 
					
						
							|  |  |  |                                 prop_rna.hard_min == 0.0 and | 
					
						
							|  |  |  |                                 prop_rna.hard_max == 1.0 and | 
					
						
							|  |  |  |                                 prop_rna.array_length in {3, 4}): | 
					
						
							|  |  |  |                             # ----- | 
					
						
							|  |  |  |                             # color | 
					
						
							|  |  |  |                             array_value = "#" + "".join(("%.2x" % int(v * 255) for v in subvalue_rna)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             # default | 
					
						
							|  |  |  |                             def str_recursive(s): | 
					
						
							|  |  |  |                                 subsubvalue_type = type(s) | 
					
						
							| 
									
										
										
										
											2012-08-25 11:54:58 +00:00
										 |  |  |                                 if subsubvalue_type in {int, float, bool}: | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                                     return number_to_str(s, subsubvalue_type) | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     return " ".join([str_recursive(si) for si in s]) | 
					
						
							| 
									
										
										
										
											2012-01-17 17:57:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                             array_value = " ".join(str_recursive(v) for v in subvalue_rna) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         node_attrs.append("%s=\"%s\"" % (prop, array_value)) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         nodes_lists.append((prop, subvalue_ls, subvalue_type)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # declare + attributes | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |         if pretty_format: | 
					
						
							| 
									
										
										
										
											2012-02-13 11:14:12 +00:00
										 |  |  |             if node_attrs: | 
					
						
							|  |  |  |                 tmp_str = "<%s " % value_type_name | 
					
						
							|  |  |  |                 tmp_ident = "\n" + ident + (" " * len(tmp_str)) | 
					
						
							|  |  |  |                 fw("%s%s%s>\n" % (ident, tmp_str, tmp_ident.join(node_attrs))) | 
					
						
							|  |  |  |                 del tmp_str | 
					
						
							|  |  |  |                 del tmp_ident | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 fw("%s<%s>\n" % (ident, value_type_name)) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # unique members | 
					
						
							|  |  |  |         for prop, subvalue, subvalue_type in nodes_items: | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |             fw("%s<%s>\n" % (ident_next, prop))  # XXX, this is awkward, how best to solve? | 
					
						
							|  |  |  |             rna2xml_node(ident_next + ident_val, subvalue, value) | 
					
						
							|  |  |  |             fw("%s</%s>\n" % (ident_next, prop))  # XXX, need to check on this. | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # list members | 
					
						
							|  |  |  |         for prop, subvalue, subvalue_type in nodes_lists: | 
					
						
							|  |  |  |             fw("%s<%s>\n" % (ident_next, prop)) | 
					
						
							|  |  |  |             for subvalue_item in subvalue: | 
					
						
							|  |  |  |                 if subvalue_item is not None: | 
					
						
							|  |  |  |                     rna2xml_node(ident_next + ident_val, subvalue_item, value) | 
					
						
							|  |  |  |             fw("%s</%s>\n" % (ident_next, prop)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fw("%s</%s>\n" % (ident, value_type_name)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |     # ------------------------------------------------------------------------- | 
					
						
							| 
									
										
										
										
											2012-11-28 06:43:04 +00:00
										 |  |  |     # needs re-working to be generic | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |     if root_node: | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         fw("%s<%s>\n" % (root_ident, root_node)) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # bpy.data | 
					
						
							|  |  |  |     if method == 'DATA': | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         ident = root_ident + ident_val | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |         for attr in dir(root_rna): | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |             # exceptions | 
					
						
							|  |  |  |             if attr.startswith("_"): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             elif attr in root_rna_skip: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |             value = getattr(root_rna, attr) | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 ls = value[:] | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 ls = None | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |             if type(ls) == list: | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |                 fw("%s<%s>\n" % (ident, attr)) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                 for blend_id in ls: | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |                     rna2xml_node(ident + ident_val, blend_id, None) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                 fw("%s</%s>\n" % (ident_val, attr)) | 
					
						
							|  |  |  |     # any attribute | 
					
						
							|  |  |  |     elif method == 'ATTR': | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         rna2xml_node(root_ident, root_rna, None) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |     if root_node: | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         fw("%s</%s>\n" % (root_ident, root_node)) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def xml2rna(root_xml, | 
					
						
							|  |  |  |             root_rna=None,  # must be set | 
					
						
							|  |  |  |             ): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def rna2xml_node(xml_node, value): | 
					
						
							|  |  |  | #        print("evaluating:", xml_node.nodeName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # --------------------------------------------------------------------- | 
					
						
							|  |  |  |         # Simple attributes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for attr in xml_node.attributes.keys(): | 
					
						
							|  |  |  | #            print("  ", attr) | 
					
						
							|  |  |  |             subvalue = getattr(value, attr, Ellipsis) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if subvalue is Ellipsis: | 
					
						
							|  |  |  |                 print("%s.%s not found" % (type(value).__name__, attr)) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 value_xml = xml_node.attributes[attr].value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 subvalue_type = type(subvalue) | 
					
						
							|  |  |  |                 tp_name = 'UNKNOWN' | 
					
						
							|  |  |  |                 if subvalue_type == float: | 
					
						
							|  |  |  |                     value_xml_coerce = float(value_xml) | 
					
						
							|  |  |  |                     tp_name = 'FLOAT' | 
					
						
							|  |  |  |                 elif subvalue_type == int: | 
					
						
							|  |  |  |                     value_xml_coerce = int(value_xml) | 
					
						
							|  |  |  |                     tp_name = 'INT' | 
					
						
							|  |  |  |                 elif subvalue_type == bool: | 
					
						
							|  |  |  |                     value_xml_coerce = {'TRUE': True, 'FALSE': False}[value_xml] | 
					
						
							|  |  |  |                     tp_name = 'BOOL' | 
					
						
							|  |  |  |                 elif subvalue_type == str: | 
					
						
							|  |  |  |                     value_xml_coerce = value_xml | 
					
						
							|  |  |  |                     tp_name = 'STR' | 
					
						
							|  |  |  |                 elif hasattr(subvalue, "__len__"): | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                     if value_xml.startswith("#"): | 
					
						
							|  |  |  |                         # read hexidecimal value as float array | 
					
						
							|  |  |  |                         value_xml_split = value_xml[1:] | 
					
						
							| 
									
										
										
										
											2012-10-08 08:28:05 +00:00
										 |  |  |                         value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                         del value_xml_split | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         value_xml_split = value_xml.split() | 
					
						
							|  |  |  |                         try: | 
					
						
							|  |  |  |                             value_xml_coerce = [int(v) for v in value_xml_split] | 
					
						
							|  |  |  |                         except ValueError: | 
					
						
							| 
									
										
										
										
											2012-09-25 05:17:23 +00:00
										 |  |  |                             try: | 
					
						
							|  |  |  |                                 value_xml_coerce = [float(v) for v in value_xml_split] | 
					
						
							| 
									
										
										
										
											2012-09-26 21:19:51 +00:00
										 |  |  |                             except ValueError:  # bool vector property | 
					
						
							| 
									
										
										
										
											2012-09-25 05:17:23 +00:00
										 |  |  |                                 value_xml_coerce = [{'TRUE': True, 'FALSE': False}[v] for v in value_xml_split] | 
					
						
							| 
									
										
										
										
											2012-01-01 10:05:04 +00:00
										 |  |  |                         del value_xml_split | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                     tp_name = 'ARRAY' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #                print("  %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type)) | 
					
						
							| 
									
										
										
										
											2012-12-13 09:46:24 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     setattr(value, attr, value_xml_coerce) | 
					
						
							|  |  |  |                 except ValueError: | 
					
						
							|  |  |  |                     # size mismatch | 
					
						
							|  |  |  |                     val = getattr(value, attr) | 
					
						
							|  |  |  |                     if len(val) < len(value_xml_coerce): | 
					
						
							|  |  |  |                         setattr(value, attr, value_xml_coerce[:len(val)]) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         setattr(value, attr, list(value_xml_coerce) + list(val)[len(value_xml_coerce):]) | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # --------------------------------------------------------------------- | 
					
						
							|  |  |  |         # Complex attributes | 
					
						
							|  |  |  |         for child_xml in xml_node.childNodes: | 
					
						
							|  |  |  |             if child_xml.nodeType == child_xml.ELEMENT_NODE: | 
					
						
							|  |  |  |                 # print() | 
					
						
							|  |  |  |                 # print(child_xml.nodeName) | 
					
						
							|  |  |  |                 subvalue = getattr(value, child_xml.nodeName, None) | 
					
						
							|  |  |  |                 if subvalue is not None: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     elems = [] | 
					
						
							|  |  |  |                     for child_xml_real in child_xml.childNodes: | 
					
						
							|  |  |  |                         if child_xml_real.nodeType == child_xml_real.ELEMENT_NODE: | 
					
						
							|  |  |  |                             elems.append(child_xml_real) | 
					
						
							|  |  |  |                     del child_xml_real | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if hasattr(subvalue, "__len__"): | 
					
						
							|  |  |  |                         # Collection | 
					
						
							|  |  |  |                         if len(elems) != len(subvalue): | 
					
						
							|  |  |  |                             print("Size Mismatch! collection:", child_xml.nodeName) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             for i in range(len(elems)): | 
					
						
							|  |  |  |                                 child_xml_real = elems[i] | 
					
						
							|  |  |  |                                 subsubvalue = subvalue[i] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                 if child_xml_real is None or subsubvalue is None: | 
					
						
							|  |  |  |                                     print("None found %s - %d collection:", (child_xml.nodeName, i)) | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     rna2xml_node(child_xml_real, subsubvalue) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  | #                        print(elems) | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                         if len(elems) == 1: | 
					
						
							|  |  |  |                             # sub node named by its type | 
					
						
							|  |  |  |                             child_xml_real, = elems | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |                             # print(child_xml_real, subvalue) | 
					
						
							|  |  |  |                             rna2xml_node(child_xml_real, subvalue) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             # empty is valid too | 
					
						
							|  |  |  |                             pass | 
					
						
							| 
									
										
										
										
											2012-01-01 04:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 08:09:30 +00:00
										 |  |  |     rna2xml_node(root_xml, root_rna) | 
					
						
							| 
									
										
										
										
											2012-01-10 15:08:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # ----------------------------------------------------------------------------- | 
					
						
							|  |  |  | # Utility function used by presets. | 
					
						
							|  |  |  | # The idea is you can run a preset like a script with a few args. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This roughly matches the operator 'bpy.ops.script.python_file_run' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 17:57:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-10 16:20:01 +00:00
										 |  |  | def _get_context_val(context, path): | 
					
						
							|  |  |  |     path_full = "context." + path | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         value = eval(path_full) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         import traceback | 
					
						
							|  |  |  |         traceback.print_exc() | 
					
						
							|  |  |  |         print("Error: %r could not be found" % path_full) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value = Ellipsis | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 17:57:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-10 15:08:12 +00:00
										 |  |  | def xml_file_run(context, filepath, rna_map): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     import xml.dom.minidom | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xml_nodes = xml.dom.minidom.parse(filepath) | 
					
						
							|  |  |  |     bpy_xml = xml_nodes.getElementsByTagName("bpy")[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for rna_path, xml_tag in rna_map: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # first get xml | 
					
						
							|  |  |  |         # TODO, error check | 
					
						
							|  |  |  |         xml_node = bpy_xml.getElementsByTagName(xml_tag)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-10 16:20:01 +00:00
										 |  |  |         value = _get_context_val(context, rna_path) | 
					
						
							| 
									
										
										
										
											2012-01-10 15:08:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if value is not Ellipsis and value is not None: | 
					
						
							| 
									
										
										
										
											2012-03-26 02:39:05 +00:00
										 |  |  |             print("  loading XML: %r -> %r" % (filepath, rna_path)) | 
					
						
							| 
									
										
										
										
											2012-01-10 16:20:01 +00:00
										 |  |  |             xml2rna(xml_node, root_rna=value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def xml_file_write(context, filepath, rna_map): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-19 22:17:19 +00:00
										 |  |  |     file = open(filepath, "w", encoding="utf-8") | 
					
						
							| 
									
										
										
										
											2012-01-10 16:20:01 +00:00
										 |  |  |     fw = file.write | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fw("<bpy>\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for rna_path, xml_tag in rna_map: | 
					
						
							|  |  |  |         # xml_tag is ignored, we get this from the rna | 
					
						
							|  |  |  |         value = _get_context_val(context, rna_path) | 
					
						
							| 
									
										
										
										
											2012-01-11 00:22:21 +00:00
										 |  |  |         rna2xml(fw, | 
					
						
							|  |  |  |                 root_rna=value, | 
					
						
							|  |  |  |                 method='ATTR', | 
					
						
							|  |  |  |                 root_ident="  ", | 
					
						
							|  |  |  |                 ident_val="  ") | 
					
						
							| 
									
										
										
										
											2012-01-10 16:20:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fw("</bpy>\n") | 
					
						
							|  |  |  |     file.close() |