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

NURBS Curve Degree Elevate & Reduce nodes.

владелец d762226b
......@@ -77,6 +77,9 @@
SvRefineNurbsCurveNode
SvCurveRemoveExcessiveKnotsNode
---
SvCurveElevateDegreeNode
SvCurveReduceDegreeNode
---
SvAdaptivePlotNurbsCurveNode
## Curves @ Bezier
......
# 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 bpy
from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level, get_data_nesting_level, repeat_last_for_length
from sverchok.utils.curve import SvCurve
from sverchok.utils.curve.nurbs import SvNurbsCurve
class SvCurveElevateDegreeNode(bpy.types.Node, SverchCustomTreeNode):
"""
Triggers: Elevate Degree
Tooltip: Elevate degree of a NURBS curve
"""
bl_idname = 'SvCurveElevateDegreeNode'
bl_label = 'Elevate Degree (NURBS Curve)'
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = 'SV_CURVE_INSERT_KNOT'
modes = [
('DELTA', "Elevate by", "Specify difference between current degree and target degree", 0),
('TARGET', "Set degree", "Specify target degree", 1)
]
def update_sockets(self, context):
self.inputs['Degree'].label = "Delta" if self.mode == 'DELTA' else "Degree"
updateNode(self, context)
mode : EnumProperty(
name = "Mode",
description = "How new curve degree is specified",
items = modes,
update = update_sockets)
degree : IntProperty(
name = "Degree",
description = "Target degree or degree delta",
min = 0,
default = 1,
update = updateNode)
def draw_buttons(self, context, layout):
layout.prop(self, 'mode', text='')
def sv_init(self, context):
self.inputs.new('SvCurveSocket', "Curve")
self.inputs.new('SvStringsSocket', 'Degree').prop_name = 'degree'
self.outputs.new('SvCurveSocket', 'Curve')
def process(self):
if not any(socket.is_linked for socket in self.outputs):
return
curve_s = self.inputs['Curve'].sv_get()
degree_s = self.inputs['Degree'].sv_get()
input_level = get_data_nesting_level(curve_s, data_types=(SvCurve,))
flat_output = input_level < 2
curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve,))
degree_s = ensure_nesting_level(degree_s, 2)
curves_out = []
for params in zip_long_repeat(curve_s, degree_s):
new_curves = []
for curve, degree in zip_long_repeat(*params):
curve = SvNurbsCurve.to_nurbs(curve)
if curve is None:
raise Exception("One of curves is not NURBS")
if self.mode == 'DELTA':
kwargs = dict(delta = degree)
else:
kwargs = dict(target = degree)
curve = curve.elevate_degree(**kwargs)
new_curves.append(curve)
if flat_output:
curves_out.extend(new_curves)
else:
curves_out.append(new_curves)
self.outputs['Curve'].sv_set(curves_out)
def register():
bpy.utils.register_class(SvCurveElevateDegreeNode)
def unregister():
bpy.utils.unregister_class(SvCurveElevateDegreeNode)
# 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 bpy
from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level, get_data_nesting_level, repeat_last_for_length
from sverchok.utils.curve import SvCurve
from sverchok.utils.curve.nurbs import SvNurbsCurve
class SvCurveReduceDegreeNode(bpy.types.Node, SverchCustomTreeNode):
"""
Triggers: Reduce Degree
Tooltip: Reduce degree of a NURBS curve
"""
bl_idname = 'SvCurveReduceDegreeNode'
bl_label = 'Reduce Degree (NURBS Curve)'
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = 'SV_CURVE_INSERT_KNOT'
modes = [
('DELTA', "Reduce by", "Specify difference between current degree and target degree", 0),
('TARGET', "Set degree", "Specify target degree", 1)
]
def update_sockets(self, context):
self.inputs['Degree'].label = "Delta" if self.mode == 'DELTA' else "Degree"
updateNode(self, context)
mode : EnumProperty(
name = "Mode",
description = "How new curve degree is specified",
items = modes,
update = update_sockets)
degree : IntProperty(
name = "Degree",
description = "Target degree or degree delta",
min = 0,
default = 1,
update = updateNode)
tolerance : FloatProperty(
name = "Tolerance",
description = "Error tolerance",
min = 0.0,
default = 1e-4,
precision = 8,
update = updateNode)
if_possible : BoolProperty(
name = "If possible",
description = "Don't fail when trying to reduce the curve's degree too many times, just reduce it as much as possible",
default = False,
update = updateNode)
def draw_buttons(self, context, layout):
layout.prop(self, 'mode', text='')
layout.prop(self, 'if_possible')
def sv_init(self, context):
self.inputs.new('SvCurveSocket', "Curve")
self.inputs.new('SvStringsSocket', 'Degree').prop_name = 'degree'
self.inputs.new('SvStringsSocket', 'Tolerance').prop_name = 'tolerance'
self.outputs.new('SvCurveSocket', 'Curve')
self.outputs.new('SvStringsSocket', 'Error')
def process(self):
if not any(socket.is_linked for socket in self.outputs):
return
curve_s = self.inputs['Curve'].sv_get()
degree_s = self.inputs['Degree'].sv_get()
tolerance_s = self.inputs['Tolerance'].sv_get()
input_level = get_data_nesting_level(curve_s, data_types=(SvCurve,))
flat_output = input_level < 2
curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve,))
degree_s = ensure_nesting_level(degree_s, 2)
tolerance_s = ensure_nesting_level(tolerance_s, 2)
curves_out = []
error_out = []
for params in zip_long_repeat(curve_s, degree_s, tolerance_s):
new_curves = []
new_errors = []
for curve, degree, tolerance in zip_long_repeat(*params):
curve = SvNurbsCurve.to_nurbs(curve)
if curve is None:
raise Exception("One of curves is not NURBS")
if self.mode == 'DELTA':
kwargs = dict(delta = degree)
else:
kwargs = dict(target = degree)
curve, error = curve.reduce_degree(tolerance=tolerance, return_error=True, if_possible = self.if_possible, **kwargs)
new_curves.append(curve)
new_errors.append(error)
if flat_output:
curves_out.extend(new_curves)
error_out.extend(new_errors)
else:
curves_out.append(new_curves)
error_out.append(new_errors)
self.outputs['Curve'].sv_set(curves_out)
self.outputs['Error'].sv_set(error_out)
def register():
bpy.utils.register_class(SvCurveReduceDegreeNode)
def unregister():
bpy.utils.unregister_class(SvCurveReduceDegreeNode)
......@@ -420,6 +420,7 @@ class SvNurbsCurve(SvCurve):
result = reduced_segments[0]
for segment in reduced_segments[1:]:
result = result.concatenate(segment, remove_knots=True, tolerance=tolerance)
max_error = max(max_error, tolerance)
result = result.reparametrize(src_t_min, src_t_max)
return result, max_error, True
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать