Открыть боковую панель
nikitronn
sverchok
Коммиты
c5568211
Коммит
c5568211
создал
Июл 02, 2021
по автору
Ilya Portnov
Просмотр файлов
Knotvector insert / remove testing.
владелец
e7a8a690
Изменения
3
Скрыть пробелы
Построчно
Рядом
tests/nurbs_tests.py
Просмотр файла @
c5568211
...
...
@@ -418,6 +418,76 @@ class OtherNurbsTests(SverchokTestCase):
result
=
inserted
.
evaluate_array
(
ts
)
self
.
assert_numpy_arrays_equal
(
result
,
expected
)
#@unittest.skip
def
test_remove_1
(
self
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
1
,
1
,
0
],
[
2
,
1
,
0
],
[
3
,
0
,
0
]])
degree
=
3
kv
=
np
.
array
([
0
,
0
,
0
,
0
,
1
,
1
,
1
,
1
],
dtype
=
np
.
float64
)
weights
=
[
1
,
1
,
1
,
1
]
curve
=
SvNativeNurbsCurve
(
degree
,
kv
,
points
,
weights
)
kv_err
=
sv_knotvector
.
check
(
degree
,
kv
,
len
(
points
))
if
kv_err
is
not
None
:
raise
Exception
(
kv_err
)
knot
=
0.5
inserted
=
curve
.
insert_knot
(
knot
,
2
)
self
.
assertEquals
(
len
(
inserted
.
get_control_points
()),
len
(
points
)
+
2
)
expected_inserted_kv
=
np
.
array
([
0
,
0
,
0
,
0
,
0.5
,
0.5
,
1
,
1
,
1
,
1
])
inserted_kv
=
inserted
.
get_knotvector
()
self
.
assert_numpy_arrays_equal
(
inserted_kv
,
expected_inserted_kv
)
removed
=
inserted
.
remove_knot
(
knot
,
1
)
expected_removed_kv
=
np
.
array
([
0
,
0
,
0
,
0
,
0.5
,
1
,
1
,
1
,
1
])
self
.
assert_numpy_arrays_equal
(
removed
.
get_knotvector
(),
expected_removed_kv
)
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
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
0
,
1
,
0
],
[
1
,
2
,
0
],
[
2
,
2
,
0
],
[
3
,
1
,
0
],
[
3
,
0
,
0
]],
dtype
=
np
.
float64
)
degree
=
3
kv
=
np
.
array
([
0
,
0
,
0
,
0
,
0.25
,
0.75
,
1
,
1
,
1
,
1
])
weights
=
[
1
,
1
,
1
,
1
,
1
,
1
]
curve
=
SvNativeNurbsCurve
(
degree
,
kv
,
points
,
weights
)
kv_err
=
sv_knotvector
.
check
(
degree
,
kv
,
len
(
points
))
if
kv_err
is
not
None
:
raise
Exception
(
kv_err
)
knot
=
0.1
inserted
=
curve
.
insert_knot
(
knot
,
1
)
self
.
assertEquals
(
len
(
inserted
.
get_control_points
()),
len
(
points
)
+
1
)
expected_inserted_kv
=
np
.
array
([
0
,
0
,
0
,
0
,
0.1
,
0.25
,
0.75
,
1
,
1
,
1
,
1
])
self
.
assert_numpy_arrays_equal
(
inserted
.
get_knotvector
(),
expected_inserted_kv
)
inserted_kv
=
inserted
.
get_knotvector
()
k
=
np
.
searchsorted
(
inserted_kv
,
knot
,
side
=
'right'
)
-
1
s
=
sv_knotvector
.
find_multiplicity
(
inserted_kv
,
knot
)
print
(
"K:"
,
k
,
"S:"
,
s
)
removed
=
inserted
.
remove_knot
(
knot
,
1
)
self
.
assert_numpy_arrays_equal
(
removed
.
get_knotvector
(),
kv
)
#@unittest.skip
def
test_remove_geomdl_1
(
self
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
1
,
1
,
0
],
[
2
,
0
,
0
]])
degree
=
2
kv
=
sv_knotvector
.
generate
(
degree
,
3
)
weights
=
[
1
,
1
,
1
]
curve
=
SvGeomdlCurve
.
build_geomdl
(
degree
,
kv
,
points
,
weights
)
inserted
=
curve
.
insert_knot
(
0.5
,
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
)
removed
=
inserted
.
remove_knot
(
0.5
,
1
)
self
.
assert_numpy_arrays_equal
(
removed
.
get_knotvector
(),
kv
)
def
test_split_1
(
self
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
1
,
0
,
0
]])
kv
=
sv_knotvector
.
generate
(
1
,
2
)
...
...
@@ -518,6 +588,31 @@ class OtherNurbsTests(SverchokTestCase):
expected_pt2
=
curve
.
evaluate
(
0.75
)
self
.
assert_numpy_arrays_equal
(
pt2
,
expected_pt2
,
precision
=
4
)
def
test_split_5
(
self
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
0
,
1
,
0
],
[
1
,
2
,
0
],
[
2
,
2
,
0
],
[
3
,
1
,
0
],
[
3
,
0
,
0
]])
weights
=
[
1
,
1
,
1
,
1
,
1
,
1
]
degree
=
3
knotvector
=
np
.
array
([
0
,
0
,
0
,
0
,
0.25
,
0.75
,
1
,
1
,
1
,
1
])
#print("KV", knotvector)
curve
=
SvNativeNurbsCurve
(
degree
,
knotvector
,
points
,
weights
)
t0
=
knotvector
[
4
]
# 0.25
curve1
,
curve2
=
curve
.
split_at
(
t0
)
expected_kv1
=
np
.
array
([
0
,
0
,
0
,
0
,
0.25
,
0.25
,
0.25
,
0.25
])
expected_kv2
=
np
.
array
([
0.25
,
0.25
,
0.25
,
0.25
,
0.75
,
1
,
1
,
1
,
1
])
self
.
assert_numpy_arrays_equal
(
curve1
.
get_knotvector
(),
expected_kv1
)
self
.
assert_numpy_arrays_equal
(
curve2
.
get_knotvector
(),
expected_kv2
)
result
=
curve1
.
concatenate
(
curve2
,
remove_knots
=
True
)
expected_result_kv
=
knotvector
self
.
assert_numpy_arrays_equal
(
result
.
get_knotvector
(),
expected_result_kv
)
def
test_single_1
(
self
):
points
=
np
.
array
([[
0
,
0
,
0
],
[
1
,
1
,
0
],
[
2
,
0
,
0
]])
kv
=
sv_knotvector
.
generate
(
2
,
3
)
...
...
utils/curve/knotvector.py
Просмотр файла @
c5568211
...
...
@@ -68,6 +68,13 @@ def generate(degree, num_ctrlpts, clamped=True):
# Return auto-generated knot vector
return
np
.
array
(
knot_vector
)
def
find_span
(
knot_vector
,
num_ctrlpts
,
knot
):
span
=
0
# Knot span index starts from zero
while
span
<
num_ctrlpts
and
knot_vector
[
span
]
<=
knot
:
span
+=
1
return
span
-
1
def
from_tknots
(
degree
,
tknots
):
n
=
len
(
tknots
)
#m = degree + n + 1
...
...
utils/curve/nurbs.py
Просмотр файла @
c5568211
...
...
@@ -126,7 +126,7 @@ class SvNurbsCurve(SvCurve):
def
get_bounding_box
(
self
):
return
bounding_box
(
self
.
get_control_points
())
def
concatenate
(
self
,
curve2
,
tolerance
=
1e-6
):
def
concatenate
(
self
,
curve2
,
tolerance
=
1e-6
,
remove_knots
=
False
):
curve1
=
self
curve2
=
SvNurbsCurve
.
to_nurbs
(
curve2
)
if
curve2
is
None
:
...
...
@@ -177,8 +177,12 @@ class SvNurbsCurve(SvCurve):
weights
=
np
.
concatenate
((
curve1
.
get_weights
(),
curve2
.
get_weights
()[
1
:]))
control_points
=
np
.
concatenate
((
curve1
.
get_control_points
(),
curve2
.
get_control_points
()[
1
:]))
re
turn
SvNurbsCurve
.
build
(
self
.
get_nurbs_implementation
(),
re
sult
=
SvNurbsCurve
.
build
(
self
.
get_nurbs_implementation
(),
p
,
knotvector
,
control_points
,
weights
)
if
remove_knots
:
join_point
=
kv1
[
-
1
]
result
=
result
.
remove_knot
(
join_point
,
p
-
1
)
return
result
def
lerp_to
(
self
,
curve2
,
coefficient
):
curve1
=
self
...
...
@@ -684,11 +688,13 @@ class SvGeomdlCurve(SvNurbsCurve):
return
surface
def
insert_knot
(
self
,
u
,
count
=
1
):
curve
=
operations
.
insert_knot
(
self
.
curve
,
[
u
],
[
count
])
curve
=
self
.
copy
()
curve
=
operations
.
insert_knot
(
curve
.
curve
,
[
u
],
[
count
])
return
SvGeomdlCurve
(
curve
)
def
remove_knot
(
self
,
u
,
count
=
1
):
curve
=
operations
.
remove_knot
(
self
.
curve
,
[
u
],
[
count
])
curve
=
self
.
copy
()
curve
=
operations
.
remove_knot
(
curve
.
curve
,
[
u
],
[
count
])
return
SvGeomdlCurve
(
curve
)
class
SvNativeNurbsCurve
(
SvNurbsCurve
):
...
...
@@ -859,13 +865,14 @@ class SvNativeNurbsCurve(SvNurbsCurve):
def
insert_knot
(
self
,
u_bar
,
count
=
1
):
# "The NURBS book", 2nd edition, p.5.2, eq. 5.11
s
=
sv_knotvector
.
find_multiplicity
(
self
.
knotvector
,
u_bar
)
N
=
len
(
self
.
control_points
)
s
=
sv_knotvector
.
find_multiplicity
(
self
.
get_knotvector
(),
u_bar
)
#print(f"I: kv {len(self.knotvector)}{self.knotvector}, u_bar {u_bar} => s {s}")
k
=
np
.
searchsorted
(
self
.
knotvector
,
u_bar
,
side
=
'right'
)
-
1
#k = np.searchsorted(self.knotvector, u_bar, side='right')-1
k
=
sv_knotvector
.
find_span
(
self
.
knotvector
,
N
,
u_bar
)
p
=
self
.
degree
u
=
self
.
knotvector
new_knotvector
=
sv_knotvector
.
insert
(
self
.
knotvector
,
u_bar
,
count
)
N
=
len
(
self
.
control_points
)
control_points
=
self
.
get_homogenous_control_points
()
for
r
in
range
(
1
,
count
+
1
):
...
...
@@ -907,9 +914,11 @@ class SvNativeNurbsCurve(SvNurbsCurve):
degree
=
self
.
get_degree
()
knotvector
=
self
.
get_knotvector
()
ctrlpts
=
self
.
get_homogenous_control_points
().
tolist
()
N
=
len
(
ctrlpts
)
s
=
sv_knotvector
.
find_multiplicity
(
knotvector
,
u
)
-
1
# multiplicity
r
=
knotvector
.
searchsorted
(
u
,
side
=
'right'
)
-
1
# knot span
s
=
sv_knotvector
.
find_multiplicity
(
knotvector
,
u
)
#-1 # multiplicity
#r = knotvector.searchsorted(u, side='right')- 1 # knot span
r
=
sv_knotvector
.
find_span
(
self
.
knotvector
,
N
,
u
)
# Edge case
if
count
<
1
:
...
...
@@ -927,6 +936,7 @@ class SvNativeNurbsCurve(SvNurbsCurve):
# Loop for Eqs 5.28 & 5.29
for
t
in
range
(
0
,
count
):
#print(f"T: {t} / {count}, first = {first}, last = {last}; N = {len(ctrlpts)}, degree = {degree}, r = {r}, s = {s}")
temp
[
0
]
=
ctrlpts
[
first
-
1
]
temp
[
last
-
first
+
2
]
=
ctrlpts
[
last
+
1
]
i
=
first
...
...
@@ -967,6 +977,9 @@ class SvNativeNurbsCurve(SvNurbsCurve):
ctrlpts_new
[
j
]
=
temp
[
j
-
first
+
1
]
i
+=
1
j
-=
1
else
:
break
#raise Exception(f"Knot {u} can not be removed {count} times")
# Update indices
first
-=
1
...
...
@@ -993,7 +1006,9 @@ class SvNativeNurbsCurve(SvNurbsCurve):
ctrlpts_new
=
np
.
array
(
ctrlpts_new
)
control_points
,
weights
=
from_homogenous
(
ctrlpts_new
)
new_kv
=
np
.
delete
(
self
.
get_knotvector
(),
np
.
s_
[(
r
-
count
):(
r
)])
new_kv
=
np
.
delete
(
self
.
get_knotvector
(),
np
.
s_
[(
r
-
t
+
1
):(
r
+
1
)])
#print(f"R: r = {r}, t = {t}, N ctrlpts {len(ctrlpts_new)}")
#print(f" {self.get_knotvector()} => {new_kv}")
return
self
.
copy
(
knotvector
=
new_kv
,
control_points
=
control_points
,
weights
=
weights
)
...
...
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать