diff --git a/release/scripts/modules/extensions_framework/__init__.py b/release/scripts/modules/extensions_framework/__init__.py
deleted file mode 100644
index 6c4ced376c5..00000000000
--- a/release/scripts/modules/extensions_framework/__init__.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-import time
-
-import bpy
-
-from extensions_framework.ui import EF_OT_msg
-
-bpy.types.register(EF_OT_msg)
-del EF_OT_msg
-
-
-def log(str, popup=False, module_name='EF'):
- """Print a message to the console, prefixed with the module_name
- and the current time. If the popup flag is True, the message will
- be raised in the UI as a warning using the operator bpy.ops.ef.msg.
-
- """
- print("[%s %s] %s" %
- (module_name, time.strftime('%Y-%b-%d %H:%M:%S'), str))
- if popup:
- bpy.ops.ef.msg(
- msg_type='WARNING',
- msg_text=str
- )
-
-
-added_property_cache = {}
-
-def init_properties(obj, props, cache=True):
- """Initialise custom properties in the given object or type.
- The props list is described in the declarative_property_group
- class definition. If the cache flag is False, this function
- will attempt to redefine properties even if they have already been
- added.
-
- """
-
- if not obj in added_property_cache.keys():
- added_property_cache[obj] = []
-
- for prop in props:
- try:
- if cache and prop['attr'] in added_property_cache[obj]:
- continue
-
- if prop['type'] == 'bool':
- t = bpy.props.BoolProperty
- a = {k: v for k,v in prop.items() if k in ['name',
- 'description','default']}
- elif prop['type'] == 'collection':
- t = bpy.props.CollectionProperty
- a = {k: v for k,v in prop.items() if k in ["ptype", "name",
- "description"]}
- a['type'] = a['ptype']
- del a['ptype']
- elif prop['type'] == 'enum':
- t = bpy.props.EnumProperty
- a = {k: v for k,v in prop.items() if k in ["items", "name",
- "description", "default"]}
- elif prop['type'] == 'float':
- t = bpy.props.FloatProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description", "min", "max", "soft_min", "soft_max",
- "default", "precision"]}
- elif prop['type'] == 'float_vector':
- t = bpy.props.FloatVectorProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description", "min", "max", "soft_min", "soft_max",
- "default", "precision", "size", "subtype"]}
- elif prop['type'] == 'int':
- t = bpy.props.IntProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description", "min", "max", "soft_min", "soft_max",
- "default"]}
- elif prop['type'] == 'pointer':
- t = bpy.props.PointerProperty
- a = {k: v for k,v in prop.items() if k in ["ptype", "name",
- "description"]}
- a['type'] = a['ptype']
- del a['ptype']
- elif prop['type'] == 'string':
- t = bpy.props.StringProperty
- a = {k: v for k,v in prop.items() if k in ["name",
- "description", "maxlen", "default", "subtype"]}
- else:
- continue
-
- setattr(obj, prop['attr'], t(**a))
-
- added_property_cache[obj].append(prop['attr'])
- except KeyError:
- # Silently skip invalid entries in props
- continue
-
-
-class declarative_property_group(bpy.types.IDPropertyGroup):
- """A declarative_property_group describes a set of logically
- related properties, using a declarative style to list each
- property type, name, values, and other relevant information.
- The information provided for each property depends on the
- property's type.
-
- The properties list attribute in this class describes the
- properties present in this group.
-
- Some additional information about the properties in this group
- can be specified, so that a UI can be generated to display them.
- To that end, the controls list attribute and the visibility dict
- attribute are present here, to be read and interpreted by a
- property_group_renderer object.
- See extensions_framework.ui.property_group_renderer.
-
- """
-
- """This list controls the order of property layout when rendered
- by a property_group_renderer. This can be a nested list, where each
- list becomes a row in the panel layout. Nesting may be to any depth.
-
- """
- controls = []
-
- """The visibility dict controls the display of properties based on
- the value of other properties. See extensions_framework.validate
- for test syntax.
-
- """
- visibility = {}
-
- """The properties list describes each property to be created. Each
- item should be a dict of args to pass to a
- bpy.props.>Property function, with the exception of 'type'
- which is used and stripped by extensions_framework in order to
- determine which Property creation function to call.
-
- Example item:
- {
- 'type': 'int', # bpy.props.IntProperty
- 'attr': 'threads', # bpy.types..threads
- 'name': 'Render Threads', # Rendered next to the UI
- 'description': 'Number of threads to use', # Tooltip text in the UI
- 'default': 1,
- 'min': 1,
- 'soft_min': 1,
- 'max': 64,
- 'soft_max': 64
- }
-
- """
- properties = []
-
- def draw_callback(self, context):
- """Sub-classes can override this to get a callback when
- rendering is completed by a property_group_renderer sub-class.
-
- """
-
- pass
-
- @classmethod
- def get_exportable_properties(cls):
- """Return a list of properties which have the 'save_in_preset' key
- set to True, and hence should be saved into preset files.
-
- """
-
- out = []
- for prop in cls.properties:
- if 'save_in_preset' in prop.keys() and prop['save_in_preset']:
- out.append(prop)
- return out
diff --git a/release/scripts/modules/extensions_framework/engine.py b/release/scripts/modules/extensions_framework/engine.py
deleted file mode 100644
index 0a6fecb034a..00000000000
--- a/release/scripts/modules/extensions_framework/engine.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-from extensions_framework.plugin import plugin
-
-class engine_base(plugin):
- """Render Engine plugin base class
-
- TODO: Remove, this class hasn't grown to be useful
-
- """
-
- bl_label = 'Abstract Render Engine Base Class'
-
- def render(self, scene):
- pass
diff --git a/release/scripts/modules/extensions_framework/outputs/__init__.py b/release/scripts/modules/extensions_framework/outputs/__init__.py
deleted file mode 100644
index f05ed25fbad..00000000000
--- a/release/scripts/modules/extensions_framework/outputs/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
diff --git a/release/scripts/modules/extensions_framework/outputs/xml_output.py b/release/scripts/modules/extensions_framework/outputs/xml_output.py
deleted file mode 100644
index 3b1102c1888..00000000000
--- a/release/scripts/modules/extensions_framework/outputs/xml_output.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-import xml.etree.cElementTree as ET
-import xml.dom.minidom as MD
-
-class xml_output(object):
- """This class serves to describe an XML output, it uses
- cElementTree and minidom to construct and format the XML
- data.
-
- """
-
- """The format dict describes the XML structure that this class
- should generate, and which properties should be used to fill
- the XML data structure
-
- """
- format = {}
-
- def __str__(self):
- return ET.tostring(self.root)
-
- def write_pretty(self, file):
- """Write a formatted XML string to file"""
- xml_dom = MD.parseString(ET.tostring(self.root, encoding='utf-8'))
- xml_dom.writexml(file, addindent=' ', newl='\n', encoding='utf-8')
-
- def pretty(self):
- """Return a formatted XML string"""
- xml_str = MD.parseString(ET.tostring(self.root))
- return xml_str.toprettyxml()
-
- def get_format(self):
- """This should be overridden in classes that produce XML
- conditionally
-
- """
- return self.format
-
- def compute(self, context):
- """Compute the XML output from the input format"""
- self.context = context
-
- self.root = ET.Element(self.root_element)
- self.parse_dict(self.get_format(), self.root)
-
- return self.root
-
- """Formatting functions for various data types"""
- format_types = {
- 'bool': lambda c,x: str(x).lower(),
- 'collection': lambda c,x: x,
- 'enum': lambda c,x: x,
- 'float': lambda c,x: x,
- 'int': lambda c,x: x,
- 'pointer': lambda c,x: x,
- 'string': lambda c,x: x,
- }
-
- def parse_dict(self, d, elem):
- """Parse the values in the format dict and collect the
- formatted data into XML structure starting at self.root
-
- """
- for key in d.keys():
- # tuple provides multiple child elements
- if type(d[key]) is tuple:
- for cd in d[key]:
- self.parse_dict({key:cd}, elem)
- continue # don't create empty element for tuple child
-
- x = ET.SubElement(elem, key)
-
- # dictionary provides nested elements
- if type(d[key]) is dict:
- self.parse_dict(d[key], x)
-
- # list provides direct value insertion
- elif type(d[key]) is list:
- x.text = ' '.join([str(i) for i in d[key]])
-
- # else look up property
- else:
- for p in self.properties:
- if d[key] == p['attr']:
- if 'compute' in p.keys():
- x.text = str(p['compute'](self.context, self))
- else:
- x.text = str(
- self.format_types[p['type']](self.context,
- getattr(self, d[key]))
- )
diff --git a/release/scripts/modules/extensions_framework/plugin.py b/release/scripts/modules/extensions_framework/plugin.py
deleted file mode 100644
index 76f41930fdd..00000000000
--- a/release/scripts/modules/extensions_framework/plugin.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-import bpy
-
-from extensions_framework import init_properties
-from extensions_framework import log
-
-class plugin(object):
- """Base class for plugins which wish to make use of utilities
- provided in extensions_framework. Using the property_groups
- attribute and the install() and uninstall() methods, a large number
- of custom scene properties can be easily defined, displayed and
- managed.
-
- TODO: Rename, 'extension' would be more appropriate than 'plugin'
-
- """
-
- """The property_groups defines a list of declarative_property_group
- types to create in specified types during the initialisation of the
- plugin.
- Item format:
- ('bpy.type prototype to attach to', )
-
- Example item:
- ('Scene', myaddon_property_group)
- In this example, a new property group will be attached to
- bpy.types.Scene and all of the properties described in that group
- will be added to it.
- See extensions_framework.declarative_property_group.
-
- """
- property_groups = []
-
- @classmethod
- def install(r_class):
- """Initialise this plugin. So far, all this does is to create
- custom property groups specified in the property_groups
- attribute.
-
- """
- for property_group_parent, property_group in r_class.property_groups:
- call_init = False
- if property_group_parent is not None:
- prototype = getattr(bpy.types, property_group_parent)
- if not hasattr(prototype, property_group.__name__):
- init_properties(prototype, [{
- 'type': 'pointer',
- 'attr': property_group.__name__,
- 'ptype': property_group,
- 'name': property_group.__name__,
- 'description': property_group.__name__
- }])
- call_init = True
- else:
- call_init = True
-
- if call_init:
- init_properties(property_group, property_group.properties)
-
- log('Extension "%s" initialised' % r_class.bl_label)
-
- @classmethod
- def uninstall(r_class):
- """Unregister property groups in reverse order"""
- reverse_property_groups = [p for p in r_class.property_groups]
- reverse_property_groups.reverse()
- for property_group_parent, property_group in reverse_property_groups:
- prototype = getattr(bpy.types, property_group_parent)
- prototype.RemoveProperty(property_group.__name__)
diff --git a/release/scripts/modules/extensions_framework/ui.py b/release/scripts/modules/extensions_framework/ui.py
deleted file mode 100644
index 5bbd69c0628..00000000000
--- a/release/scripts/modules/extensions_framework/ui.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-import bpy
-
-from extensions_framework.validate import Visibility
-
-class EF_OT_msg(bpy.types.Operator):
- """An operator to show simple messages in the UI"""
- bl_idname = 'ef.msg'
- bl_label = 'Show UI Message'
- msg_type = bpy.props.StringProperty(default='INFO')
- msg_text = bpy.props.StringProperty(default='')
- def execute(self, context):
- self.report({self.properties.msg_type}, self.properties.msg_text)
- return {'FINISHED'}
-
-def _get_item_from_context(context, path):
- """Utility to get an object when the path to it is known:
- _get_item_from_context(context, ['a','b','c']) returns
- context.a.b.c
- No error checking is performed other than checking that context
- is not None. Exceptions caused by invalid path should be caught in
- the calling code.
-
- """
-
- if context is not None:
- for p in path:
- context = getattr(context, p)
- return context
-
-class property_group_renderer(object):
- """Mix-in class for sub-classes of bpy.types.Panel. This class
- will provide the draw() method which implements drawing one or
- more property groups derived from
- extensions_framework.declarative_propery_group.
- The display_property_groups list attribute describes which
- declarative_property_groups should be drawn in the Panel, and
- how to extract those groups from the context passed to draw().
-
- """
-
- """The display_property_groups list attribute specifies which
- custom declarative_property_groups this panel should draw, and
- where to find that property group in the active context.
- Example item:
- ( ('scene',), 'myaddon_property_group')
- In this case, this renderer will look for properties in
- context.scene.myaddon_property_group to draw in the Panel.
-
- """
- display_property_groups = []
-
- def draw(self, context):
- """Sub-classes should override this if they need to display
- other (object-related) property groups. super().draw(context)
- can be a useful call in those cases.
-
- """
- for property_group_path, property_group_name in \
- self.display_property_groups:
- ctx = _get_item_from_context(context, property_group_path)
- property_group = getattr(ctx, property_group_name)
- for p in property_group.controls:
- self.draw_column(p, self.layout, ctx, context,
- property_group=property_group)
- property_group.draw_callback(context)
-
- def check_visibility(self, lookup_property, property_group):
- """Determine if the lookup_property should be drawn in the Panel"""
- vt = Visibility(property_group)
- if lookup_property in property_group.visibility.keys():
- if hasattr(property_group, lookup_property):
- member = getattr(property_group, lookup_property)
- else:
- member = None
- return vt.test_logic(member,
- property_group.visibility[lookup_property])
- else:
- return True
-
- # tab_level = 0
-
- def is_real_property(self, lookup_property, property_group):
- for prop in property_group.properties:
- if prop['attr'] == lookup_property:
- return prop['type'] not in ['text', 'prop_search']
-
- return False
-
- def draw_column(self, control_list_item, layout, context,
- supercontext=None, property_group=None):
- # self.tab_level += 1
- """Draw a column's worth of UI controls in this Panel"""
- if type(control_list_item) is list:
- draw_row = False
-
- found_percent = None
- # print('\t'*self.tab_level, '--', property_group, '--')
- for sp in control_list_item:
- # print('\t'*self.tab_level, sp)
- if type(sp) is float:
- found_percent = sp
- elif type(sp) is list:
- for ssp in [s for s in sp if self.is_real_property(s, property_group)]:
- draw_row = draw_row or self.check_visibility(ssp,
- property_group)
- # print('\t'*self.tab_level, 'List: ', draw_row)
- else:
- draw_row = draw_row or self.check_visibility(sp,
- property_group)
- # print('\t'*self.tab_level, 'Single: ', draw_row)
- # print('\t'*self.tab_level, '-->', draw_row)
- # print('\t'*self.tab_level, '--', property_group, '--')
-
- next_items = [s for s in control_list_item if type(s) in [str, list]]
- if draw_row and len(next_items) > 0:
- if found_percent is not None:
- splt = layout.split(percentage=found_percent)
- else:
- splt = layout.row(True)
- for sp in next_items:
- col2 = splt.column()
- self.draw_column(sp, col2, context, supercontext,
- property_group)
- else:
- if self.check_visibility(control_list_item, property_group):
-
- for current_property in property_group.properties:
- if current_property['attr'] == control_list_item:
- current_property_keys = current_property.keys()
- if 'type' in current_property_keys:
-
- if current_property['type'] in ['int', 'float',
- 'float_vector', 'enum', 'string']:
- layout.prop(
- property_group,
- control_list_item,
- text = current_property['name'],
- expand = current_property['expand'] \
- if 'expand' in current_property_keys \
- else False,
- slider = current_property['slider'] \
- if 'slider' in current_property_keys \
- else False,
- toggle = current_property['toggle'] \
- if 'toggle' in current_property_keys \
- else False,
- icon_only = current_property['icon_only'] \
- if 'icon_only' in current_property_keys \
- else False,
- event = current_property['event'] \
- if 'event' in current_property_keys \
- else False,
- full_event = current_property['full_event'] \
- if 'full_event' in current_property_keys \
- else False,
- emboss = current_property['emboss'] \
- if 'emboss' in current_property_keys \
- else True,
- )
- if current_property['type'] in ['bool']:
- layout.prop(
- property_group,
- control_list_item,
- text = current_property['name'],
- toggle = current_property['toggle'] \
- if 'toggle' in current_property_keys \
- else False,
- icon_only = current_property['icon_only'] \
- if 'icon_only' in current_property_keys \
- else False,
- event = current_property['event'] \
- if 'event' in current_property_keys \
- else False,
- full_event = current_property['full_event'] \
- if 'full_event' in current_property_keys \
- else False,
- emboss = current_property['emboss'] \
- if 'emboss' in current_property_keys \
- else True,
- )
- elif current_property['type'] in ['operator']:
- layout.operator(current_property['operator'],
- text = current_property['text'],
- icon = current_property['icon']
- )
-
- elif current_property['type'] in ['text']:
- layout.label(
- text = current_property['name']
- )
-
- elif current_property['type'] in ['template_list']:
- layout.template_list(
- current_property['src'](supercontext, context),
- current_property['src_attr'],
- current_property['trg'](supercontext, context),
- current_property['trg_attr'],
- rows = 4 \
- if not 'rows' in current_property_keys \
- else current_property['rows'],
- maxrows = 4 \
- if not 'rows' in current_property_keys \
- else current_property['rows'],
- type = 'DEFAULT' \
- if not 'list_type' in current_property_keys \
- else current_property['list_type']
- )
-
- elif current_property['type'] in ['prop_search']:
- layout.prop_search(
- current_property['trg'](supercontext,
- context),
- current_property['trg_attr'],
- current_property['src'](supercontext,
- context),
- current_property['src_attr'],
- text = current_property['name'],
- )
- else:
- layout.prop(property_group, control_list_item)
-
- # Fire a draw callback if specified
- if 'draw' in current_property_keys:
- current_property['draw'](supercontext, context)
-
- break
- # self.tab_level -= 1
diff --git a/release/scripts/modules/extensions_framework/util.py b/release/scripts/modules/extensions_framework/util.py
deleted file mode 100644
index dc737c6e4ae..00000000000
--- a/release/scripts/modules/extensions_framework/util.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-import configparser
-import datetime
-import os
-import tempfile
-import threading
-
-import bpy
-
-"""List of possibly appropriate paths to load/save addon config from/to"""
-config_paths = []
-if bpy.utils.user_resource('CONFIG') != "": config_paths.append(bpy.utils.user_resource('CONFIG'))
-if bpy.utils.user_resource('SCRIPTS') != "": config_paths.append(bpy.utils.user_resource('SCRIPTS'))
-for pth in bpy.utils.script_paths():
- if pth != "": config_paths.append(pth)
-
-"""This path is set at the start of export, so that calls to
-path_relative_to_export() can make all exported paths relative to
-this one.
-"""
-export_path = '';
-
-def path_relative_to_export(p):
- """Return a path that is relative to the export path"""
- global export_path
- p = filesystem_path(p)
- try:
- relp = os.path.relpath(p, os.path.dirname(export_path))
- except ValueError: # path on different drive on windows
- relp = p
-
- return relp.replace('\\', '/')
-
-def filesystem_path(p):
- """Resolve a relative Blender path to a real filesystem path"""
- if p.startswith('//'):
- pout = bpy.path.abspath(p)
- else:
- pout = os.path.realpath(p)
-
- return pout.replace('\\', '/')
-
-# TODO: - somehow specify TYPES to get/set from config
-
-def find_config_value(module, section, key, default):
- """Attempt to find the configuration value specified by string key
- in the specified section of module's configuration file. If it is
- not found, return default.
-
- """
- global config_paths
- fc = []
- for p in config_paths:
- if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK):
- fc.append( '/'.join([p, '%s.cfg' % module]))
-
- if len(fc) < 1:
- print('Cannot find %s config file path' % module)
- return default
-
- cp = configparser.SafeConfigParser()
-
- cfg_files = cp.read(fc)
- if len(cfg_files) > 0:
- try:
- val = cp.get(section, key)
- if val == 'true':
- return True
- elif val == 'false':
- return False
- else:
- return val
- except:
- return default
- else:
- return default
-
-def write_config_value(module, section, key, value):
- """Attempt to write the configuration value specified by string key
- in the specified section of module's configuration file.
-
- """
- global config_paths
- fc = []
- for p in config_paths:
- if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK):
- fc.append( '/'.join([p, '%s.cfg' % module]))
-
- if len(fc) < 1:
- raise Exception('Cannot find a writable path to store %s config file' %
- module)
-
- cp = configparser.SafeConfigParser()
-
- cfg_files = cp.read(fc)
-
- if not cp.has_section(section):
- cp.add_section(section)
-
- if value == True:
- cp.set(section, key, 'true')
- elif value == False:
- cp.set(section, key, 'false')
- else:
- cp.set(section, key, value)
-
- if len(cfg_files) < 1:
- cfg_files = fc
-
- fh=open(cfg_files[0],'w')
- cp.write(fh)
- fh.close()
-
- return True
-
-def scene_filename():
- """Construct a safe scene filename, using 'untitled' instead of ''"""
- filename = os.path.splitext(os.path.basename(bpy.data.filepath))[0]
- if filename == '':
- filename = 'untitled'
- return bpy.path.clean_name(filename)
-
-def temp_directory():
- """Return the system temp directory"""
- return tempfile.gettempdir()
-
-def temp_file(ext='tmp'):
- """Get a temporary filename with the given extension. This function
- will actually attempt to create the file."""
- tf, fn = tempfile.mkstemp(suffix='.%s'%ext)
- os.close(tf)
- return fn
-
-class TimerThread(threading.Thread):
- """Periodically call self.kick(). The period of time in seconds
- between calling is given by self.KICK_PERIOD, and the first call
- may be delayed by setting self.STARTUP_DELAY, also in seconds.
- self.kick() will continue to be called at regular intervals until
- self.stop() is called. Since this is a thread, calling self.join()
- may be wise after calling self.stop() if self.kick() is performing
- a task necessary for the continuation of the program.
- The object that creates this TimerThread may pass into it data
- needed during self.kick() as a dict LocalStorage in __init__().
-
- """
- STARTUP_DELAY = 0
- KICK_PERIOD = 8
-
- active = True
- timer = None
-
- LocalStorage = None
-
- def __init__(self, LocalStorage=dict()):
- threading.Thread.__init__(self)
- self.LocalStorage = LocalStorage
-
- def set_kick_period(self, period):
- """Adjust the KICK_PERIOD between __init__() and start()"""
- self.KICK_PERIOD = period + self.STARTUP_DELAY
-
- def stop(self):
- """Stop this timer. This method does not join()"""
- self.active = False
- if self.timer is not None:
- self.timer.cancel()
-
- def run(self):
- """Timed Thread loop"""
- while self.active:
- self.timer = threading.Timer(self.KICK_PERIOD, self.kick_caller)
- self.timer.start()
- if self.timer.isAlive(): self.timer.join()
-
- def kick_caller(self):
- """Intermediary between the kick-wait-loop and kick to allow
- adjustment of the first KICK_PERIOD by STARTUP_DELAY
-
- """
- if self.STARTUP_DELAY > 0:
- self.KICK_PERIOD -= self.STARTUP_DELAY
- self.STARTUP_DELAY = 0
-
- self.kick()
-
- def kick(self):
- """Sub-classes do their work here"""
- pass
-
-def format_elapsed_time(t):
- """Format a duration in seconds as an HH:MM:SS format time"""
-
- td = datetime.timedelta(seconds=t)
- min = td.days*1440 + td.seconds/60.0
- hrs = td.days*24 + td.seconds/3600.0
-
- return '%i:%02i:%02i' % (hrs, min%60, td.seconds%60)
diff --git a/release/scripts/modules/extensions_framework/validate.py b/release/scripts/modules/extensions_framework/validate.py
deleted file mode 100644
index d9cee8fd807..00000000000
--- a/release/scripts/modules/extensions_framework/validate.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Extensions Framework
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see .
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-"""
-Pure logic and validation class.
-
-By using a Subject object, and a dict of described logic tests, it
-is possible to arrive at a True or False result for various purposes:
-1. Data validation
-2. UI control visibility
-
-A Subject can be any object whose members are readable with getattr() :
-class Subject(object):
- a = 0
- b = 1
- c = 'foo'
- d = True
- e = False
- f = 8
- g = 'bar'
-
-
-Tests are described thus:
-
-Use the special list types Logic_AND and Logic_OR to describe
-combinations of values and other members. Use Logic_Operator for
-numerical comparison.
-
-With regards to Subject, each of these evaluate to True:
-TESTA = {
- 'a': 0,
- 'c': Logic_OR([ 'foo', 'bar' ]),
- 'd': Logic_AND([True, True]),
- 'f': Logic_AND([8, {'b': 1}]),
- 'e': {'b': Logic_Operator({'gte':1, 'lt':3}) },
- 'g': Logic_OR([ 'baz', Logic_AND([{'b': 1}, {'f': 8}]) ])
-}
-
-With regards to Subject, each of these evaluate to False:
-TESTB = {
- 'a': 'foo',
- 'c': Logic_OR([ 'bar', 'baz' ]),
- 'd': Logic_AND([ True, 'foo' ]),
- 'f': Logic_AND([9, {'b': 1}]),
- 'e': {'b': Logic_Operator({'gte':-10, 'lt': 1}) },
- 'g': Logic_OR([ 'baz', Logic_AND([{'b':0}, {'f': 8}]) ])
-}
-
-With regards to Subject, this test is invalid
-TESTC = {
- 'n': 0
-}
-
-Tests are executed thus:
-S = Subject()
-L = Logician(S)
-L.execute(TESTA)
-
-"""
-
-class Logic_AND(list):
- pass
-class Logic_OR(list):
- pass
-class Logic_Operator(dict):
- pass
-
-class Logician(object):
- """Given a subject and a dict that describes tests to perform on
- its members, this class will evaluate True or False results for
- each member/test pair. See the examples below for test syntax.
-
- """
-
- subject = None
- def __init__(self, subject):
- self.subject = subject
-
- def get_member(self, member_name):
- """Get a member value from the subject object. Raise exception
- if subject is None or member not found.
-
- """
- if self.subject is None:
- raise Exception('Cannot run tests on a subject which is None')
-
- return getattr(self.subject, member_name)
-
- def test_logic(self, member, logic, operator='eq'):
- """Find the type of test to run on member, and perform that test"""
-
- if type(logic) is dict:
- return self.test_dict(member, logic)
- elif type(logic) is Logic_AND:
- return self.test_and(member, logic)
- elif type(logic) is Logic_OR:
- return self.test_or(member, logic)
- elif type(logic) is Logic_Operator:
- return self.test_operator(member, logic)
- else:
- # compare the value, I think using Logic_Operator() here
- # allows completeness in test_operator(), but I can't put
- # my finger on why for the minute
- return self.test_operator(member,
- Logic_Operator({operator: logic}))
-
- def test_operator(self, member, value):
- """Execute the operators contained within value and expect that
- ALL operators are True
-
- """
-
- # something in this method is incomplete, what if operand is
- # a dict, Logic_AND, Logic_OR or another Logic_Operator ?
- # Do those constructs even make any sense ?
-
- result = True
- for operator, operand in value.items():
- operator = operator.lower().strip()
- if operator in ['eq', '==']:
- result &= member==operand
- if operator in ['not', '!=']:
- result &= member!=operand
- if operator in ['lt', '<']:
- result &= member']:
- result &= member>operand
- if operator in ['gte', '>=']:
- result &= member>=operand
- if operator in ['and', '&']:
- result &= member&operand
- if operator in ['or', '|']:
- result &= member|operand
- if operator in ['len']:
- result &= len(member)==operand
- # I can think of some more, but they're probably not useful.
-
- return result
-
- def test_or(self, member, logic):
- """Member is a value, logic is a set of values, ANY of which
- can be True
-
- """
- result = False
- for test in logic:
- result |= self.test_logic(member, test)
-
- return result
-
- def test_and(self, member, logic):
- """Member is a value, logic is a list of values, ALL of which
- must be True
-
- """
- result = True
- for test in logic:
- result &= self.test_logic(member, test)
-
- return result
-
- def test_dict(self, member, logic):
- """Member is a value, logic is a dict of other members to
- compare to. All other member tests must be True
-
- """
- result = True
- for other_member, test in logic.items():
- result &= self.test_logic(self.get_member(other_member), test)
-
- return result
-
- def execute(self, test):
- """Subject is an object, test is a dict of {member: test} pairs
- to perform on subject's members. Wach key in test is a member
- of subject.
-
- """
-
- for member_name, logic in test.items():
- result = self.test_logic(self.get_member(member_name), logic)
- print('member %s is %s' % (member_name, result))
-
-# A couple of name aliases
-class Validation(Logician):
- pass
-class Visibility(Logician):
- pass