Closed ghost closed 9 years ago
I don't have much time today to respond to this, but will show how to do the edges, it is usually a missing [ ]
around the list, to inform sverchok about the level of nestedness (nestedness is on the table for being solved.. we talk about it often)
import math
TWO_PI = 2*math.pi
def sv_main(radius=1, turns=1, smth=4):
verts_out = []
edges_out = []
in_sockets = [
['s', 'radius', radius],
['s', 'turns', turns],
['s', 'smooth', smth]
]
out_sockets = [
['v', 'Verts', [verts_out]], # extra wrapping
['s', 'Edges', [edges_out]]
]
smth = abs(turns*smth*8) #least subdivision = 8
Htheta = turns*360 #total angle
av = verts_out.append
for i in range(0,smth+1):
theta = math.radians(i*Htheta/smth)
gamma = theta*radius/(turns*TWO_PI)
av((math.cos(theta)*gamma, math.sin(theta)*gamma, 0.0))
ae = edges_out.append
num_verts = len(verts_out)
for i in range(num_verts-1):
ae([i,(i+1)])
return in_sockets, out_sockets
My suggested previous script kept the distance between consecutive next verts approximately the same (Evenly distributed - depending on the slider settings). But anyway, this is how to do edges for a non closed entity
Great, thanks for your help, i'll try to proceed from here.
a slightly different effect using my spiral script and the image decomp node and a SN script that modifies the size of the dupliObject (icosphere) on the Particle system attached to the spiral., for every point on the spiral, it tracks the nearest pixel on the image, and gets the z distance
I've experimented now and had difficulty generating a single polygon (to simulate the spiral paintbrush stroke so-to-say) of so many vertices.. Blender may even crash.
probably need to make sure that the edges of the polygon never cross over too ahwell, good fun anyway
Wow this is great, i wish i get familiar enough with Sverchock to achieve similar results, would you like to share the node tree screenshots?
https://www.dropbox.com/s/b0ok3fobnya40nb/sprial_from_img_no_particles2.blend?dl=0
you may have to press 'load' on the image
actually, here's a fixed version which does bake correctly. When baked you can hit F with the sv_(number) mesh in edit more and it will make the polygon :) https://www.dropbox.com/s/b0ok3fobnya40nb/sprial_from_img_no_particles2.blend?dl=0
import mathutils
from mathutils import Vector, kdtree
def sv_main(image_verts=[[]], spiral_verts=[[]], reamp=-0.3, maxdist=0.7, rescale=1.0):
gloc = []
edges_out = []
in_sockets = [
['v', 'image_verts', image_verts],
['v', 'spiral_verts', spiral_verts],
['s', 'reamp', reamp],
['s', 'maxdist', maxdist],
['s', 'rescale', rescale]
]
out_sockets = [
['v', 'locations', [gloc]],
['s', 'edges', [edges_out]]
]
print('point 1')
# A little boilerplate is needed
if (not image_verts) or (not image_verts[0]):
return in_sockets, out_sockets
else:
v = image_verts[0]
if (not spiral_verts) or (not spiral_verts[0]):
return in_sockets, out_sockets
else:
sv = spiral_verts[0]
print('point 4')
# KD BUILD
size = len(v)
kd = kdtree.KDTree(size)
for i, vtx in enumerate(v):
kd.insert(Vector(vtx), i)
kd.balance()
side_left = []
side_right = []
sidel_add = side_left.append
sider_add = side_right.append
# PARTICLE LOOP
for i in range(len(sv)):
pt = Vector(sv[i])
for (co, index, dist) in kd.find_range(pt, maxdist):
z1 = pt.z
z2 = co.z
size = ((z1 - z2) * reamp) / 2
dtc = Vector(pt).length # distance to center
if dtc == 0:
dtc += 0.01
size1 = dtc - size
size2 = dtc + size
amp1 = (size1 / dtc) * rescale
amp2 = (size2 / dtc) * rescale
v1 = Vector((0,0,0)).lerp(pt, amp1)
v2 = Vector((0,0,0)).lerp(pt, amp2)
sidel_add(v1[:])
sider_add(v2[:])
# stop at first find.
break
gloc.extend(side_left)
gloc.extend(side_right[::-1])
ae = edges_out.append
num_verts = len(gloc)
for i in range(num_verts-1):
ae([i,(i+1)])
ae([num_verts-1,0])
print(num_verts)
print(edges_out[-1])
return in_sockets, out_sockets
wow. uvconnect node can do polygons anyway, but needed two equal count of vertices, so list of inner and list of outer vertices chain. also we can remake pipe tube node to handle various thickness of pipe. such way we can manipulate it on layout IMHO
I explored a bit further since those posts, but it's busy around here at home :).
this outputs a polygon (replaces and reuses the edges list, because lazy)
gloc.extend(side_left)
gloc.extend(side_right[::-1])
ae = edges_out.extend
num_verts = len(gloc)
for i in range(num_verts-1):
ae([i])
i'd need to write a more stable spiral / coil routine to get better output, with fine control over distance between points and delta radius for consecutive arms of the spiral. But am not so interested anymore
import math
def spiral_points(scale, arc=1, separation=1):
"""
lifted directly from:
http://stackoverflow.com/a/27528612/1243487
by user: liborm
generate points on an Archimedes' spiral
with `arc` giving the length of arc between two points
and `separation` giving the distance between consecutive
turnings
- approximate arc length with circle arc at given distance
- use a spiral equation r = b * phi
"""
def p2c(r, phi):
"""polar to cartesian
"""
return (scale * r * math.cos(phi), scale * r * math.sin(phi), 0)
# yield a point at origin
# not using the origin may give better results
yield (0, 0, 0)
# initialize the next point in the required distance
r = arc
b = separation / (2 * math.pi)
# find the first phi to satisfy distance of `arc` to the second point
phi = float(r) / b
while True:
yield p2c(r, phi)
# advance the variables
# calculate phi that will give desired arc length at current radius
# (approximating with circle)
phi += float(arc) / r
r = b * phi
def sv_main(arc=1, separation=3, num_points=5000, scale=0.13):
points = []
in_sockets = [
['s', 'arc', arc],
['s', 'separation', separation],
['s', 'num_points', num_points],
['s', 'scale', scale]
]
out_sockets = [
['v', 'verts', [points]]
]
point_gen = spiral_points(scale, arc, separation)
for i in range(num_points):
points.append(next(point_gen))
return in_sockets, out_sockets
Aah... I can simplify this simply by using Zeffi Spiral and Blender Displace Modifier 💃
I am trying to replicate my Grasshopper algorithm on Sverchock https://www.behance.net/gallery/Single-Stroke-mimicry/14936449 And here what i managed to achieve yet: 1) I tried to use @zeffii 's SN code to create the spiral , but it i needed more control on the parameters so i manipulated a little and wrote this :
To create the spiral with controlling the exact Radius, No of Turns and the Smoothness :
I have desperately tried to output the edges as well but never succeeded, so i surrendered and just used an external Line Node :\ .
2) My spiral SN node have one problem that the vertices are not evenly distributed on the curve so i needed to Rebuild it (as in rhino and grasshopper rebuild commands) :
3) Now we have an evenly distributed vertices that need to be Offseted in both directions. This was too hard but here how i managed to do the first Offset.
Basically what i needed to do is rotating every vertex 90 degrees around the previous vertex to create a vector perpendicular to the spiral at this point, to use it as moving vector. I found the Lists node too complicated but i managed to do it with trial and error.
Now i need to : A- control the offset distance for every vertex and B- manage to connect vertices with edges and C- Loft the two spirals to create the stroke width, may be with UVconnect node
But i think these will be too difficult after what i have experienced with lists and data nesting. i need to have some break and restudy the manual again to understand how this works ! Or may be i have to study Blender scripting to be more aware of what Sverchock does.