Открыть боковую панель
nikitronn
sverchok
Коммиты
5e8e9481
Коммит
5e8e9481
создал
Сен 13, 2021
по автору
Ilya Portnov
Просмотр файлов
Extend curve - technical refactoring.
владелец
76ce02de
Изменения
2
Скрыть пробелы
Построчно
Рядом
nodes/curve/extend_curve.py
Просмотр файла @
5e8e9481
...
...
@@ -9,6 +9,7 @@ from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_
from
sverchok.utils.curve
import
SvCurve
,
SvTaylorCurve
,
SvLine
,
SvCircle
,
SvCurveLengthSolver
from
sverchok.utils.curve.algorithms
import
concatenate_curves
,
reverse_curve
from
sverchok.utils.curve.nurbs
import
SvNurbsCurve
from
sverchok.utils.curve.extend
import
extend_curve
from
sverchok.utils.geom
import
circle_by_two_derivatives
class
SvExtendCurveNode
(
bpy
.
types
.
Node
,
SverchCustomTreeNode
):
...
...
@@ -81,139 +82,6 @@ class SvExtendCurveNode(bpy.types.Node, SverchCustomTreeNode):
if
self
.
len_mode
==
'L'
:
layout
.
prop
(
self
,
'len_resolution'
)
def
make_line
(
self
,
point
,
tangent
,
t_ext
,
sign
):
if
sign
<
0
:
before_start
=
point
-
t_ext
*
tangent
# / np.linalg.norm(tangent_start)
return
SvLine
.
from_two_points
(
before_start
,
point
)
else
:
after_end
=
point
+
t_ext
*
tangent
# / np.linalg.norm(tangent_end)
return
SvLine
.
from_two_points
(
point
,
after_end
)
def
set_length
(
self
,
base_curve
,
curve
,
t_ext
,
sign
=
1
):
if
curve
is
None
:
return
None
if
self
.
len_mode
==
'T'
:
curve
.
u_bounds
=
(
0
,
t_ext
)
if
isinstance
(
curve
,
SvLine
)
and
sign
<
0
:
unit
=
curve
.
direction
/
np
.
linalg
.
norm
(
curve
.
direction
)
t_target
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
start
=
curve
.
point
+
curve
.
direction
-
t_ext
*
unit
curve
.
point
=
start
curve
.
u_bounds
=
(
0
,
t_target
)
elif
self
.
len_mode
==
'L'
:
if
isinstance
(
curve
,
SvLine
):
if
sign
>
0
:
curve
.
direction
=
curve
.
direction
t_ext
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
curve
.
u_bounds
=
(
0
,
t_ext
)
else
:
unit
=
curve
.
direction
/
np
.
linalg
.
norm
(
curve
.
direction
)
t_target
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
start
=
curve
.
point
+
curve
.
direction
-
t_ext
*
unit
curve
.
point
=
start
curve
.
u_bounds
=
(
0
,
t_target
)
else
:
u_min
,
u_max
=
base_curve
.
get_u_bounds
()
base_length
=
base_curve
.
calc_length
(
u_min
,
u_max
,
self
.
len_resolution
)
# base_length / (u_max - u_min) ~= t_ext / (t_target - 0)
t_mid
=
t_ext
*
(
u_max
-
u_min
)
/
base_length
#self.debug(f"Base curve len: {base_length}, range: {u_max - u_min}, T_ext {t_ext} => T_mid {t_mid}")
curve
.
u_bounds
=
(
0
,
t_mid
)
solver
=
SvCurveLengthSolver
(
curve
)
solver
.
prepare
(
'SPL'
,
self
.
len_resolution
)
t_target
=
solver
.
solve
(
np
.
array
([
t_ext
]))[
0
]
#self.debug(f"C: {type(curve)}: L = {t_mid} => T = {t_target}")
curve
.
u_bounds
=
(
0
,
t_target
)
return
curve
def
extend_curve
(
self
,
curve
,
t_before
,
t_after
):
u_min
,
u_max
=
curve
.
get_u_bounds
()
start
,
end
=
curve
.
evaluate
(
u_min
),
curve
.
evaluate
(
u_max
)
start_extent
,
end_extent
=
None
,
None
is_nurbs
=
isinstance
(
curve
,
SvNurbsCurve
)
if
self
.
mode
==
'LINE'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
if
t_before
>
0
:
start_extent
=
self
.
make_line
(
start
,
tangent_start
,
t_before
,
-
1
)
start_extent
=
self
.
set_length
(
curve
,
start_extent
,
t_before
,
-
1
)
if
t_after
>
0
:
end_extent
=
self
.
make_line
(
end
,
tangent_end
,
t_after
,
+
1
)
end_extent
=
self
.
set_length
(
curve
,
end_extent
,
t_after
,
+
1
)
elif
self
.
mode
==
'ARC'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
if
t_before
>
0
:
if
np
.
linalg
.
norm
(
second_start
)
>
1e-6
:
eq1
=
circle_by_two_derivatives
(
start
,
-
tangent_start
,
second_start
)
start_extent
=
SvCircle
.
from_equation
(
eq1
)
start_extent
=
self
.
set_length
(
curve
,
start_extent
,
t_before
,
-
1
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
else
:
start_extent
=
self
.
make_line
(
start
,
tangent_start
,
t_before
,
-
1
)
start_extent
=
self
.
set_length
(
curve
,
start_extent
,
t_before
,
-
1
)
if
t_after
>
0
:
if
np
.
linalg
.
norm
(
second_end
)
>
1e-6
:
eq2
=
circle_by_two_derivatives
(
end
,
tangent_end
,
second_end
)
end_extent
=
SvCircle
.
from_equation
(
eq2
)
else
:
end_extent
=
self
.
make_line
(
end
,
tangent_end
,
t_after
,
+
1
)
end_extent
=
self
.
set_length
(
curve
,
end_extent
,
t_after
,
+
1
)
elif
self
.
mode
==
'QUAD'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
if
t_before
>
0
:
start_extent
=
SvTaylorCurve
(
start
,
[
-
tangent_start
,
second_start
])
start_extent
=
self
.
set_length
(
curve
,
start_extent
,
t_before
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
if
t_after
>
0
:
end_extent
=
SvTaylorCurve
(
end
,
[
tangent_end
,
second_end
])
end_extent
=
self
.
set_length
(
curve
,
end_extent
,
t_after
)
elif
self
.
mode
==
'CUBIC'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
third_start
,
third_end
=
curve
.
third_derivative_array
(
np
.
array
([
u_min
,
u_max
]))
if
t_before
>
0
:
start_extent
=
SvTaylorCurve
(
start
,
[
-
tangent_start
,
second_start
,
-
third_start
])
start_extent
=
self
.
set_length
(
curve
,
start_extent
,
t_before
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
if
t_after
>
0
:
end_extent
=
SvTaylorCurve
(
end
,
[
tangent_end
,
second_end
,
third_end
])
end_extent
=
self
.
set_length
(
curve
,
end_extent
,
t_after
)
else
:
raise
Exception
(
"Unsupported mode"
)
if
is_nurbs
:
if
start_extent
is
not
None
and
not
isinstance
(
start_extent
,
SvNurbsCurve
):
start_extent
=
start_extent
.
to_nurbs
(
implementation
=
curve
.
get_nurbs_implementation
())
if
end_extent
is
not
None
and
not
isinstance
(
end_extent
,
SvNurbsCurve
):
end_extent
=
end_extent
.
to_nurbs
(
implementation
=
curve
.
get_nurbs_implementation
())
return
start_extent
,
end_extent
def
process
(
self
):
if
not
any
(
socket
.
is_linked
for
socket
in
self
.
outputs
):
return
...
...
@@ -231,7 +99,10 @@ class SvExtendCurveNode(bpy.types.Node, SverchCustomTreeNode):
curve_out
=
[]
for
curves
,
t_before_i
,
t_after_i
in
zip_long_repeat
(
curve_s
,
t_before_s
,
t_after_s
):
for
curve
,
t_before
,
t_after
in
zip_long_repeat
(
curves
,
t_before_i
,
t_after_i
):
start_extent
,
end_extent
=
self
.
extend_curve
(
curve
,
t_before
,
t_after
)
start_extent
,
end_extent
=
extend_curve
(
curve
,
t_before
,
t_after
,
mode
=
self
.
mode
,
len_mode
=
self
.
len_mode
,
len_resolution
=
self
.
len_resolution
)
start_out
.
append
(
start_extent
)
end_out
.
append
(
end_extent
)
curves
=
[]
...
...
utils/curve/extend.py
0 → 100644
Просмотр файла @
5e8e9481
# 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
import
numpy
as
np
from
sverchok.utils.curve.core
import
SvTaylorCurve
from
sverchok.utils.curve.primitives
import
SvLine
,
SvCircle
from
sverchok.utils.curve.nurbs
import
SvNurbsCurve
from
sverchok.utils.curve.algorithms
import
SvCurveLengthSolver
,
reverse_curve
from
sverchok.utils.geom
import
circle_by_two_derivatives
def
set_length
(
base_curve
,
curve
,
t_ext
,
sign
=
1
,
len_mode
=
'T'
,
len_resolution
=
50
):
if
curve
is
None
:
return
None
if
len_mode
==
'T'
:
curve
.
u_bounds
=
(
0
,
t_ext
)
if
isinstance
(
curve
,
SvLine
)
and
sign
<
0
:
unit
=
curve
.
direction
/
np
.
linalg
.
norm
(
curve
.
direction
)
t_target
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
start
=
curve
.
point
+
curve
.
direction
-
t_ext
*
unit
curve
.
point
=
start
curve
.
u_bounds
=
(
0
,
t_target
)
elif
len_mode
==
'L'
:
if
isinstance
(
curve
,
SvLine
):
if
sign
>
0
:
curve
.
direction
=
curve
.
direction
t_ext
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
curve
.
u_bounds
=
(
0
,
t_ext
)
else
:
unit
=
curve
.
direction
/
np
.
linalg
.
norm
(
curve
.
direction
)
t_target
=
t_ext
/
np
.
linalg
.
norm
(
curve
.
direction
)
start
=
curve
.
point
+
curve
.
direction
-
t_ext
*
unit
curve
.
point
=
start
curve
.
u_bounds
=
(
0
,
t_target
)
else
:
u_min
,
u_max
=
base_curve
.
get_u_bounds
()
base_length
=
base_curve
.
calc_length
(
u_min
,
u_max
,
len_resolution
)
# base_length / (u_max - u_min) ~= t_ext / (t_target - 0)
t_mid
=
t_ext
*
(
u_max
-
u_min
)
/
base_length
curve
.
u_bounds
=
(
0
,
t_mid
)
solver
=
SvCurveLengthSolver
(
curve
)
solver
.
prepare
(
'SPL'
,
len_resolution
)
t_target
=
solver
.
solve
(
np
.
array
([
t_ext
]))[
0
]
curve
.
u_bounds
=
(
0
,
t_target
)
return
curve
def
extend_curve
(
curve
,
t_before
,
t_after
,
mode
=
'LINE'
,
len_mode
=
'T'
,
len_resolution
=
50
):
def
make_line
(
point
,
tangent
,
t_ext
,
sign
):
if
sign
<
0
:
before_start
=
point
-
t_ext
*
tangent
# / np.linalg.norm(tangent_start)
return
SvLine
.
from_two_points
(
before_start
,
point
)
else
:
after_end
=
point
+
t_ext
*
tangent
# / np.linalg.norm(tangent_end)
return
SvLine
.
from_two_points
(
point
,
after_end
)
u_min
,
u_max
=
curve
.
get_u_bounds
()
start
,
end
=
curve
.
evaluate
(
u_min
),
curve
.
evaluate
(
u_max
)
start_extent
,
end_extent
=
None
,
None
is_nurbs
=
isinstance
(
curve
,
SvNurbsCurve
)
if
mode
==
'LINE'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
if
t_before
>
0
:
start_extent
=
make_line
(
start
,
tangent_start
,
t_before
,
-
1
)
start_extent
=
set_length
(
curve
,
start_extent
,
t_before
,
-
1
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
if
t_after
>
0
:
end_extent
=
make_line
(
end
,
tangent_end
,
t_after
,
+
1
)
end_extent
=
set_length
(
curve
,
end_extent
,
t_after
,
+
1
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
elif
mode
==
'ARC'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
if
t_before
>
0
:
if
np
.
linalg
.
norm
(
second_start
)
>
1e-6
:
eq1
=
circle_by_two_derivatives
(
start
,
-
tangent_start
,
second_start
)
start_extent
=
SvCircle
.
from_equation
(
eq1
)
start_extent
=
set_length
(
curve
,
start_extent
,
t_before
,
-
1
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
else
:
start_extent
=
make_line
(
start
,
tangent_start
,
t_before
,
-
1
)
start_extent
=
set_length
(
curve
,
start_extent
,
t_before
,
-
1
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
if
t_after
>
0
:
if
np
.
linalg
.
norm
(
second_end
)
>
1e-6
:
eq2
=
circle_by_two_derivatives
(
end
,
tangent_end
,
second_end
)
end_extent
=
SvCircle
.
from_equation
(
eq2
)
else
:
end_extent
=
make_line
(
end
,
tangent_end
,
t_after
,
+
1
)
end_extent
=
set_length
(
curve
,
end_extent
,
t_after
,
+
1
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
elif
mode
==
'QUAD'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
if
t_before
>
0
:
start_extent
=
SvTaylorCurve
(
start
,
[
-
tangent_start
,
second_start
])
start_extent
=
set_length
(
curve
,
start_extent
,
t_before
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
if
t_after
>
0
:
end_extent
=
SvTaylorCurve
(
end
,
[
tangent_end
,
second_end
])
end_extent
=
set_length
(
curve
,
end_extent
,
t_after
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
elif
mode
==
'CUBIC'
:
tangent_start
=
curve
.
tangent
(
u_min
)
tangent_end
=
curve
.
tangent
(
u_max
)
second_start
=
curve
.
second_derivative
(
u_min
)
second_end
=
curve
.
second_derivative
(
u_max
)
third_start
,
third_end
=
curve
.
third_derivative_array
(
np
.
array
([
u_min
,
u_max
]))
if
t_before
>
0
:
start_extent
=
SvTaylorCurve
(
start
,
[
-
tangent_start
,
second_start
,
-
third_start
])
start_extent
=
set_length
(
curve
,
start_extent
,
t_before
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
if
is_nurbs
:
start_extent
=
start_extent
.
to_nurbs
()
start_extent
=
reverse_curve
(
start_extent
)
if
t_after
>
0
:
end_extent
=
SvTaylorCurve
(
end
,
[
tangent_end
,
second_end
,
third_end
])
end_extent
=
set_length
(
curve
,
end_extent
,
t_after
,
len_mode
=
len_mode
,
len_resolution
=
len_resolution
)
else
:
raise
Exception
(
"Unsupported mode"
)
if
is_nurbs
:
if
start_extent
is
not
None
and
not
isinstance
(
start_extent
,
SvNurbsCurve
):
start_extent
=
start_extent
.
to_nurbs
(
implementation
=
curve
.
get_nurbs_implementation
())
if
end_extent
is
not
None
and
not
isinstance
(
end_extent
,
SvNurbsCurve
):
end_extent
=
end_extent
.
to_nurbs
(
implementation
=
curve
.
get_nurbs_implementation
())
return
start_extent
,
end_extent
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать