Created
October 19, 2025 15:59
-
-
Save portnov/63284532fe0d7e8d22344781a987c897 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| in curve_in C | |
| out curve_out C | |
| """ | |
| from math import sqrt, exp | |
| import numpy as np | |
| from sverchok.data_structure import zip_long_repeat, ensure_nesting_level, repeat_last_for_length | |
| from sverchok.utils.curve.core import SvCurve, UnsupportedCurveTypeException | |
| from sverchok.utils.curve.nurbs import SvNurbsCurve | |
| from sverchok.utils.curve.bezier import SvCubicBezierCurve | |
| from sverchok.utils.curve.nurbs_algorithms import concatenate_nurbs_curves | |
| from sverchok.dependencies import scipy | |
| from scipy.optimize import fsolve | |
| def process_segment(segment, c1, c2): | |
| #print(f"Fit to {c1}, {c2}") | |
| A, B, C, D = segment.get_control_points() | |
| v1 = B - A | |
| v13 = np.linalg.norm(v1)**3 | |
| v2 = D - C | |
| v23 = np.linalg.norm(v2)**3 | |
| def equations(p): | |
| X, Y = p | |
| x, y = exp(X), exp(Y) | |
| #x, y = p | |
| C_star = D - y*v2 | |
| B_star = A + x*v1 | |
| eq1 = 2 * np.linalg.norm(np.cross(v1, C_star - A)) / (x*x * v13) - 3*c1 | |
| eq2 = 2 * np.linalg.norm(np.cross(v2, B_star - D)) / (y*y * v23) - 3*c2 | |
| return (eq1, eq2) | |
| initial_guess = [0, 0] | |
| ps = fsolve(equations, initial_guess) | |
| #print(solution) | |
| #ps, info, ier, mesg = solution | |
| X, Y = ps | |
| x, y = exp(X), exp(Y) | |
| #x,y = ps | |
| #print(f"Sol: {x}, {y}") | |
| B_star = A + x*v1 | |
| C_star = D - y*v2 | |
| result = SvCubicBezierCurve(A, B_star, C_star, D) | |
| #k1 = result.curvature(0) | |
| #k2 = result.curvature(1) | |
| #print("Res", k1, k2) | |
| return result | |
| def process(curve): | |
| p = curve.get_degree() | |
| if p != 3: | |
| raise UnsupportedCurveTypeException("Only degree 3 curves are supported for now") | |
| segments = curve.to_bezier_segments() | |
| start_curvatures = [] | |
| end_curvatures = [] | |
| for segment in segments: | |
| c1 = segment.curvature(0) | |
| c2 = segment.curvature(1) | |
| #print("Src", c1, c2) | |
| start_curvatures.append(c1) | |
| end_curvatures.append(c2) | |
| target_curvatures = [start_curvatures[0]] | |
| for c1, c2 in zip(end_curvatures[:-1], start_curvatures[1:]): | |
| c = sqrt(c1*c2) | |
| target_curvatures.append(c) | |
| target_curvatures.append(end_curvatures[-1]) | |
| #print("Target", target_curvatures) | |
| result = [] | |
| for segment, c1, c2 in zip(segments, target_curvatures[:-1], target_curvatures[1:]): | |
| segment = process_segment(segment, c1, c2) | |
| result.append(segment) | |
| return concatenate_nurbs_curves(result) | |
| curve_in = ensure_nesting_level(curve_in, 1, data_types=(SvCurve,)) | |
| curve_out = [] | |
| for curve in curve_in: | |
| curve = SvNurbsCurve.to_nurbs(curve) | |
| if curve is None: | |
| raise UnsupportedCurveTypeException("One of curve is not NURBS") | |
| curve = process(curve) | |
| curve_out.append(curve) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment