# #####
# This file is part of the RobotDesigner of the Neurorobotics subproject (SP10)
# in the Human Brain Project (HBP).
# It has been forked from the RobotEditor (https://gitlab.com/h2t/roboteditor)
# developed at the Karlsruhe Institute of Technology in the
# High Performance Humanoid Technologies Laboratory (H2T).
# #####
# ##### 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.
#
# ##### END GPL LICENSE BLOCK #####
# #####
#
# Copyright (c)
#
# Changes:
#
# 2016-01-15: Stefan Ulbrich (FZI) (FZI Forschungszentrum Informatik)
# Template created
# Today: Your Name
# Please add ALWAYS your modifications
#
# ######
"""
Sphinx-autodoc tag
"""
# System imports
import os
from inspect import getmembers, isclass
# Blender imports
import bpy
# RobotDesigner imports
from ..core import config, PluginManager, RDOperator, logfile
[docs]@PluginManager.register_class
class GenerateAPI(RDOperator):
"""
:ref:`operator` for ...
**Preconditions:**
**Postconditions:**
"""
bl_idname = config.OPERATOR_PREFIX + "generate_api"
bl_label = "Generate Python API"
@RDOperator.OperatorLogger
def execute(self, context):
try:
base_path = os.path.join(config.script_path, "resources/blender_api/bpy/")
self.logger.info("Writing API stubs to: {}".format(base_path))
for op_module_name in dir(bpy.ops):
ops_dir = os.path.join(base_path, "ops")
if not os.path.exists(ops_dir):
os.makedirs(ops_dir)
self.logger.debug("Creating module: {}".format(ops_dir))
with open(os.path.join(ops_dir, op_module_name + ".py"), "w") as f:
op_module = getattr(bpy.ops, op_module_name)
for op_submodule_name in dir(op_module):
op = getattr(op_module, op_submodule_name)
text = repr(op).split("\n")
if text[-1].startswith("bpy.ops."):
f.write(
'def %s:\n """\n %s\n """\n pass\n'
% (
text[-1].replace(
"bpy.ops.%s." % op_module_name, ""
),
text[0].replace("#", ""),
)
)
types = [i for i in getmembers(bpy.types, isclass) if "." not in i[0]]
with open(os.path.join(base_path, "types.py"), "w") as f:
for bpy_type in types:
if bpy_type[0] is not "Operator":
f.write("class %s(object):\n\tpass\n\n" % bpy_type[0])
else:
# Adding overridable methods removes inspection check warnings about unused variables
f.write(
"class %s(object):"
"\n\t@classmethod"
"\n\tdef poll(cls,context): pass"
"\n\tdef invoke(self, context, event): pass"
"\n\tdef execute(self,context): pass \n\n" % bpy_type[0]
)
# Data is just a class with classes
# Context
with open(os.path.join(base_path, "__init__.py"), "w") as f:
f.write("from . import ops, types, props\n\n")
f.write("class context(object):")
for member in [
i[0] for i in getmembers(bpy.context) if "__" not in i[0]
]:
f.write("\n %s = None" % member)
f.write("\n\n")
f.write("class data(object):")
for member in [i[0] for i in getmembers(bpy.data) if "__" not in i[0]]:
f.write("\n %s = None" % member)
f.write("\n\n")
# utils are several modules
# Properties are in one module
with open(base_path + "props.py", "w") as f:
f.write("import sys\n\n")
for prop in [
getattr(bpy.props, i[0])
for i in getmembers(bpy.props)
if "Property" in i[0]
]:
text = prop.__doc__.split("\n")
signature = text[0].replace(".. function:: ", "")
docstring = "\n".join(text[1:])
f.write(
'def %s:\n """%s\n """\n pass\n\n'
% (signature, docstring)
)
return {"FINISHED"}
except:
print(logfile.log_callstack())