diff --git a/utils/__init__.py b/utils/__init__.py index 4d733b405446e7587204b81beb2d0b672baffdfd..cc39c537cd0fe0e02923e1aabd5a7fc22add2335 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -128,7 +128,7 @@ utils_modules = [ "snlite_utils", "snlite_importhelper", "context_managers", "sv_node_utils", "sv_noise_utils", "profile", "logging", "testing", "sv_requests", "sv_shader_sources", "tree_structure", "avl_tree", "sv_nodeview_draw_helper", "sv_font_xml_parser", "modules.edge_utils", "modules.polygon_utils", - "wfc_algorithm", "handle_blender_data", "nodes_mixins.generating_objects", + "wfc_algorithm", "handle_blender_data", "nodes_mixins.generating_objects", "decorators_compilation", "nodes_mixins.show_3d_properties", "modules_inspection", "sv_json_export", "sv_json_import", "meshes", "tree_walk", "mesh_functions", 'mesh.inset_faces', 'mesh.extrude_edges', "sv_json_struct", "nodeview_time_graph_drawing", "modules.shader_utils", "dummy_nodes", diff --git a/utils/decorators_compilation.py b/utils/decorators_compilation.py new file mode 100644 index 0000000000000000000000000000000000000000..a5dba67043ceab175e0ffc071cc68dd97a4683a6 --- /dev/null +++ b/utils/decorators_compilation.py @@ -0,0 +1,31 @@ +# This file is part of project Sverchok. It's copyrighted by the contributors +# recorded in the version control history of the file, available from +# its original location https://github.com/nortikin/sverchok/commit/master +# +# SPDX-License-Identifier: GPL3 +# License-Filename: LICENSE + +from sverchok.dependencies import numba + + +local_numba_storage = {} + +# # further reading +# # https://stackoverflow.com/a/54024922/1243487 + +def njit(**kwargs): + if numba: + + def wrapper(function_to_compile): + function_name = function_to_compile.__name__ + if function_name not in local_numba_storage: + jitted_func = numba.njit(**kwargs)(function_to_compile) + local_numba_storage[function_name] = jitted_func + return local_numba_storage[function_name] + + else: + + def wrapper(function_to_compile): + return function_to_compile + + return wrapper diff --git a/utils/geom.py b/utils/geom.py index a97f3673134ffbbd76e936d4627b5e3ee274319c..1b8c22d30697d74fe652d75540903105219cb456 100644 --- a/utils/geom.py +++ b/utils/geom.py @@ -47,6 +47,11 @@ from sverchok.data_structure import match_long_repeat, describe_data_shape from sverchok.utils.math import np_mixed_product from sverchok.utils.logging import debug, info +# njit is a light-wrapper aroudn numba.njit, if found +from sverchok.dependencies import numba # not strictly needed i think... +from sverchok.utils.decorators_compilation import njit + + identity_matrix = Matrix() # constants @@ -203,6 +208,7 @@ class CubicSpline(Spline): super().__init__() + if is_cyclic: #print(describe_data_shape(vertices)) @@ -210,7 +216,7 @@ class CubicSpline(Spline): va, vb, vc = vertices[0], vertices[1], vertices[2] locs = np.array([vc, va, vb, vc, va, vb, vc, va, vb, vc, va]) else: - locs = np.array(vertices[-4:] + vertices + vertices[:4]) + locs = np.concatenate((vertices[-4:], vertices, vertices[:4]), axis=0) if tknots is None: if metric is None: @@ -233,44 +239,54 @@ class CubicSpline(Spline): n = len(locs) if n < 2: - raise Exception("Cubic spline can't be build from less than 3 vertices") - - # a = locs - h = tknots[1:] - tknots[:-1] - h[h == 0] = 1e-8 - q = np.zeros((n - 1, 3)) - q[1:] = 3 / h[1:, np.newaxis] * (locs[2:] - locs[1:-1]) - 3 / \ - h[:-1, np.newaxis] * (locs[1:-1] - locs[:-2]) - - l = np.zeros((n, 3)) - l[0, :] = 1.0 - u = np.zeros((n - 1, 3)) - z = np.zeros((n, 3)) - - for i in range(1, n - 1): - l[i] = 2 * (tknots[i + 1] - tknots[i - 1]) - h[i - 1] * u[i - 1] - l[i, l[i] == 0] = 1e-8 - u[i] = h[i] / l[i] - z[i] = (q[i] - h[i - 1] * z[i - 1]) / l[i] - l[-1, :] = 1.0 - z[-1] = 0.0 - - b = np.zeros((n - 1, 3)) - c = np.zeros((n, 3)) - - for i in range(n - 2, -1, -1): - c[i] = z[i] - u[i] * c[i + 1] - b = (locs[1:] - locs[:-1]) / h[:, np.newaxis] - h[:, np.newaxis] * (c[1:] + 2 * c[:-1]) / 3 - d = (c[1:] - c[:-1]) / (3 * h[:, np.newaxis]) - - splines = np.zeros((n - 1, 5, 3)) - splines[:, 0] = locs[:-1] - splines[:, 1] = b - splines[:, 2] = c[:-1] - splines[:, 3] = d - splines[:, 4] = tknots[:-1, np.newaxis] + raise Exception("Cubic spline can't be built from less than 3 vertices") + + @njit(cache=True) + def calc_cubic_splines(tknots, n, locs): + """ + returns splines + """ + h = tknots[1:] - tknots[:-1] + h[h == 0] = 1e-8 + + delta_i = (locs[2:] - locs[1:-1]) + delta_j = (locs[1:-1] - locs[:-2]) + nn = (3 / h[1:].reshape((-1, 1)) * delta_i) - (3 / h[:-1].reshape((-1, 1)) * delta_j) + q = np.vstack((np.array([[0.0, 0.0, 0.0]]), nn)) + l = np.zeros((n, 3)) + l[0, :] = 1.0 + u = np.zeros((n - 1, 3)) + z = np.zeros((n, 3)) + + for i in range(1, n - 1): + l[i] = 2 * (tknots[i + 1] - tknots[i - 1]) - h[i - 1] * u[i - 1] + for idx in range(len(l[i])): # range(l[i].shape[0]): + if l[i][idx] == 0: + l[i][idx] = 1e-8 + u[i] = h[i] / l[i] + z[i] = (q[i] - h[i - 1] * z[i - 1]) / l[i] + + l[-1, :] = 1.0 + z[-1] = 0.0 + + b = np.zeros((n - 1, 3)) + c = np.zeros((n, 3)) + for i in range(n - 2, -1, -1): + c[i] = z[i] - u[i] * c[i + 1] + + h_flat = h.reshape((-1, 1)) + b = (locs[1:] - locs[:-1]) / h_flat - h_flat * (c[1:] + 2 * c[:-1]) / 3 + d = (c[1:] - c[:-1]) / (3 * h_flat) + + splines = np.zeros((n - 1, 5, 3)) + splines[:, 0] = locs[:-1] + splines[:, 1] = b + splines[:, 2] = c[:-1] + splines[:, 3] = d + splines[:, 4] = tknots[:-1].reshape((-1, 1)) + return splines - self.splines = splines + self.splines = calc_cubic_splines(tknots, n, locs) def eval(self, t_in, tknots = None): """