Modeling Kagome weave pattern with sverchok
The following article below describes the details of how to apply kagome weave pattern for 3d models.
In this post, following the paper, I try to make a simple kagome-weave-pattern model with Blender and its node editor, sverchok.
(This may currently work well only for the closed and symmetrical surfaces.)
At first, It needs to modify the original mesh and prepare it for applying the main algorithm. Connecting the center points of the mesh triangles to make dual meshes and truncating the vertices of the hexagons to make a mesh before the next procedure.
Then, the next step is to divide the edges into linear elements for weaving, but I could not find the way to make edge loops easily with the sverchok nodes. So I wrote a small script to 'walk' the vertices, find the connected edges to the each points, and connecting two of them which has similar angles around the vertices (the script is at the bottom of this post). Before applying this scripted node, I made expanded and shrinked meshes to get the vertices of the 'upper' and 'lower' point lists.
After that, you have to choose the vertices from the two lists interchangeably to make crossing points to model interlacing. You have already two lists of the vertices('upper' or 'lower') in the node editor, so I chose the vertices one after another from the two lists and integrated selected vertices into one list.
After identifing the weave-lines, these are converted to material strip which has some width. In this process, it seems difficult to generate the strip in the right way (the original article described) with Blender. Instead, I use some different ways to get the strip by using Blender's modifiers, though the strip may not accurately follow the original surface . For example, It seems easy to get the one line with 'Extdude-edge' modifier (and 'UV Connection' modifier will also worked fine).
But when I tried to iterate the strip-generation with applying the 'range' node for eace lines, it did not work correctly, especially at the matrix node(, the matrix can not be applied individually, and currently I do not understand why this does not work properly). I could not get the right direction of the extrusion for each lines with this way.
Instead, I used 'Solidify' modifier node to get the strip width, and applied 'Fill holes' node to materialize the strip for the edges of the strip. It works correctly and the result seems to be fine. And though I do not try yet, it may be better if you use 'obj raycast' node to move verts by their normals onto original mesh.
Finally, I applied 'Subdivide' node with smoothing to get the final mesh.
In this modeling process, I probably do not use the best way to generate kagome pattern. Because it may not work correctly when using 'open' surface or different pattern meshes, and there may be more better and effective way. But this noding method can be the first step to model the kagome weave with Blender's sverchok, and I hope this will help someone who will try to make more complex kagome weave models.
The script below is used for the 'Scripted' node in this noding process.
(Sorry for the ugly code...)
+linear_edges.py+
import numpy as np
import copy
from numpy import linalg as LA
# calc angles between two edges
def calcVectorAngle(verts=, e1=, e2=):
angle = -1
if len(verts) > 0 and len(e1) > 1 and len(e2) > 1:
if len(verts) > max([e1[0], e1[1], e2[0], e2[1]]):
v1 = np.array(verts[e1[1]]) - np.array(verts[e1[0]])
v2 = np.array(verts[e2[1]] - np.array(verts[e2[0]]))
i = np.inner(v1, v2)
n = LA.norm(v1) * LA.norm(v2)
c = i / n
angle = np.rad2deg(np.arccos(np.clip(c, -1.0, 1.0)))
return angle
# find an edge which angle is similar to the source
def findNextEdge(verts=, linked_edges=, vertex_index=0, source_edge=, angle_range=0.0):
if (len(verts) == 0) or (len(linked_edges) < vertex_index) or (len(source_edge) != 2):
return
linked = linked_edges[vertex_index]
index = linked.index(source_edge)
targets =
diffs =
# find next edge
for i, elem in enumerate(linked):
if i != index:
angle = calcVectorAngle(verts, source_edge, elem)
diff = -1
if angle != -1:
if abs(angle) < angle_range:
diff = abs(angle)
elif abs(angle - 180) < angle_range:
diff = abs(angle - 180)
elif abs(angle - 360) < angle_range:
diff = abs(angle - 360)
if diff >= 0:
targets.append(elem)
diffs.append(diff)
if (len(diffs) == 1) and (len(targets) == 1):
return targets[0]
elif len(diffs) > 1:
min_index = diffs.index(min(diffs))
return targets[min_index]
return
def sv_main(verts_in=, edges_in=, angle_range_in=0.0):
in_sockets = [
['v', 'verts', verts_in],
['s', 'edges', edges_in],
['s', 'angle_range', angle_range_in]]
# press Ctrl+I, look in console
verts =
edges =
angle_range = 0.0
out_verts =
out_edges =
if verts_in:
verts = verts_in[0]
if edges_in:
edges = edges_in[0]
linked_edges = [ for i in range(len(verts))]
if angle_range_in:
angle_range = angle_range_in
# prepare linked_edges per verts
for i in range(len(verts)):
for e in edges:
if e.count(i) > 0:
linked_edges[i].append(e)
# walk through edges
walked = [False]*len(edges)
loop_verts =
i = 0
prev_vertex = -1
while True:
if len(edges) == 0:
break
e = edges[i]
if len(e) < 2:
break;
# check duplication
if walked[i]:
out_verts.append(copy.deepcopy(loop_verts))
loop_verts.clear()
# prepare next loop
if walked.count(False) == 0:
break
i = walked.index(False)
e = edges[i]
prev_vertex = -1
# determine next direction
v = e[1] if (prev_vertex == -1 or prev_vertex == e[0]) else e[0]
prev_vertex = v
walked[i] = True
loop_verts.append(verts[v])
next_edge = findNextEdge(verts, linked_edges, v, e, angle_range)
if len(next_edge) > 0:
# continue to walk current loop
i = edges.index(next_edge)
elif walked.count(False) > 0:
# begin to walk another loop
i = walked.index(False)
else:
# walked all verts
continue
# generate new loop edges
for i, vi in enumerate(out_verts):
es = []
for j in range(len(vi)):
e = [j, (j + 1) if (j < len(vi) - 1) else 0]
es.append(e)
out_edges.append(es)
out_sockets = [['s', 'verts', [out_verts]],
['s', 'edges', [out_edges]]]
return in_sockets, out_sockets
References:
- (PDF) Beyond the basket case: A principled approach to the modelling ...https://www.researchgate.net/.../328043391_Beyond_the_basket_case_A_pri...
- https://www.mathpython.com/ja/numpy-vector-angle/
- https://github.com/nortikin/sverchok/issues/919
Environment: