Skip to content

Commit

Permalink
Merge pull request #4810 from nortikin/curvature_colors
Browse files Browse the repository at this point in the history
Viewer Draw Curve: indicate curvature by colors.
  • Loading branch information
portnov authored Dec 15, 2022
2 parents e0eca17 + 10b824b commit 80cf578
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 12 deletions.
18 changes: 16 additions & 2 deletions docs/nodes/viz/viewer_draw_curve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The parameters of the node are (in this order):

-------------

* **Display Node Points**, **Node Points Color**, **Node Points Size**. Control
* **Display Node Points** (N icon), **Node Points Color**, **Node Points Size**. Control
display of curve's node points, for NURBS and NURBS-like curves. Nodes are
not shown by default.

Expand All @@ -85,13 +85,22 @@ The parameters of the node are (in this order):

-------------

* **Display Curvature Comb**, **Comb Color**, **Comb Line Width**. Control
* **Display Curvature Comb** (C icon), **Comb Color**, **Comb Line Width**. Control
display of curve's curvature comb. Curvature comb is not shown by default.
* **Scale**. This parameter is available only when **Display Curvature Comb**
parameter is enabled. This defines the scaling applied to curve normals used
to display the curvature comb. The default value of 1.0 means that normals
length will be equal to curve's curvature in corresponding points.

-------------

* **Indicate Curvature** (G icon), **Curvature Color**. If enabled, curve's
curvature is indicated by drawing a curve with a color gradient: the color
specified in **Curve Line Color** parameter is used to draw the most flat
curve segments, and the color specified in the **Curvature Color** parameter
is used to draw the places where curve's curvature hast the greatest value.
Disabled by default.

Operators
---------

Expand All @@ -116,6 +125,11 @@ Example of curvature comb display:
.. image:: https://user-images.githubusercontent.com/284644/206860681-a70d93af-a72b-4dcb-bf36-3678135b835a.png
:target: https://user-images.githubusercontent.com/284644/206860681-a70d93af-a72b-4dcb-bf36-3678135b835a.png

Example of curvature indication by color gradient:

.. image:: https://user-images.githubusercontent.com/284644/206875486-4f018e3e-4b90-4b6d-9df1-28df129e65d2.png
:target: https://user-images.githubusercontent.com/284644/206875486-4f018e3e-4b90-4b6d-9df1-28df129e65d2.png

* Generator-> :doc:`Line </nodes/generator/line_mk4>`
* Transform-> :doc:`Randomize </nodes/transforms/randomize>`
* Curves->NURBS-> :doc:`Approximate NURBS Curve </nodes/curve/approximate_nurbs_curve>`
58 changes: 50 additions & 8 deletions nodes/viz/viewer_draw_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@
from sverchok.utils.sv_operator_mixins import SvGenericNodeLocator
from sverchok.ui.bgl_callback_3dview import callback_disable, callback_enable

def draw_edges(shader, points, edges, line_width, color):
def draw_edges(shader, points, edges, line_width, color, is_smooth=False):
if is_smooth:
draw_edges_colored(shader, points, edges, line_width, [color for i in range(len(points))])
else:
bgl.glLineWidth(line_width)
batch = batch_for_shader(shader, 'LINES', {"pos": points}, indices=edges)
shader.bind()
shader.uniform_float('color', color)
batch.draw(shader)
bgl.glLineWidth(1)

def draw_edges_colored(shader, points, edges, line_width, colors):
bgl.glLineWidth(line_width)
batch = batch_for_shader(shader, 'LINES', {"pos": points}, indices=edges)
batch = batch_for_shader(shader, 'LINES', {"pos": points, "color": colors}, indices=edges)
shader.bind()
shader.uniform_float('color', color)
batch.draw(shader)
bgl.glLineWidth(1)

Expand All @@ -38,18 +48,30 @@ def draw_points(shader, points, size, color):
batch.draw(shader)
bgl.glPointSize(1)

def draw_points_colored(shader, points, size, colors):
bgl.glPointSize(size)
batch = batch_for_shader(shader, 'POINTS', {"pos": points, "color": colors})
shader.bind()
batch.draw(shader)
bgl.glPointSize(1)

def draw_curves(context, args):
node, draw_inputs, v_shader, e_shader = args
is_smooth = node.draw_curvature

bgl.glEnable(bgl.GL_BLEND)

for item in draw_inputs:

if node.draw_line:
draw_edges(e_shader, item.points, item.edges, node.line_width, node.line_color)
if node.draw_curvature and item.curvature_point_colors is not None:
colors = item.curvature_point_colors.tolist()
draw_edges_colored(e_shader, item.points, item.edges, node.line_width, colors)
else:
draw_edges(e_shader, item.points, item.edges, node.line_width, node.line_color, is_smooth)

if node.draw_control_polygon and item.control_points is not None:
draw_edges(e_shader, item.control_points, item.control_polygon_edges, node.control_polygon_line_width, node.control_polygon_color)
draw_edges(e_shader, item.control_points, item.control_polygon_edges, node.control_polygon_line_width, node.control_polygon_color, is_smooth)

if node.draw_control_points and item.control_points is not None:
draw_points(v_shader, item.control_points, node.control_points_size, node.control_points_color)
Expand All @@ -58,10 +80,13 @@ def draw_curves(context, args):
draw_points(v_shader, item.node_points, node.nodes_size, node.nodes_color)

if node.draw_comb and item.comb_edges is not None:
draw_edges(e_shader, item.comb_points, item.comb_edges, node.comb_width, node.comb_color)
draw_edges(e_shader, item.comb_points, item.comb_edges, node.comb_width, node.comb_color, is_smooth)

if node.draw_verts:
draw_points(v_shader, item.points, node.verts_size, node.verts_color)
if node.draw_curvature:
draw_points_colored(v_shader, item.points, node.verts_size, item.curvature_point_colors)
else:
draw_points(v_shader, item.points, node.verts_size, node.verts_color)

bgl.glEnable(bgl.GL_BLEND)

Expand Down Expand Up @@ -193,6 +218,16 @@ class SvCurveViewerDrawNode(SverchCustomTreeNode, bpy.types.Node):
min = 0.0, default = 1.0,
update = updateNode)

draw_curvature: BoolProperty(
update=updateNode, name='Indicate Curvature', default=False)

curvature_color : FloatVectorProperty(
name = "Curvature Color",
default = (1.0, 0.1, 0.1, 1.0),
size = 4, min = 0.0, max = 1.0,
subtype = 'COLOR',
update = updateNode)

def draw_buttons(self, context, layout):
layout.prop(self, "activate", icon="HIDE_" + ("OFF" if self.activate else "ON"))

Expand Down Expand Up @@ -231,6 +266,10 @@ def draw_buttons(self, context, layout):
if self.draw_comb:
grid.prop(self, 'comb_scale', text='Scale')

row = grid.row(align=True)
row.prop(self, 'draw_curvature', text="", icon='EVENT_G')
row.prop(self, 'curvature_color', text="")

row = layout.row(align=True)
row.scale_y = 4.0 if self.prefs_over_sized_buttons else 1
self.wrapper_tracked_ui_draw_op(row, SvBakeCurveOp.bl_idname, icon='OUTLINER_OB_MESH', text="B A K E")
Expand All @@ -244,7 +283,10 @@ def sv_init(self, context):
def draw_all(self, draw_inputs):

v_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
e_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
if self.draw_curvature:
e_shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
else:
e_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')

draw_data = {
'tree_name': self.id_data.name[:],
Expand Down
23 changes: 21 additions & 2 deletions utils/curve/bakery.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self, node, curve, resolution):
self.curve = curve
self.resolution = resolution

if node.draw_line or node.draw_verts or node.draw_comb:
if node.draw_line or node.draw_verts or node.draw_comb or node.draw_curvature:
t_min, t_max = curve.get_u_bounds()
ts = np.linspace(t_min, t_max, num=resolution)
n = len(ts)
Expand All @@ -53,10 +53,15 @@ def __init__(self, node, curve, resolution):
else:
self.node_points = None

if node.draw_comb or node.draw_curvature:
self.curvatures = curve.curvature_array(ts)
else:
self.curvatures = None

if node.draw_comb:
n = len(self.points)
normals = curve.main_normal_array(ts, normalize=True)
curvatures = curve.curvature_array(ts)[np.newaxis].T
curvatures = self.curvatures[np.newaxis].T
comb_normals = node.comb_scale * curvatures * normals
comb_points = self.points - comb_normals
self.comb_points = np.concatenate((self.points, comb_points)).tolist()
Expand All @@ -67,6 +72,20 @@ def __init__(self, node, curve, resolution):
self.comb_points = None
self.comb_edges = None

if node.draw_curvature:
color1 = np.array(node.line_color)
color2 = np.array(node.curvature_color)
#curvatures = np.tanh(self.curvatures)
curvatures = self.curvatures
c, C = curvatures.min(), curvatures.max()
coefs = (curvatures - c) / (C - c)
coefs = coefs[np.newaxis].T
self.curvature_point_colors = (1 - coefs) * color1 + coefs * color2
self.curvature_edge_colors = 0.5 * (self.curvature_point_colors[1:] + self.curvature_point_colors[:-1])
else:
self.curvature_point_colors = None
self.curvature_edge_colors = None

def bake(self, object_name):
me = bpy.data.meshes.new(object_name)
me.from_pydata(self.points, self.edges, [])
Expand Down
1 change: 1 addition & 0 deletions utils/surface/bakery.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def __init__(self):
self.draw_control_points = False
self.draw_nodes = False
self.draw_comb = False
self.draw_curvature = False

def __init__(self, node, surface, resolution_u, resolution_v):
self.node = node
Expand Down

0 comments on commit 80cf578

Please sign in to comment.