Коммит ccce1b28 создал по автору Ilya Portnov's avatar Ilya Portnov
Просмотр файлов

Minor changes.

владелец e30503bb
...@@ -424,25 +424,25 @@ class OtherNurbsTests(SverchokTestCase): ...@@ -424,25 +424,25 @@ class OtherNurbsTests(SverchokTestCase):
degree = 3 degree = 3
kv = np.array([0, 0, 0, 0, 1, 1, 1, 1], dtype=np.float64) kv = np.array([0, 0, 0, 0, 1, 1, 1, 1], dtype=np.float64)
weights = [1, 1, 1, 1] weights = [1, 1, 1, 1]
ts = np.linspace(0.0, 1.0, num=5)
curve = SvNativeNurbsCurve(degree, kv, points, weights) curve = SvNativeNurbsCurve(degree, kv, points, weights)
orig_pts = curve.evaluate_array(ts)
kv_err = sv_knotvector.check(degree, kv, len(points)) kv_err = sv_knotvector.check(degree, kv, len(points))
if kv_err is not None: if kv_err is not None:
raise Exception(kv_err) raise Exception(kv_err)
knot = 0.5 knot = 0.5
inserted = curve.insert_knot(knot, 2) inserted = curve.insert_knot(knot, 2)
self.assertEquals(len(inserted.get_control_points()), len(points)+2) self.assertEquals(len(inserted.get_control_points()), len(points)+2)
self.assert_numpy_arrays_equal(inserted.evaluate_array(ts), orig_pts)
expected_inserted_kv = np.array([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1]) expected_inserted_kv = np.array([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1])
inserted_kv = inserted.get_knotvector() inserted_kv = inserted.get_knotvector()
self.assert_numpy_arrays_equal(inserted_kv, expected_inserted_kv) self.assert_numpy_arrays_equal(inserted_kv, expected_inserted_kv)
removed = inserted.remove_knot(knot, 1) removed = inserted.remove_knot(knot, 2)
expected_removed_kv = np.array([0, 0, 0, 0, 0.5, 1, 1, 1, 1]) expected_removed_kv = kv
self.assert_numpy_arrays_equal(removed.get_knotvector(), expected_removed_kv) self.assert_numpy_arrays_equal(removed.get_knotvector(), expected_removed_kv)
self.assert_numpy_arrays_equal(removed.evaluate_array(ts), orig_pts)
removed2 = removed.remove_knot(knot, 1)
expected_removed_kv = np.array([0, 0, 0, 0, 1, 1, 1, 1])
self.assert_numpy_arrays_equal(removed2.get_knotvector(), expected_removed_kv)
def test_remove_2(self): def test_remove_2(self):
points = np.array([[0, 0, 0], points = np.array([[0, 0, 0],
...@@ -479,14 +479,24 @@ class OtherNurbsTests(SverchokTestCase): ...@@ -479,14 +479,24 @@ class OtherNurbsTests(SverchokTestCase):
degree = 2 degree = 2
kv = sv_knotvector.generate(degree,3) kv = sv_knotvector.generate(degree,3)
weights = [1, 1, 1] weights = [1, 1, 1]
ts = np.linspace(0.0, 1.0, num=5)
curve = SvGeomdlCurve.build_geomdl(degree, kv, points, weights) curve = SvGeomdlCurve.build_geomdl(degree, kv, points, weights)
orig_pts = curve.evaluate_array(ts)
inserted = curve.insert_knot(0.5, 1) inserted = curve.insert_knot(0.5, 1)
self.assert_numpy_arrays_equal(inserted.evaluate_array(ts), orig_pts)
expected_inserted_kv = np.array([0, 0, 0, 0.5, 1, 1, 1]) expected_inserted_kv = np.array([0, 0, 0, 0.5, 1, 1, 1])
self.assert_numpy_arrays_equal(inserted.get_knotvector(), expected_inserted_kv) self.assert_numpy_arrays_equal(inserted.get_knotvector(), expected_inserted_kv)
removed = inserted.remove_knot(0.5, 1) removed = inserted.remove_knot(0.5, 1)
self.assert_numpy_arrays_equal(removed.get_knotvector(), kv) self.assert_numpy_arrays_equal(removed.get_knotvector(), kv)
#self.assert_numpy_arrays_equal(removed.evaluate_array(ts), orig_pts)
print("CP", removed.get_control_points())
print("W", removed.get_weights())
#self.assert_numpy_arrays_equal(removed.get_control_points(), points)
def test_split_1(self): def test_split_1(self):
points = np.array([[0, 0, 0], [1, 0, 0]]) points = np.array([[0, 0, 0], [1, 0, 0]])
......
...@@ -329,6 +329,20 @@ class SvFreeCadNurbsCurve(SvNurbsCurve): ...@@ -329,6 +329,20 @@ class SvFreeCadNurbsCurve(SvNurbsCurve):
curve.curve.insertKnot(u, count) curve.curve.insertKnot(u, count)
return curve return curve
def remove_knot(self, u, count=1, tolerance=1e-4):
curve = SvFreeCadNurbsCurve(self.curve.copy(), self.ndim) # copy
ms = sv_knotvector.to_multiplicity(self.get_knotvector())
idx = None
M = None
for i, (u1, m) in enumerate(ms):
if u1 == u:
idx = i
M = m - count
break
if idx is not None:
curve.curve.removeKnot(idx+1, M, tolerance)
return curve
SvNurbsMaths.curve_classes[SvNurbsMaths.FREECAD] = SvFreeCadNurbsCurve SvNurbsMaths.curve_classes[SvNurbsMaths.FREECAD] = SvFreeCadNurbsCurve
def curve_to_freecad(sv_curve): def curve_to_freecad(sv_curve):
......
...@@ -188,8 +188,12 @@ def find_multiplicity(knot_vector, u, tolerance=1e-6): ...@@ -188,8 +188,12 @@ def find_multiplicity(knot_vector, u, tolerance=1e-6):
pairs = to_multiplicity(knot_vector, tolerance) pairs = to_multiplicity(knot_vector, tolerance)
#print(f"kv {knot_vector} => {pairs}") #print(f"kv {knot_vector} => {pairs}")
for k, count in pairs: for k, count in pairs:
if abs(k - u) < tolerance: if tolerance is None:
return count if k == u:
return count
else:
if abs(k - u) < tolerance:
return count
return 0 return 0
def get_internal_knots(knot_vector, output_multiplicity = False, tolerance=1e-6): def get_internal_knots(knot_vector, output_multiplicity = False, tolerance=1e-6):
......
...@@ -304,8 +304,10 @@ class SvNurbsCurve(SvCurve): ...@@ -304,8 +304,10 @@ class SvNurbsCurve(SvCurve):
p = self.get_degree() p = self.get_degree()
return p+1 == k return p+1 == k
def is_rational(self): def is_rational(self, tolerance=1e-6):
raise Exception("Not implemented!") weights = self.get_weights()
w, W = weights.min(), weights.max()
return (W - w) > tolerance
def get_knotvector(self): def get_knotvector(self):
""" """
...@@ -919,8 +921,8 @@ class SvNativeNurbsCurve(SvNurbsCurve): ...@@ -919,8 +921,8 @@ class SvNativeNurbsCurve(SvNurbsCurve):
N = len(ctrlpts) N = len(ctrlpts)
s = sv_knotvector.find_multiplicity(knotvector, u)#-1 # multiplicity s = sv_knotvector.find_multiplicity(knotvector, u)#-1 # multiplicity
#r = knotvector.searchsorted(u, side='right')- 1 # knot span r = knotvector.searchsorted(u, side='right')- 1 # knot span
r = sv_knotvector.find_span(self.knotvector, N, u) #r = sv_knotvector.find_span(self.knotvector, N, u)
# Edge case # Edge case
if count < 1: if count < 1:
......
...@@ -302,6 +302,35 @@ class SvFreeCadNurbsSurface(SvNurbsSurface): ...@@ -302,6 +302,35 @@ class SvFreeCadNurbsSurface(SvNurbsSurface):
return SvFreeCadNurbsCurve(fc_curve) return SvFreeCadNurbsCurve(fc_curve)
def insert_knot(self, direction, parameter, count=1):
surface = SvFreeCadNurbsSurface(self.surface.copy())
tolerance = 1e-6
if direction == 'U':
surface.surface.insertUKnot(parameter, count, tolerance)
else:
surface.surface.insertVKnot(parameter, count, tolerance)
return surface
def remove_knot(self, direction, parameter, count=1, tolerance=1e-4):
surface = SvFreeCadNurbsSurface(self.surface.copy())
if direction == 'U':
ms = sv_knotvector.to_multiplicity(self.get_knotvector_u())
else:
ms = sv_knotvector.to_multiplicity(self.get_knotvector_v())
idx = None
M = None
for i, (u1, m) in enumerate(ms):
if u1 == parameter:
idx = i
M = m - count
break
if idx is not None:
if direction == 'U':
surface.surface.removeUKnot(idx+1, M, tolerance)
else:
surface.surface.removeVKnot(idx+1, M, tolerance)
return surface
# def to_nurbs(self, **kwargs): # def to_nurbs(self, **kwargs):
# return self # return self
......
...@@ -31,6 +31,17 @@ def reparametrize_by_segments(curve, t_values): ...@@ -31,6 +31,17 @@ def reparametrize_by_segments(curve, t_values):
return result return result
def find_knot_multiplicities(curve, knots, tolerance=None):
return [(knot, sv_knotvector.find_multiplicity(curve.get_knotvector(), knot)) for knot in knots]
def sum_multiplicities(multiplicities):
#print(multiplicities)
result = defaultdict(int)
for ms in multiplicities:
for u, count in ms:
result[u] = max(result[u], count)
return result.items()
def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=None, v_knots=None, knotvector_accuracy=6): def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=None, v_knots=None, knotvector_accuracy=6):
if (u_knots is None) != (v_knots is None): if (u_knots is None) != (v_knots is None):
...@@ -42,6 +53,7 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N ...@@ -42,6 +53,7 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N
raise Exception("Some of V-curves are rational. Rational curves are not supported for Gordon surface.") raise Exception("Some of V-curves are rational. Rational curves are not supported for Gordon surface.")
intersections = np.array(intersections) intersections = np.array(intersections)
knotvector_tolerance = 10**(-knotvector_accuracy)
if u_knots is not None: if u_knots is not None:
loft_u_kwargs = loft_v_kwargs = interpolate_kwargs = {'metric': 'POINTS'} loft_u_kwargs = loft_v_kwargs = interpolate_kwargs = {'metric': 'POINTS'}
...@@ -50,8 +62,17 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N ...@@ -50,8 +62,17 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N
v_curves = [reparametrize_by_segments(c, knots) for c, knots in zip(v_curves, v_knots)] v_curves = [reparametrize_by_segments(c, knots) for c, knots in zip(v_curves, v_knots)]
#print("U", u_curves) #print("U", u_curves)
#print("V", v_curves) #print("V", v_curves)
target_u_knots = np.linspace(0.0, 1.0, num = len(v_curves))
target_v_knots = np.linspace(0.0, 1.0, num = len(u_curves))
orig_ints_ms_u = sum_multiplicities([find_knot_multiplicities(c, knots) for c, knots in zip(u_curves, u_knots)])
orig_ints_ms_v = sum_multiplicities([find_knot_multiplicities(c, knots) for c, knots in zip(v_curves, v_knots)])
else: else:
loft_u_kwargs = loft_v_kwargs = interpolate_kwargs = {'metric': metric} loft_u_kwargs = loft_v_kwargs = interpolate_kwargs = {'metric': metric}
orig_ints_ms_u = None
orig_ints_ms_v = None
#u_curves = unify_curves_degree(u_curves) #u_curves = unify_curves_degree(u_curves)
#u_curves = unify_curves(u_curves, accuracy=knotvector_accuracy)#, method='AVERAGE') #u_curves = unify_curves(u_curves, accuracy=knotvector_accuracy)#, method='AVERAGE')
...@@ -92,5 +113,27 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N ...@@ -92,5 +113,27 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N
control_points, weights=None) control_points, weights=None)
#print(f"Result: {surface}") #print(f"Result: {surface}")
# if orig_ints_ms_u is not None:
# print("KV.U", surface.get_knotvector_u())
# ms_u = dict(sv_knotvector.to_multiplicity(surface.get_knotvector_u()))
# for (u, orig_count), target_u in zip(orig_ints_ms_u, target_u_knots):
# current_count = ms_u.get(target_u, 0)
# diff = current_count - orig_count - 1
# print(f"R: U = {u} => {target_u}, orig = {orig_count}, now = {current_count}")
# if diff > 0:
# print(f"R: remove U = {target_v} x {diff}")
# surface = surface.remove_knot(SvNurbsSurface.U, target_u, diff)
#
# if orig_ints_ms_v is not None:
# print("KV.V", surface.get_knotvector_v())
# ms_v = dict(sv_knotvector.to_multiplicity(surface.get_knotvector_v()))
# for (v, orig_count), target_v in zip(orig_ints_ms_v, target_v_knots):
# current_count = ms_v.get(target_v, 0)
# diff = current_count - orig_count - 1
# print(f"R: V = {v} => {target_v}, orig = {orig_count}, now = {current_count}")
# if diff > 0:
# print(f"R: remove V = {target_v} x {diff}")
# surface = surface.remove_knot(SvNurbsSurface.V, target_v, diff)
return lofted_u, lofted_v, interpolated, surface return lofted_u, lofted_v, interpolated, surface
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать