Expand source code
# ##### 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 #####
import inspect
from math import *
import numpy as np
import bpy
from mathutils import Vector, Matrix
from sverchok.utils.sv_script import SvScript
from sverchok.utils.math import sign
def load_script(source, file_name):
from_file = '<{}>'.format(file_name)
code = compile(source, from_file, 'exec', optimize=0)
# insert classes that we can inherit from
local_space = {cls.__name__:cls for cls in SvScript.__subclasses__()}
base_classes = set(cls.__name__ for cls in SvScript.__subclasses__())
local_space["SvScript"] = SvScript
exec(code, globals(),local_space)
script = None
for name in code.co_names:
# filter out inherited
if not name in local_space:
continue
# skip base classes
if name in base_classes:
continue
try:
script_class = local_space.get(name)
if inspect.isclass(script_class):
script = script_class()
if isinstance(script, SvScript):
print("Script Node found script {}".format(name))
script = script
globals().update(local_space)
except Exception as Err:
print("Script Node couldn't load {0}".format(name))
print(Err)
if not script:
raise ImportWarning("Couldn't find script in {}".format(name))
return script
def make_functions_dict(*functions):
return dict([(function.__name__, function) for function in functions])
# Functions
safe_names = make_functions_dict(
# From math module
acos, acosh, asin, asinh, atan, atan2,
atanh, ceil, copysign, cos, cosh, degrees,
erf, erfc, exp, expm1, fabs, factorial, floor,
fmod, frexp, fsum, gamma, hypot, isfinite, isinf,
isnan, ldexp, lgamma, log, log10, log1p, log2, modf,
pow, radians, sin, sinh, sqrt, tan, tanh, trunc,
# Additional functions
abs, sign, max, min, len, sum, zip,
# From mathutlis module
Vector, Matrix,
# Python type conversions
tuple, list, str, dict, set, int, float,
any, all, dir
)
# Constants
safe_names['e'] = e
safe_names['pi'] = pi
safe_names['np'] = np
# Blender modules
# Consider this not safe for now
safe_names["bpy"] = bpy
def _add_numpy_exact(r, names):
for name in names:
r[name] = getattr(np, name)
safe_names_np = safe_names.copy()
_add_numpy_exact(safe_names_np, [
'ceil', 'copysign', 'cos', 'sin',
'cosh', 'sinh', 'degrees', 'radians',
'exp', 'expm1', 'fabs', 'floor', 'fmod',
'frexp', 'hypot', 'isfinite', 'isinf',
'isnan', 'ldexp', 'log', 'log10', 'log1p', 'log2',
'modf', 'sqrt', 'tan', 'tanh', 'trunc'
])
def _numpy_wrapper(f):
return lambda a: np.array([f(x) for x in a])
def np_pow(x, p, mod=None):
if mod is None:
return x ** p
else:
return (x ** p) % mod
safe_names_np.update({
'acos': np.arccos,
'acosh': np.arccosh,
'asin': np.arcsin,
'asinh': np.arcsinh,
'atan2': np.arctan2,
'atanh': np.arctanh,
'pow': np_pow,
'erf': _numpy_wrapper(erf),
'erfc': _numpy_wrapper(erfc),
'gamma': _numpy_wrapper(gamma),
'lgamma': _numpy_wrapper(lgamma),
'factorial': _numpy_wrapper(factorial)
})